Re: __toString() must return a string value
| From: | Johannes Schlüter | Date: | Sun, 22 Feb 2009 10:09:28 +0000 |
| Subject: | Re: __toString() must return a string value | ||
| References: | 1 2 3 4 5 | Groups: | php.pecl.dev |
| Request: | Send a blank email to pecl-dev+get-6145@lists.php.net to get a copy of this message | ||
On Sun, 2009-02-22 at 09:19 +0100, Piotr Pokora wrote:
> What might return NULL zval?
>
> PHP_FUNCTION(date_format)
> {
> [...]
> RETURN_STRING(date_format(format, format_len, dateobj->time,
> dateobj->time->is_localtime), 0);
> }
>
> Can you give me a pointer where this method(function) returns NULL zval
> so I should really worry about in derived class?
I didn't check the code, before, but go up 3 or 4 lines and you read
RETURN_FALSE in case arguement parsing fails - usually we return null in
that case ...
> Of course, you are
> right, to avoid future segfaults when API change I should return zval.
... but that's the point: You should not rely on the types.
> But, I started this thread to talk about this particular case.
That was also meant as general hint ..
> Should it looks like this?
>
> MAKE_STD_ZVAL(return_value);
> Z_TYPE_P(return_value) = IS_STRING;
> zend_call_method_with_1_params(&zend_object,
> Z_OBJCE_P(zend_object), NULL, "format", &return_value, fmt);
If you debug this you will see that, after calling zend_call_method,
return_value points to a string zval having the formatted date, but it
will point to a different place than where the engine expects your
return value.
Using simple printf-"debugging":
php_printf("before calling zend_call_method: %x\n", return_value);
zend_call_method_with_1_params(&zend_object,
Z_OBJCE_P(zend_object), NULL, "format", &return_value, fmt);
php_printf("after calling zend_call_method: %x\n", return_value);
You will see that return_value is different there, whereas with
php_printf("before setting retval: %x\n", return_value);
RETVAL_STRING("a new return value", 1);
php_printf("after setting retval: %x\n", return_value);
the address will be the same.
And no the problem is not within Zend/PHP APIs but C pointer stuff.
johannes