2011-08-03 27 views
4

我写了一个C++库,公开了一些类。我还使用zend编写了一个php扩展,作为C++库的封装。序列化可通过php扩展访问的C++类

我有一个问题,正确序列化我的对象,例如,当我尝试将它们存储在$ _SESSION中。

下面是一个例子:

struct spider_object 
{ 
    zend_object m_std; 
    Spider::QGramTokenizer* m_pObject; 
}; 

... 

zend_class_entry *spider_QGramTokenizer_ce; 

PHP_METHOD(spider_QGramTokenizer, __construct) 
{ 
    long lQGramSize; 

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &lQGramSize) == FAILURE) 
    { 
     WRONG_PARAM_COUNT; 
    } 

    Spider::QGramTokenizer* pQT = new Spider::QGramTokenizer(static_cast<uint16_t>(lQGramSize)); 
    spider_object* pO = static_cast<spider_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); 
    pO->m_pObject = pQT; 
}  


PHP_METHOD(spider_QGramTokenizer, getQGramSize) 
{ 
    spider_object *pO = static_cast<spider_object*>(zend_object_store_get_object(getThis() TSRMLS_CC)); 
    Spider::QGramTokenizer* pQT = static_cast<Spider::QGramTokenizer*>(pO->m_pObject); 

    if (pQT != NULL) 
    { 
     RETURN_LONG(pQT->getQGramSize()); 
    } 
    else 
     zend_error(E_ERROR, "Null QGramTokenizer instance.\n"); 
} 

我创造我的脚本spider_QGramTokenizer对象和它的伟大工程。一旦我将它作为会话变量存储并尝试从不同的脚本中获取它,我会将该对象恢复正常,但如果我调用getQGramSize作为示例,那么会出现“Null QGramTokenizer实例”错误。

换句话说,serialize()不知道如何__sleep或__wakeup spider_object :: m_pObject实例,它只是简单地将它设置为null。或者,实际上,存储在zend_object_store 中的整个spider_object实例根本没有序列化。

我想重写__sleep和__wakeup的,但我不知道 下做的引擎盖和从什么__sleep返回数组需要什么Zend的,再加上我怎么搭载在那里我自己 m_pObject相关的数据?那可能吗?

回答

0

当PHP中的对象被反序列化时,构造函数不会被调用(再次),因为实例已经构建(然后序列化,然后最终反序列化)。这至少应该解释你看到的行为(比较:How does Doctrine 2 retrieve entities without calling the entity's constructor?)。

我不知道PHP扩展API为反序列化提供了哪些例程,但是如果您能够将C++对象的实例存储在PHP私有成员中,它将在序列化后可用。

我不能说如果__sleep__wakeup也可以在C代码中定义,也许这是有效的。但我不是一个PHP扩展开发人员,所以我的专业知识在这个领域没有。