Проблема сериализации класса C ++, доступного через расширение php - PullRequest
4 голосов
/ 04 августа 2011

Я написал библиотеку C ++, которая предоставляет ряд классов. Я также написал расширение php, используя zend, в качестве оболочки над библиотекой 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 instance».

Другими словами, serialize () не знает, как __sleep или __wakeup экземпляра spider_object :: m_pObject, и просто устанавливает его в null. Или, фактически, весь экземпляр spider_object хранится в zend_object_store не сериализуется вообще.

Я думал о переопределении __sleep и __wakeup, но я понятия не имею, что делает Zend под капот и каким должен быть возвращаемый массив из __sleep, плюс как я могу добавить свой собственный m_pObject связанные данные там? Это возможно?

1 Ответ

0 голосов
/ 04 августа 2011

Когда объекты в PHP не сериализованы, конструктор не вызывается (снова), поскольку экземпляр уже был создан (затем сериализован, а затем, наконец, не сериализован).Это должно как минимум объяснить поведение, которое вы видите (сравните: Как Doctrine 2 извлекает сущности без вызова конструктора сущности? ).

Я не знаю, какие подпрограммы предлагает API расширения PHPоднако для десериализации, если вы сможете сохранить экземпляр вашего объекта C ++ в приватном члене PHP, он будет доступен после сериализации.

Я не могу сказать, могут ли __sleep и __wakeupбыть определенным в коде C, вероятно, это работает.Но я не являюсь разработчиком расширений PHP, поэтому я не разбираюсь в этой области.

...