2016-02-11 64 views
0

我是c擴展的新手,所以如果您發現我的問題不好,請原諒。我正在嘗試將php-memcached對象傳遞給我的自定義php擴展。有人可以幫助我如何檢索和使用我的擴展代碼中的對象。將php-memcached對象傳遞給擴展方法

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 ???  

} 

我曾嘗試使用Google,但沒有在網絡上的相同的可用非常少的幫助。我也查找了php-memcached源文件,但是沒有找到輸出的結構文件,通過執行include「php_memcached.h」可以使用。

回答

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。

+0

我試過了,但它正常工作,但正如你正確地提到,在我的代碼中重新定義結構並不是一個好主意。將與php-memcached團隊一起檢查他們是否可以將頭文件中的結構導出。我只是不想重複創建一個memcache實例和添加服務器到它的努力,配置哪些可能在php代碼中是多餘的。感謝您的幫助,您的回答確實清楚了我的許多疑問。 –

相關問題