PHP的$this变量

手册上的一个有意思的小示例。
http://www.php.net/manual/zh/language.variables.basics.php

	$this = 'text'; // error
	$name = 'this';
	$$name = 'text'; // sets $this to 'text'
	echo $$name;

在PHP的词法分析时,$this变量是符合其规则的,在语法解析生成中间代码时,PHP内核会根据变量类型在生成赋值的中间代码时判断是否为$this变量,如果是则报错。这里为什么要报错呢?因为this作为一个特殊的变量,在对象的成员方法等调用初始化时会将this变量添加到活动符号表。

在类的成员方法里面,可以用 ->(对象运算符):$this->property(其中 property 是该属性名)这种方式来访问非静态属性。

当一个方法在类定义内部被调用时,有一个可用的伪变量 $this。$this 是一个到主叫对象的引用(通常是该方法所从属的对象,但如果是从第二个对象静态调用时也可能是另一个对象)。

在词法分析、语法分析并生成中间代码时,$this作为一个特殊的变量存在,特别是在生成中间代码时,代码中充斥着对于this的特殊处理。这些都是为后面的运行做准备,如识别标记出某处使用this变量,在存储opcode的zend_op_array结构体中专门有一个变量this_var标识是否有this变量。一个函数或一个类方法都会生成一个新的zend_op_array,在生成中间代码时,判断当前变量是否为this变量。

this变量在执行过程中会有两种存在状态,一种是全局传递的状态,存储在EG(This),一种是当前作用域状态,以this变量存储在EG(active_symbol_table)(当前执行环境的活动符号表)。
在我们执行一个 op_array 时,比如一个对象的方法,PHP内核会给这个 op_array 生成一个 zendexecutedata ,在生成初始化时,EG(This) 会添加到EG(active_symbol_table) 。
在方法调用过程中,如果有用到this变量,则会直接取EG(active_symbol_table)的值。

那么一个对象中的EG(This)在哪里初始化呢?
就EG(This)变量本身来说,在我们初始化PHP的执行环境时,它和其它全局变量(如EG(scope)等)一样都会被初始化为NULL。
对于一个对象来说,当我们创建了一个对象,调用时,PHP内核会将当前获得的对象直接赋值给EG(This),而这个当前获得的对象是在通过new操作生成对象时创建的对象本身。

如下这个简单示例:

	class Foo {
	     public $var = 10;
 
	     function t() {
	          echo $this->var;     
	     }
 
	     function t2() {
	     	echo 33;
		}
	}
 
	$foo = new Foo();
	$foo->t();

其主程序流程生成的中间代码如下:

        function name:  (null)
	number of ops:  8
	compiled vars:  !0 = $foo
	line     # *  op                           fetch          ext  return  operands
	---------------------------------------------------------------------------------
	   2     0  >   NOP                                                      
	  15     1      ZEND_FETCH_CLASS                              4  :1      'Foo'
	         2      NEW                                              $2      :1
	         3      DO_FCALL_BY_NAME                              0          
	         4      ASSIGN                                                   !0, $2
	  16     5      ZEND_INIT_METHOD_CALL                                    !0, 't'
	         6      DO_FCALL_BY_NAME                              0          
	         7    > RETURN                                                   1

this变量原始的对象值出生在 opcode NEW,经过了赋值(ASSIGN)后,在方法初始化时,将变量本身传递给执行环境的调用者,调用者又在执行调用(DO_FCALL_BY_NAME)时将变量传递给EG(This),当执行这个方法的op_array时,初始化当前作用域的环境(zend_execute_data)时,会将EG(This)作为$this变量添加到活动符号表,后续方法中的$this变量的使用就会直接取符号表的变量。

出自:http://www.phppan.com/2013/10/php-this-var/

<think>好的,我现在需要帮助用户理解PHP中的$this关键字的作用和用法。根据用户提供的四个引用内容,我需要整理出清晰、准确的回答,并生成相关问题。 首先,我要确定用户的需求。用户可能刚接触PHP的面向对象编程,对$this的使用场景和意义不太清楚。需要解释$this的基本概念,并结合示例说明其用法。 从引用中得知,$this是一个指向当前对象实例的伪变量,只能在类的内部使用,用于访问该对象的属性和方法。比如在类的方法中,无法预知实例化的对象名称,因此用$this代替。例如,在类Cart中,访问属性时用$this->items而不是假设对象名为$cart或$another_cart。 接下来,需要总结$this的关键点:指向当前实例、仅内部可用、访问属性和方法的方式。同时要注意与self和parent的区别,但用户的问题主要聚焦于$this,这部分可以简要提及或放在相关问题里。 然后,考虑如何结构化解说。可能分为作用、基本用法、注意事项、代码示例等部分。代码示例很重要,能帮助用户直观理解。根据引用中的例子,比如设置和获取属性,实例化后的不同对象调用方法时$this的指向变化。 注意事项方面,要提到不能在静态方法中使用$this,只能在类内部使用,避免指向错误。同时,结合引用中的错误示例说明正确用法。 生成的相关问题需要围绕$this的扩展知识,比如与self的区别、常见错误、静态方法中的使用限制等。确保问题能引导用户深入理解。 最后,检查回答是否符合系统级指令:使用正确的中文,数学公式格式(虽然这里可能用不到),引用标记正确,代码块使用正确语法,问题部分合理。</think>### PHP$this关键字的作用和用法详解 #### 一、$this的核心作用 `$this`是PHP面向对象编程中的**伪变量**,专门用于在类内部表示**当前对象实例**。它相当于一个指向"自己"的指针,在实例化时动态绑定到具体的对象[^1][^4]。 #### 二、基本用法说明 1. **访问对象属性** ```php class User { public $name; public function setName($name) { $this->name = $name; // 等价于当前对象->name } } ``` 2. **调用对象方法** ```php class Calculator { public function add($a, $b) { return $a + $b; } public function calculate() { return $this->add(5, 3); // 调用本类方法 } } ``` #### 三、关键特性说明 | 特性 | 说明 | |-----------------------|--------------------------------------------------------------------| | 动态绑定 | 根据调用时的对象决定指向(如`$obj->method()`中的`$this`指向`$obj`)[^4] | | 作用域限制 | 只能在类的**非静态方法**中使用 | | 访问控制 | 可以访问本类的private/protected属性(同对象作用域) | | 不可用于静态方法 | 静态方法属于类而非实例,使用`self::`代替[^2] | #### 四、典型应用场景 ```php class Database { private $connection; public function connect() { $this->connection = new PDO(...); } public function query($sql) { return $this->connection->query($sql); } } // 使用示例 $db = new Database(); $db->connect(); // $this指向$db实例 ``` #### 五、常见错误示例 ```php class ErrorExample { public static function wrong() { $this->name = 'test'; // 错误!静态方法中不能使用$this } public function missingArrow() { this->name = 'test'; // 错误!缺少箭头符号$ } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值