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