本文共 1736 字,大约阅读时间需要 5 分钟。
建议读者先看下这边文章
接下来我会从源码的角度来观察这些现象
看一段简单的代码
然后查到赋值对应的opcode是 ZEND_ASSIGN_SPEC_CV_CONST_HANDLER,在zend_vm_execute.h中找到对应的实现
static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS){ USE_OPLINE zval *value; zval **variable_ptr_ptr; SAVE_OPLINE(); value = opline->op2.zv; variable_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr_ptr == NULL)) { if (zend_assign_to_string_offset(&EX_T(opline->op1.var), value, IS_CONST TSRMLS_CC)) { if (RETURN_VALUE_USED(opline)) { zval *retval; ALLOC_ZVAL(retval); ZVAL_STRINGL(retval, Z_STRVAL_P(EX_T(opline->op1.var).str_offset.str)+EX_T(opline->op1.var).str_offset.offset, 1, 1); INIT_PZVAL(retval); EX_T(opline->result.var).var.ptr = retval; } } else if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else if (IS_CV == IS_VAR && UNEXPECTED(*variable_ptr_ptr == &EG(error_zval))) { if (0) { zval_dtor(value); } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else { if (IS_CONST == IS_TMP_VAR) { value = zend_assign_tmp_to_variable(variable_ptr_ptr, value TSRMLS_CC); } else if (IS_CONST == IS_CONST) { value = zend_assign_const_to_variable(variable_ptr_ptr, value TSRMLS_CC); } else { value = zend_assign_to_variable(variable_ptr_ptr, value TSRMLS_CC); } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(value); EX_T(opline->result.var).var.ptr = value; } } /* zend_assign_to_variable() always takes care of op2, never free it! */ CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE();}
转载地址:http://pksmb.baihongyu.com/