将php-memcached对象传递给扩展方法

时间:2016-02-11 09:48:02

标签: php c php-extension

我是c扩展的新手,所以如果你发现我的问题蹩脚,请原谅。我试图将一个php-memcached对象传递给我的自定义php扩展。有人可以帮助我如何在我的扩展程序代码中检索和使用该对象。

php-memcached对象将在php中创建,然后传递给我的扩展的bleow方法。

我的方法是这样的

PHP_METHOD(Test_Ext, test_memcache) 
{
    zval *obj, *memc_link = NULL;
    memcached_st *memc;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &memc_link) == FAILURE) {
    return;
}
obj = getThis();

    //How can I use the memc_link to get the memcached_st obj ???    

}

我尝试过谷歌搜索,但网上提供的帮助却很少。我也查找了php-memcached源代码,并没有找到导出的struct,我可以通过包含“php_memcached.h”来使用它

1 个答案:

答案 0 :(得分:1)

官方说你不能。

memcached_st存储在对象中。您可以使用"o"修饰符从用户检索该对象。当php-memcached导出类条目时,您也可以请求特定对象。

#include "memcached/php_memcached.h"

/*...*/
zval *memcached_object;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &memcached_object, php_memc_get_ce()) == FAILURE) {
    return;
}
/* ... */

然后你可以确定memcached_object拥有一个memcached PHP对象。但你不知道这个对象是什么样的。遗憾的是,该信息未导出。两者都不是C级API。

如果您喜欢冒险并喜欢与其他私人物品一起玩,那么您可以将对象结构复制到您的代码中并使用它。但请注意:每当memcached维护者决定以任何方式更改其实现时,这可能会严重破坏......并且您的编译器将无法帮助您。

因此,我们从php_memcached.c复制描述它的结构并使用它。请注意,我从原始中删除了一些元素。请参阅内联评论。

#include "memcached/php_memcached.h"

typedef struct {
    zend_object zo;

    struct memc_obj {
        memcached_st *memc;
        zend_bool compression;

#ifdef DISABLED_0
        /* Commenting these out as we don't have access to the
           enum declarations. We should not copy or create any of
           these objects as we won't know the size, but we will know
           the offset of the members above, which should be enough.
           Also we don't know if HAVE_MEMCACHED_SASL is defined so we
           know nothing about store_retry_count's offset.
        */

        enum memcached_serializer serializer;
        enum memcached_compression_type compression_type;
#if HAVE_MEMCACHED_SASL
        zend_bool has_sasl_data;
#endif
        long store_retry_count;
#endif
    } *obj;

    zend_bool is_persistent;
    zend_bool is_pristine;
    int rescode;
    int memc_errno;
} fake_php_memc_t;

PHP_FUNCTION(myfunc)
{
    zval *memcached_object;
    fake_php_memc_t *fakeobj;
    memcached_st *memc;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &memcached_object, php_memc_get_ce()) == FAILURE) {
        return;
    }

    fakeobj = (php_memc_t *) zend_object_store_get_object(object TSRMLS_CC);
    memc = fakeobj->obj->memc;
    /* .... */
}

注意:我没有对此进行测试,可能存在拼写错误等。

提醒:如上所述,请注意这会构建对您的另一个扩展的见解的假设!

最好是让php-memcached维护者导出一个具有你需要的功能的API。