2012-03-30 53 views
6

自定义serialize_handler在php中使用第三方(django)会话管理的过程中,我需要有自定义序列化函数为了正确编码/解码它适合django的盐渍存储的会话数据。目前,似乎ini设置session.serialize_handler可以是php或wddx。为自定义php SessionHandler(DB存储)

有什么办法可以将一个自定义的serialize_handler设置为一个类吗?

我想有这样的事情:

class CustomSessionSerializer { 

    public static function serialize($data){ 
    // Serializes raw data 
    } 

    public static function unserialize($sdata){ 
    // Deserializes serialized data 
    } 
} 

,并将它使用我的自定义SessionHandler。

igbinary project on github似乎添加一个自定义serialize_handler作为PHP扩展。 我很好奇,如果自定义序列化不可能发生在另一个地方而不是C扩展。

+0

github上的igbinary项目(https://github.com/igbinary/igbinary)似乎实现了自定义序列化,但这远远超出了我对PHP自定义的期望。 – 2012-04-01 18:55:43

+0

我不认为在普通的PHP中可以这样做,除非你接管整个'$ _SESSION'超全局并且自己写一切与会话相关的东西。 – 2012-04-01 18:57:44

回答

0

您可以使用session_set_save_handler()使用自己的会话处理功能

在PHP 5.4,你可以使用SessionHandlerInterface

默认情况下,您将收到已经序列化的数据,因此您将不得不反序列化它并使用您自己的序列化例程。

+0

破解,如果仔细看看我的问题,您会看到我已经设置了一个自定义会话处理程序。问题是关于自定义序列化,因为此步骤在读取之前发生,并且在写入之后发生。 – 2012-04-01 21:20:11

+0

你只剩下session.serialize_handler允许你做的事情(普通的或带有PHP扩展的),或者使用'read'和'write'处理程序并进行自定义的非序列化 - > PHP序列化/ PHP非序列化 - >自定义序列化。 – Crack 2012-04-01 21:37:58

0

可能看起来像一个变通,但它做你所需要的。序列化适用于您的自定义会话处理程序接收到超全局的$_SESSION,并且您需要将其从序列化的读取处理程序中返回。但是,您可以将会话存储为任何序列化或格式或任何您想要的内容。

class SessionHandler { 

    public function __construct() { 
     session_set_save_handler(
      array($this, 'open') 
      ,array($this, 'close') 
      ,array($this, 'read') 
      ,array($this, 'write') 
      ,array($this, 'destroy') 
      ,array($this, 'gc') 
     ); 
    } 

    public function open($savePath, $sessionName) { 
     return true; 
    } 

    public function close() { 
     return true; 
    } 

    public function read($id) { 
     $data = CustomStorage::fetchSessionData($id); 
     return serialize(
      CustomSerialization::unserialize($data); 
     ); 
    } 

    public function write($id, $serializedData) { 
     CustomStorage::writeSessionData(
      $id 
      ,CustomSerialization::serialize(unserialize($serializedData)) 
     ); 
     return true; 
    } 

    //gc and destroy 
} 

虽然不漂亮,有一些开销,但你只需要存储时控制序列化,所以它应该做的伎俩。

希望它有帮助!

+0

感谢capi,不幸的是,它看起来像是在session_encode被调用时发生的奇怪序列化,并且在我看来,这一步可能被取消 – 2012-04-07 22:15:23

2

我一直在处理这个问题,并有一个解决方案。

想法是,尽管您可以轻松地从PHP修改session.serializer_handler,但在运行序列化程序之前,可以清空$ _SESSION的内容。
使用会话的管理(如Zend的\会议\ SessionManager),其中与register_shutdown_function注册的功能,在被传递回save_handler$ _SESSION内容复制一个类,然后$ _SESSION是空的。

因此,串行器运行但空字符串,并且自定义序列化在您的自定义save_handler上执行。