1

What I've tried:

//...
zend_long dest;
if (UNEXPECTED(!zend_parse_arg_long(arg, &dest, NULL, 0, 0))) {
    zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be of the type integer", "", zend_zval_type_name(arg), "", arg);
}
zval_ptr_dtor(arg);
ZVAL_LONG(arg, dest);
//...

The problem is that if arg is a literal string with a malformed number like "10x" the engine raises a notice:

Notice: A non well formed numeric value encountered in...

What I really wanted is to be able to cast arg just like as the following PHP userland code:

(int) "10x" // evaluates to 10, no NOTICE

I'm still crawling through the zend API so any help on how to find a good (updated) PHP internals reference or general advice is welcome.

marcio
  • 10,002
  • 11
  • 54
  • 83

1 Answers1

6

You can perform an integer cast without modifying the original value using the zval_get_long function:

zend_long lval = zval_get_long(zv);

If you want to change the type of an existing zval you can use the convert_to_long function:

convert_to_long(zv);
// Z_TYPE_P(zv) == IS_LONG now

If zv is a reference, convert_to_long will unwrap the reference before casting (so zv will no longer be a reference). It is more likely that you want to dereference it instead (so the reference is still there, but zv points to its inner value):

ZVAL_DEREF(zv);
convert_to_long(zv);

Note that in PHP 7 it is not necessary to perform a separation before using convert_to_long.

NikiC
  • 100,734
  • 37
  • 191
  • 225
  • Thanks, that really cleared things up. Any good place with a good zend api reference? Official documentation seems very outdated and sparse. – marcio Jan 17 '15 at 23:07
  • 1
    @marcio You're a bit out of luck there right now, there isn't really any docs on the PHP 7 API yet. The closest is this migration info: https://wiki.php.net/phpng-upgrading Which is also not totally up to date ^^ – NikiC Jan 17 '15 at 23:30