Note that there are some explanatory texts on larger screens.

plurals
  1. POphp extension: can not update class field using zend_hash_update
    primarykey
    data
    text
    <p>I want to realize this class into php extension:</p> <pre><code>class MyClass { protected $attrs = array(); public function __construct($id = null) { $this-&gt;attrs['id'] = $id; $this-&gt;attrs['name'] = ''; } public function __get($key) { if (array_key_exists($key, $this-&gt;attr)) return $this-&gt;attrs[$key]; } public function __set($key, $value) { if (array_key_exists($key, $this-&gt;attr)) $this-&gt;attrs[$key] = $value; } } </code></pre> <p>I've already implemented __constructor, $attrs field, and __get method. And now I can't figure about __set.</p> <p>There is my c code:</p> <pre><code>PHP_METHOD(MyClass, __set) { char *key; int key_len; zval *value; if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &amp;key, &amp;key_len, &amp;value)) { RETURN_NULL(); } zval *attrs, *obj; obj = getThis(); attrs = zend_read_property(Z_OBJCE_P(obj), obj, "attrs", strlen("attrs"), TRUE, TSRMLS_C); if (Z_TYPE_P(attrs) == IS_ARRAY &amp;&amp; zend_hash_exists(Z_ARRVAL_P(attrs), key, strlen(key) + 1)) { zend_hash_update(Z_ARRVAL_P(attributes), key, strlen(key) + 1, &amp;value, sizeof(zval*), NULL); } else { zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 1, TSRMLS_C, "unknown field \"%s\"", key); } } </code></pre> <p>Where attrs - declared protected property in init function (I've declared property as null, but when I add data to $attrs in constructor - property updates to be an array)</p> <pre><code>zend_declare_property_null(myclass_ce, "attrs", strlen("attrs"), ZEND_ACC_PROTECTED TSRMLS_CC); </code></pre> <p>So my question is: how I need to update my attr field in c? My extensions succesfully compiles, I can define properties, read them, but I can't set them - because setted value becomes null, example:</p> <pre><code>class MyClass2 extends MyClass { public function __construct($id = null) { parent::__construct($id); $this-&gt;attrs["type"] = "clz"; } } $c = new MyClass(); var_dump($c-&gt;type); // string(3) "clz" $c-&gt;type = "myclz"; // no error, my __set method handles this call, and I'm sure I'm getting correct value var_dump($c-&gt;type); // NULL </code></pre> <p>I'm new to c development and I really need help.</p> <p><strong>UPD 1.</strong> I've tried change __set body to this:</p> <pre><code>zval *strval; MAKE_STD_ZVAL(strval); ZVAL_STRING(strval, Z_STRVAL_P(value), TRUE); if (Z_TYPE_P(attributes) == IS_ARRAY &amp;&amp; zend_hash_exists(Z_ARRVAL_P(attributes), key, strlen(key) + 1)) { zend_hash_update(HASH_OF(attributes), key, strlen(key) + 1, &amp;strval, sizeof(zval*), NULL); } </code></pre> <p>And now I can set string values. If I need to make switch on each type of zval??</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload