Thanks a lot Mr.@mreiche, I think i finally got it:
It’s exactly as you said: the variable $_SESSION is decoded and encoded by the session.serialize_handler. When I retrieve the $session_data within the read() function, I only receive the encoded data.
So my finally solution to Setting Up Couchbase as a PHP Session Handler with igbinary Encoding was:
Step 1: Create a PassThruTranscoder class for encoding and decoding data. In case of the $_SESSION data that is already encoded and decoded by the session.serialize_handler, the goal is to ensure that Couchbase accepts this data “as it is,” without further encoding or decoding. To use this class effectively, follow these steps:
- Define the
PassThruTranscoderclass: This class should implement theTranscoderinterface, which specifies the necessary methods for encoding and decoding data. - Implement the
encodemethod: Within thePassThruTranscoderclass, implement theencodemethod. This method is responsible for encoding data. However, in your specific case, you don’t want to modify the data during encoding. Simply return the data along with the appropriate flags, making sure not to alter the original data’s format. - Implement the
decodemethod: Similarly, in thePassThruTranscoderclass, implement thedecodemethod. This method handles the decoding of data when retrieved from Couchbase. As with encoding, ensure that thedecodemethod doesn’t modify the data. It should return the data exactly as it was stored, preserving its original format.
By placing the PassThruTranscoder class in the same folder as autoload.php and using Couchbase\PassThruTranscoder, you organize your code effectively. This allows you to access and utilize the PassThruTranscoder class correctly in your project.
Step 2: Create a generic Couchbase class that handles connections and operations on a Couchbase database. This class includes methods for getting, writing, modifying, and deleting data.
- Import the necessary Couchbase classes and define the
Couchbaseclass. - Initialize a Couchbase cluster with the provided connection details (connection string, username, password) in the constructor.
- Implement methods for getting a collection, getting a document, erasing a document, inserting a document, and upserting a document in a specified bucket, scope, and collection.
- Handle exceptions that may occur during these operations.
Exemple:
<?php
require_once '/path_to/autoload.php';
use Couchbase\Cluster;
use Couchbase\ClusterOptions;
use Couchbase\GetOptions;
use Couchbase\InsertOptions;
use Couchbase\UpsertOptions;
use Couchbase\Exception\CouchbaseException;
use Couchbase\Exception\DocumentNotFoundException;
use Couchbase\PassThruTranscoder;
class myCouchbase {
var $classname = "myCouchbase";
private $cluster = null;
private $Cas = null;
private $passTranscoder;
private CouchbaseException $Exception;
public function __construct(string $connectionString = "", string $user = "", string $password = "", bool $passTranscoder = false) {
if ($connectionString && $user && $password) {
$options = new ClusterOptions();
$options->credentials($user, $password);
$cluster = new Cluster($connectionString, $options);
$this->cluster = $cluster;
$this->passTranscoder = $passTranscoder;
}
}
public function getCollection(string $bucket_label, string $scope_label, string $collection_label) {
try {
if ($this->cluster) {
$bucket = $this->cluster->bucket($bucket_label);
if($bucket) $scope = $bucket->scope($scope_label);
if($scope) $collection = $scope->collection($collection_label);
return $collection;
}
}
catch (CouchbaseException $ex) {
$this->Exception = $ex;
return false;
}
}
public function getDocument(string $bucket_label, string $scope_label, string $collection_label, $key) {
$collection = $this->getCollection($bucket_label, $scope_label, $collection_label);
try {
$options = null;
if($this->passTranscoder){
$options = new GetOptions();
$options->transcoder(new PassThruTranscoder());
}
$result = $collection->get($key, $options ? $options : null);
$this->Cas = $result->cas();
return $result->content();
}
catch (DocumentNotFoundException $ex) {
$this->Cas = null;
return false;
}
catch (CouchbaseException $ex) {
$this->Exception = $ex;
return false;
}
}
public function erase(string $bucket_label, string $scope_label,string $collection_label, $key) {
$collection = $this->getCollection($bucket_label, $scope_label, $collection_label);
try {
$collection->remove($key);
return true;
}
catch (CouchbaseException $ex) {
if ($ex->getCode() == "COUCHBASE_KEY_ENOENT") {
$this->Cas = null;
return true;
} else {
$this->Exception = $ex;
return false;
}
}
}
public function insert(string $bucket_label, string $scope_label, string $collection_label, $key, $value, $expiry = 0) {
$collection = $this->getCollection($bucket_label, $scope_label, $collection_label);
try {
$options = null;
//If the insert() is called first than the get() the Cas is null (also 0 is false in php)
if ($expiry || $this->Cas || $this->passTranscoder) {
$options = new InsertOptions();
if ($expiry) $options->expiry($expiry);
if ($this->passTranscoder) $options->transcoder(new PassThruTranscoder());
}
$result = $collection->insert($key, $value, $options ? $options : null);
$this->Cas = $result->cas();
return true;
}
catch (CouchbaseException $ex) {
$this->Exception = $ex;
return false;
}
}
public function upsert(string $bucket_label, string $scope_label, string $collection_label, $key, $value, $expiry = 0) {
$collection = $this->getCollection($bucket_label, $scope_label, $collection_label);
try {
$options = null;
//If the upsert() is called first than the get() the Cas is null (also 0 is false in php)
if ($expiry || $this->Cas || $this->passTranscoder) {
$options = new UpsertOptions();
if ($expiry) $options->expiry($expiry);
if ($this->passTranscoder) $options->transcoder(new PassThruTranscoder());
}
$result = $collection->upsert($key, $value, $options ? $options : null);
$this->Cas = $result->cas();
return true;
}
catch (CouchbaseException $ex) {
$this->Exception = $ex;
return false;
}
}
}
?>
Step 3: Create a CouchbaseSessionHandler class that implements the SessionHandlerInterface for managing PHP sessions using Couchbase as the session storage (example: PHP session handler for couchbase 7 · GitHub).
- Initialize the
CouchbaseSessionHandlerwith connection details, bucket, scope, and collection labels. - Implement the
open,close,read,write,destroy, andgcmethods as required by theSessionHandlerInterface. - Use the
myCouchbaseclass for handling Couchbase operations within these methods.
Step 4: Use the code to manage PHP sessions with Couchbase as the session handler.
- Set the session save handler to the
CouchbaseSessionHandlerclass. - Start a new session with a session ID.
- Update the session data and interact with Couchbase for storing and retrieving session information.