I'm trying to store zvals in a hash table which is part of a resource.
Unfortunately the zvals do not seem to "persist" between function calls:
<?php
$ctx = foo_create_context();
foo_assign_value($ctx, "foo", "bar");
// prints NULL:
var_dump(foo_get_value($ctx, "foo"));
?>
Please see my code below. In foo_get_value zend_hash_find() does not
return FAILURE, so the key is there while the value is gone. Can
someone spot my mistake?
- Martin
typedef struct _foo_context {
HashTable *variables;
} foo_context;
PHP_FUNCTION(foo_create_context) {
foo_context *ctx;
ctx = emalloc(sizeof(foo_context));
ALLOC_HASHTABLE(ctx->variables);
zend_hash_init(ctx->variables, 32, NULL, NULL, 0);
ZEND_REGISTER_RESOURCE(return_value, ctx, le_foo_context);
}
PHP_FUNCTION(foo_assign_value) {
foo_context *ctx;
zval *zcontext;
char *name;
int name_len;
zval *value;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsz",
&zcontext, &name, &name_len, &value) == FAILURE)
{
return;
}
ZEND_FETCH_RESOURCE(ctx, foo_context*, &zcontext, -1,
FOO_CONTEXT_RES_NAME, le_adl_context);
zend_hash_update(ctx->variables, name, name_len + 1, &value,
sizeof(zval*), NULL);
}
PHP_FUNCTION(foo_get_value) {
foo_context *ctx;
zval *zcontext;
char *name;
int name_len;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs",
&zcontext, &name, &name_len) == FAILURE)
{
return;
}
ZEND_FETCH_RESOURCE(ctx, foo_context*, &zcontext, -1,
FOO_CONTEXT_RES_NAME, le_foo_context);
zval **value;
if (zend_hash_find(ctx->variables, name, name_len + 1,
(void**)&value) == FAILURE) {
return;
}
RETVAL_ZVAL(*value, 1, 0);
}
wrote:
> I'm trying to store zvals in a hash table which is part of a resource.
> Unfortunately the zvals do not seem to "persist" between function calls:
>
> [...]
>
> ALLOC_HASHTABLE(ctx->variables);
> zend_hash_init(ctx->variables, 32, NULL, NULL, 0);
>
You probably want to give a destructor to zend_hash_init, since you're
storing zvals, that would be ZVAL_PTR_DTOR.
> [...]
> if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsz",
> &zcontext, &name, &name_len, &value) == FAILURE)
> {
> return;
> }
>
> ZEND_FETCH_RESOURCE(ctx, foo_context*, &zcontext, -1,
> FOO_CONTEXT_RES_NAME, le_adl_context);
>
> zend_hash_update(ctx->variables, name, name_len + 1, &value,
> sizeof(zval*), NULL);
You're not incrementing the refcount of the value you're adding to the
hash table. Call zval_add_ref.
--
Gustavo Lopes
On Fri, 22 Oct 2010 22:22:06 +0100, Martin Jansen martin@divbyzero.net
wrote:I'm trying to store zvals in a hash table which is part of a resource.
Unfortunately the zvals do not seem to "persist" between function calls:You probably want to give a destructor to zend_hash_init, since you're
storing zvals, that would be ZVAL_PTR_DTOR.You're not incrementing the refcount of the value you're adding to the
hash table. Call zval_add_ref.
Those two hints seem to do the trick. Thanks!
- Martin