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
PassThruTranscoder
class: This class should implement theTranscoder
interface, which specifies the necessary methods for encoding and decoding data. - Implement the
encode
method: Within thePassThruTranscoder
class, implement theencode
method. 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
decode
method: Similarly, in thePassThruTranscoder
class, implement thedecode
method. This method handles the decoding of data when retrieved from Couchbase. As with encoding, ensure that thedecode
method 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
Couchbase
class. - 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
CouchbaseSessionHandler
with connection details, bucket, scope, and collection labels. - Implement the
open
,close
,read
,write
,destroy
, andgc
methods as required by theSessionHandlerInterface
. - Use the
myCouchbase
class 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
CouchbaseSessionHandler
class. - Start a new session with a session ID.
- Update the session data and interact with Couchbase for storing and retrieving session information.