何时使用 self,何时使用 $this?一劳永逸地搞清楚
\n\n如果你曾经用面向对象风格编写过 PHP 代码,那么你肯定遇到过这个问题:“到底该选 self 还是 $this?”这个问题非常流行,以至于在 Stack Overflow 上获得了数万次浏览和数百条评论。这并非偶然:它们之间的区别是那些“小细节”之一,它可能让你的代码虽然能运行但晦涩难懂,或者变得优雅且清晰。
让我们先明确一点:这两者不可互换。它们有着不同的理念,更重要的是,在继承时行为也不同。如果你在应该用 self 的地方用了 $this,或者反之,你就有可能遇到难以发现的逻辑错误。
在本文中,我们将从基础到高级场景,把所有内容梳理清楚。开始吧!
\n\n\n\n
简短回答(给赶时间的人)
\n\n如果你只想记住一条规则,请记住这条:
\n\n- \n
$this->— 用于访问实例(对象)的属性和方法。仅在非静态上下文中有效。 \n self::— 用于访问类的静态属性和方法。在静态和非静态上下文中都有效。 \n static::— “后期静态绑定”。当需要子类覆盖父类的行为时使用。 \n
但魔鬼,一如既往,藏在细节中。让我们深入探讨。
\n\n什么是 $this?
\n\n$this 是一个伪变量,它引用当前对象。它仅在类的方法(非静态方法)内部可用,并指向你正在操作的那个实例。
<?php\n\nclass User {\n public string $name;\n\n public function setName(string $name): void {\n $this->name = $name; // 访问当前对象的属性\n }\n\n public function getName(): string {\n return $this->name;\n }\n}\n\n$user = new User();\n$user->setName('安娜');\necho $user->getName(); // 安娜\n\n很简单:$this->name 的意思是“获取调用此方法的那个对象的 name 属性”。
什么是 self?
\n\nself 是对当前类的引用,而不是对对象的引用。它用于访问类的静态成员(使用关键字 static 声明的属性和方法)。
<?php\n\nclass Config {\n public static string $appName = 'PythonLib';\n\n public static function getAppName(): string {\n return self::$appName; // 访问类的静态属性\n }\n}\n\necho Config::getAppName(); // PythonLib\n\n请注意:self 始终指向它被编写所在的类。即使你创建了一个子类,父类中的 self 仍然指向父类。这是它与 static 最重要的区别。
主要区别:继承时的 self vs $this
\n\n这里开始变得有趣了。假设你有一个基类 Animal 和一个子类 Dog。
<?php\n\nclass Animal {\n public static function whoAmI(): string {\n return '我是动物';\n }\n\n public function say(): string {\n // 使用 self — 它绑定到 Animal 类\n return self::whoAmI();\n }\n}\n\nclass Dog extends Animal {\n public static function whoAmI(): string {\n return '我是狗';\n }\n}\n\n$dog = new Dog();\necho $dog->say(); // 我是动物