当我在PHP_FUNCTION里获得一个PHP对象的字符串,我希望在内存中直接生成PHP的对象,共下面代码调用。
类似PHP中的eval函数。
例如:
$strClass = "class A {function test(){echo 'test';}}";
eval($strClass);
把这段功能用php拓展 C或C++实现。
类似PHP中的eval函数。
例如:
$strClass = "class A {function test(){echo 'test';}}";
eval($strClass);
把这段功能用php拓展 C或C++实现。
在php的源码中找eval函数找不到
源码文件:Zend/zend_language_parser.y
-------------------------------
internal_functions_in_yacc:
T_ISSET '(' isset_variables ')' { $$ = $3; }
| T_EMPTY '(' variable ')' { zend_do_isset_or_isempty(ZEND_ISEMPTY, &$$, &$3 TSRMLS_CC); }
| T_INCLUDE expr { zend_do_include_or_eval(ZEND_INCLUDE, &$$, &$2 TSRMLS_CC); }
| T_INCLUDE_ONCE expr { zend_do_include_or_eval(ZEND_INCLUDE_ONCE, &$$, &$2 TSRMLS_CC); }
| T_EVAL '(' expr ')' { zend_do_include_or_eval(ZEND_EVAL, &$$, &$3 TSRMLS_CC); }
| T_REQUIRE expr { zend_do_include_or_eval(ZEND_REQUIRE, &$$, &$2 TSRMLS_CC); }
| T_REQUIRE_ONCE expr { zend_do_include_or_eval(ZEND_REQUIRE_ONCE, &$$, &$2 TSRMLS_CC); }
;第6行那个
T_EVAL '(' expr ')' { zend_do_include_or_eval(ZEND_EVAL, &$$, &$3 TSRMLS_CC); }
就是eval,在其他文件中定义了这个token就是eval。其中第一个参数,我找到了常量的定义:
#define ZEND_EVAL (1<<0)
#define ZEND_INCLUDE (1<<1)
#define ZEND_INCLUDE_ONCE (1<<2)
#define ZEND_REQUIRE (1<<3)
#define ZEND_REQUIRE_ONCE (1<<4)
...
比较有趣,它为什么要这样左移位来赋值?问了做c的同事,给了我一种解释,说是这样写比较简洁。如果要写一个1<<31的实际数太大了,容易出错。void zend_do_include_or_eval(int type, znode *result, const znode *op1 TSRMLS_DC) /* {{{ */
{
zend_do_extended_fcall_begin(TSRMLS_C);
{
zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); opline->opcode = ZEND_INCLUDE_OR_EVAL;
opline->result_type = IS_VAR;
opline->result.var = get_temporary_variable(CG(active_op_array));
SET_NODE(opline->op1, op1);
SET_UNUSED(opline->op2);
opline->extended_value = type;
GET_NODE(result, opline->result);
}
zend_do_extended_fcall_end(TSRMLS_C);
}
/* }}} */楼主继续追下去看看里面的调用逻辑,能否通过这个zend api实现你要的功能。