如何使用zend引擎API对类似(int)的值进行类型转换?

mar*_*cio 1 c php-internals

我尝试过的:

//...
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);
//...
Run Code Online (Sandbox Code Playgroud)

问题是,如果arg是一个带有格式错误的数字的字符串,就像"10x"引擎引发了一个通知:

Notice: A non well formed numeric value encountered in...
Run Code Online (Sandbox Code Playgroud)

我真正想要的是能够arg像下面的PHP用户态代码一样进行转换:

(int) "10x" // evaluates to 10, no NOTICE
Run Code Online (Sandbox Code Playgroud)

我仍在浏览zend API,所以欢迎任何有关如何找到一个好的(更新的)PHP内部参考或一般建议的帮助.

Nik*_*kiC 6

您可以使用以下zval_get_long函数执行整数转换而无需修改原始值:

zend_long lval = zval_get_long(zv);
Run Code Online (Sandbox Code Playgroud)

如果要更改现有zval的类型,可以使用以下convert_to_long函数:

convert_to_long(zv);
// Z_TYPE_P(zv) == IS_LONG now
Run Code Online (Sandbox Code Playgroud)

如果zv是引用,convert_to_long将在转换之前解包引用(因此zv将不再是引用).您更有可能要取消引用它(因此引用仍然存在,但zv指向其内部值):

ZVAL_DEREF(zv);
convert_to_long(zv);
Run Code Online (Sandbox Code Playgroud)

请注意,在PHP 7中,没有必要在使用前执行分离convert_to_long.