I am new to c extension, so please excuse if you find my question lame. I am trying to pass a php-memcached object to my custom php-extension. Can someone help me with how can I retrieve and use the object in my extension code.
A php-memcached object will be created in php and then passed to the bleow method of my extension.
My method is something like this
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 ???
}
I have tried googling but there is very less help available on the net for the same. I also looked for the php-memcached source and didn't find the struct exported which I could use by doing an include "php_memcached.h"
Officially you can't.
The memcached_st
is stored inside an object. You can retrieve that object from the user with the "o"
modifier. As php-memcached exports the class entry you can also request the specific object.
#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;
}
/* ... */
Then you can be sure that memcached_object
holds a memcached PHP object. But you don't know what this object looks like. Unfortunately that information isn't exported. Neither is a C level API.
If you like risk and like playing with other's private things you however can copy the object structure into your code and work with that. But be warned: That may break heavily whenever memcached maintainers decide to change their implementation in any way ... and your compiler won't be able to help you.
So we copy the structure describing it from php_memcached.c and work with it. Note that I cut out some elements from the original. See inline comment.
#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;
/* .... */
}
Note: I haven't tested this, there might be typos etc.
Reminder: As said, be careful this builds assumptions about the insights of another extension into yours!
Better would be to ask php-memcached maintainers to export an API with the features you need.