views:

221

answers:

1

Writing a PHP extension in C, I want to convert a userland object (IS_OBJECT) to a string through __toString() if it has one, and fail otherwise. What should I use? I don't need another zval on output, just a char *.

zval *zo;

switch (Z_TYPE_P(zo)) {
case IS_STRING:
    ... Z_STRVAL_P(zo) ...
    break;
case IS_OBJECT:
    ... ???(zo) ...
    break;
...
}
+1  A: 

The reflection module does something like

ZVAL_STRINGL(&fname, "__tostring", sizeof("__tostring") - 1, 1);
result= call_user_function_ex(NULL, &object, &fname, &retval_ptr, 0, NULL, 0, NULL TSRMLS_CC);
zval_dtor(&fname);

if (result == FAILURE) {
    _DO_THROW("Invocation of method __toString() failed");
    /* Returns from this function */
}

And then you'd extract the char* with Z_STRVAL_P().
But I guess you could also use

case IS_OBJECT:
  if ( SUCCESS==zend_std_cast_object_tostring(uservar, uservar, IS_STRING TSRMLS_CC) ) {
    int len = Z_STRLEN_P(uservar);
    char* pValue = Z_STRVAL_P(uservar);
    ...
  }

zend_std_cast_object_tostring() is implemented in zend/zend_object_handlers.c. You might want to check if it really does what you want

VolkerK
Thanks for the answer. In the end I've settled with `zend_make_printable_zval` (defined in Zend/zend.c): the SPL snippet is ugly, and `zend_std_cast_object_tostring` includes behavior which breaks requirements I didn't mention in my question (sorry about that).
just somebody