Re: DateTime call_user_function_ex
| From: | Johannes Schlüter | Date: | Wed, 11 Jul 2007 22:49:25 +0000 |
| Subject: | Re: DateTime call_user_function_ex | ||
| References: | 1 | Groups: | php.pecl.dev |
| Request: | Send a blank email to pecl-dev+get-4797@lists.php.net to get a copy of this message | ||
Hi Piotr,
I didn't check your code in detail but a few ideas:
First of all: In most cases it's better to use zend_call_method instead
of calol_user_function, in this case there's even a macro
zend_call_method_with_1_params in Zend/zent_interfaces.h which makes
this a tiny bit simpler in your case (just pass NULL for fn_proxy if you
call the method just once on that object)
On Wed, 2007-07-11 at 13:40 +0200, Piotr Pokora wrote:
> /* Create params array and format ISO8601 compatible string */
> zval *dt_params;
> MAKE_STD_ZVAL(dt_params);
> array_init(dt_params);
> add_index_string(dt_params, 0, (gchar *)"DateTime::ISO8601", 0);
Here you're setting the string "DateTime::ISO8601" as parameter for the
function you're going to call later, this would mean you're doing
$dt->format("DateTime::ISO8601");
instead of using the constant, as in
$dt->format(DateTime::ISO8601);
A String is interpreted by the date stuff as format specifier, so you
get the name of the day for D of DateTime, a gives you am or pm
depending on the time, ... (see php.net/date_format and php.net/date)
Therefore you need to lookup the value of the constant and use that
value, see zend_get_constant().
>
> zval *f_format;
> MAKE_STD_ZVAL(f_format);
> ZVAL_STRING(f_format, "format", 0);
>
> /* Copy function arguments */
> zval ***args = __copy_args(dt_params);
>
> /* TSRMSLS_FETCH(); */ /* Should be called here (required for CG macro ) */
Some compilers need variable declaratiosn to be on the beginning of the
block, TSRMLS_FETCH declares a variable so it should be moved to the top
(just like f_format and args) if oyu want it to work on any compiler.
> zval *retval;
> call_user_function_ex(NULL, &zvalue, f_format,
> &retval, 1, args, 1, NULL TSRMLS_CC);
> efree(args);
>
> return (const gchar *)Z_STRVAL_P(retval);
> }
>
> http://www.php.net/manual/pl/zend.calling-user-functions.php
> This doc says I should destroy retval. Do I have to use it if I need to return string value?
> If yes, why do I have to copy it over again to another zval?
You have to care for either passing it back to the engine somewhere (for
example as return value from some function, storing it in some
property, ...) or you have to free it somewhere. You don't have to copy
it, but as soon as it is returned you are responsible for it.
Btw. the documentation there is currently a bit outdated (it's from PHP
4.0 times, I think, and was never updated) but Gwynne is currently
working on improving it so best reference is digging through the code
(and Sara's book of course) :-)
johannes