诡异的php变量名
来源:互联网 发布:mac怎么关掉死机程序 编辑:程序博客网 时间:2024/05/09 08:04
在类的方法中,$this关键字用来指向当前类的对象实例,如果对$this进行赋值操作,会发生什么事情?
<?php
class Person
{
protected $_name = "phper";
protected $_age = 18;
public function getName()
{
$this = 123;
return $this->_name;
}
public function getAge()
{
return $this->_age;
}
}
$p = new Person();
$p->getName();
?>
执行代码,报错:
1
Fatal error: Cannot re-assign $
this
in...
public function getName()
{
$a = "this";
$$a = 123;
echo $this;
return $this->_name;
}
然后执行代码,发现能够顺利执行,$this的值变成了123, 由此可以判断对$this关键字的保护也仅限与语法分析阶段。
当$this的值变成123之后,按理说$this->_name肯定会报错的,但是居然代码能正常执行,这个确实很让人觉得不可思议。于是推断 $this->_name这样的引用方式和一般的对象变量引用方式在有差异,我们继续对getName做修改:
public function getName()
{
$a = "this";
$$a = 123;
$b = 123;
echo $this;
echo $b;
$this->getAge();
$b->getAge();
return $this->_name;
}
这段代码中,$this和$b的值都等于123,但是$this->getAge()可以顺利执行,$b->getAge()却报错:Fatal error: Call to a member function getAge() on a non-object...
这是一个诡异的问题,于是可以推断$this->getAge()和$b->getAge()在编译之后对应的op handler肯定有所差异,于是查看之。
通过vld查看op的信息:
- $this->getAge()对应的为: ZEND_INIT_METHOD_CALL RES[ IS_UNUSED ] OP1[ IS_UNUSED ] OP2[ IS_CONST (8142027) 'getAge' ]
- $b->getAge()在对应的为: ZEND_INIT_METHOD_CALL RES[ IS_UNUSED ] OP1[ IS_CV !0 ] OP2[ , IS_CONST (8142039) 'getAge' ]
虽然对应了同样的op code,但是由于操作数的不同(前者不使用OP1,后者使用OP1, 且OP1的值!0表示$b),同一个op code对应同一类handler,然后根据操作数的类型确定到此类handler中的某一个handler。
- $this->getAge()对应的handler处理为:ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER
- $b->getAge() 对应的handler处理为:ZEND_INIT_METHOD_CALL_SPEC_CV_CONST_HANDLER
这就是它们的差异了,在执行:
$my = new Person();
$name = $my->getName();
调用getName的时候,getName()的作用域(scope)已经被设置成$name对象中,语法分析的时候对于getName中$this->getAge()这样的调用时只是在当前作用域(scope)中调用getAge()函数,不会理会$this的具体值,而在$b->getAge()这样的调用时,会关心$b所对应的值。
- 诡异的php变量名
- 39-诡异的变量名
- PHP的可变变量名
- PHP的可变变量名
- PHP的可变变量名
- PHP的可变变量名
- 怎样获取PHP变量的变量名之PHP实现
- 怎么样获取PHP变量的变量名之扩展实现
- PHP变量名、类名、函数名均可为变量
- JavaScript 诡异的全局变量和局部变量
- PHP的可变变量名的使用方法分享
- php中可变变量名
- php 可以动态的new一个变量类名
- php中可变变量名使用的作用域问题
- 拼接的变量可以作为php函数名
- 关于php的GearmanClient的诡异事件
- [PHP]explode的一点诡异之处
- PHP foreach()语句的一个诡异问题
- mysql 让空值用0补充的函数IFNULL(a,0)
- Tomcat启动错误:java.lang.OutOfMemoryError
- 几种排序的总结
- C++ wstring string char* wchar_t相互转换
- Android-获取屏幕分辨率
- 诡异的php变量名
- java学习之路----java开发实战经典第12章习题及答案
- servlet生命周期与工作原理
- camera vivi虚拟驱动架构
- c/c++ 数字转成字符串, 字符串转成数字
- Fedora 17 设置开机自动启动服务使用新的服务管理工具
- SharePoint 2013 图文开发系列之入门教程
- Printf() 输出格式控制
- 蓝桥杯:基础练习 特殊回文数