laravel フレームワークを使用して、zencart サイトまたは他のフレームワーク (ThinkPHP など) によって実装されたプロジェクトを再構築し、ビジネスを laravel プロジェクトに移行するステップステップ により、この時点で両側のセッションを共有する必要があります。 laravel によって生成されたセッション データは PHP ネイティブ セッションによって読み込むことができ、その逆も可能であることを認識する必要があります。これにより、最終的にシステム再構築の複雑さが大幅に軽減されます。
同じシリアル化アルゴリズムを使用して、シリアル化された結果の両側で一貫性を保ちます。
serialize / unserialize
session.serialize_handler はシリアル化/逆シリアル化に使用されるプロセッサ名を定義します。 現在サポートされているのは、PHP シリアル化形式 (php_serialize という名前)、PHP PHP 内部形式 (php および php_binary という名前)、および WDDX (wddx という名前) です。 PHP が WDDX サポートを使用してコンパイルされている場合は、WDDX のみを使用できます。 php_serialize は PHP 5.5.4 以降で利用可能です。 php_serialize は内部的には、serialize/unserialize 関数を直接使用するだけであり、php や php_binary のような制限はありません。 古いシリアライザーを使用すると、$_SESSION のインデックスが数値でなくなり、特殊文字 (| と !) が含まれなくなります。 php_serialize を使用して、スクリプトの終了時に数値および特殊文字のインデックスによって引き起こされるエラーを回避します。 デフォルトではphpが使用されます。
处理器 | 对应的存储格式 |
---|---|
php_binary | 键名的长度对应的 ASCII 字符+键名+经过 serialize() 函数反序列处理的值 |
php | 键名+竖线+经过 serialize() 函数反序列处理的值 |
php_serialize (php>=5.5.4) | 经过 serialize() 函数反序列处理的数组 |
[Session]session.serialize_handler = php_serialize # 使用新的序列化方法
'cookie' => 'zenid', # 与 zencart 保持一致
<? 'stores' => [ 'redis' => [ 'driver' => 'redis', 'connection' => 'default', 'prefix' => 'PHPREDIS_SESSION', # 与 zencart 保持一致 ], ],
<? public function save() { $this->addBagDataToSession(); $this->ageFlashData(); $this->handler->write($this->getId(), $this->prepareForStorage(serialize($this->attributes))); $this->started = false; }
<? /** * Read the session data from the handler. * * @return array */ protected function readFromHandler() { $data = $this->handler->read($this->getId()); if ($data) { $data = @unserialize($this->prepareForUnserialize($data)); if ($data !== false && $data !== null && is_array($data)) { return $data; } } return []; }
zencart writes
PHPREDIS_SESSION :02103fd8mo5jb7qia51lnu7lh5
"a:1:{s:13:\"securityToken\";s:32:\"3c83dcba20e98cfd77ba70db6de93497\";}"
laravel 読み取り
読み取りに失敗しました
デバッグ
<? protected function readFromHandler() { $data = $this->handler->read($this->getId()); error_log(var_export($data, true)); # 跟踪从 redis 中取出的数据,确定问题原因 if ($data) { $data = @unserialize($this->prepareForUnserialize($data)); if ($data !== false && $data !== null && is_array($data)) { return $data; } } return []; }
error_log
[15-Mar-2016 07:59:01 UTC] array ('securityToken' => '03eac95413cbfcc16ea599f36d2e24e2',)
問題の原因
$data = $this-> ;handler-> ;read($this->getId())、$data は配列であり、逆シリアル化が成功する可能性があることを証明していますが、handler->read によってもう一度逆シリアル化されました ( string を取り出すと、後でデシリアライズが行われます)、handler->read にデシリアライズ機能があることを示します。したがって、zencart は保存時と読み取り時にもう 1 回シリアル化と逆シリアル化を実行する必要があります。
書き込み
<?function _sess_write($key, $val) { global $SESS_LIFE; $val = serialize($val); #序列化多一次 $redis_new = new Redis(); $redis_new->pconnect(SESSION_REDIS_HOST_NEW, SESSION_REDIS_PORT_NEW); $redis_new->auth(SESSION_REDIS_PASSWORD_NEW); $redis_new->select(SESSION_REDIS_DB_NEW); $rd_ssk = 'PHPREDIS_SESSION:' . $key ; $redis_new->setex($rd_ssk,$SESS_LIFE, $val); return true;}
read
<?function _sess_read($key) { $redis_new = new Redis(); $redis_new->pconnect(SESSION_REDIS_HOST_NEW, SESSION_REDIS_PORT_NEW); $redis_new->auth(SESSION_REDIS_PASSWORD_NEW); $redis_new->select(SESSION_REDIS_DB_NEW); $rd_ssk = 'PHPREDIS_SESSION:' . $key ; $sess_value = $redis_new->get($rd_ssk); $sess_value = unserialize($sess_value); #反序列化 return $sess_value;}
"s:67:\"a:1:{s:13:\"securityToken\";s:32:\"8a190ebc150a39dd8a7bd46a9c2665cc\";}\";"
laravel は
<?public function save(){ $this->addBagDataToSession(); $this->ageFlashData(); # 模拟 session 赋值 $this->attributes = array( 'securityToken' => '03eac95413cbfcc16ea599f36d2e24e2', ); $this->handler->write($this->getId(), $this->prepareForStorage(serialize($this->attributes))); $this->started = false;}
"s:67:\"a:1:{s:13:\"securityToken\";s:32:\"03eac95413cbfcc16ea599f36d2e24e2\";}\";"
$_SESSION['language'] = 'english';
Session::put('language', 'en');