self 或 $this 在 PHP 中:何时使用什么?带示例解析

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:为什么这个问题困扰着每个 PHP 开发者?

\n\n

如果你曾经用面向对象风格编写过 PHP 代码,你肯定遇到过这个难题:何时使用 self,何时使用 $this? 这个问题是 Stack Overflow 上最热门的问题之一(数千次浏览和数十个投票)。看起来区别很明显,但一旦深入挖掘,即使是经验丰富的开发者也会开始混淆。

\n\n

在本文中,我们将把一切梳理清楚。你将了解到:

\n
    \n
  • self 和 $this 的根本区别是什么;
  • \n
  • 在哪些情况下它们各自是必需的;
  • \n
  • 继承和静态上下文是如何工作的;
  • \n
  • 当然,还会看到可以立即应用的现实代码示例。
  • \n
\n\n

让我们一劳永逸地搞清楚吧!

\n\n

基本规则:静态 vs 实例

\n\n

最重要的一点需要记住:

\n
    \n
  • $this — 引用当前对象(类的实例)。仅在非静态上下文中工作。
  • \n
  • self — 引用编写代码的当前类。用于访问静态属性、常量和静态方法。
  • \n
\n\n

听起来很简单?让我们通过一个示例来验证。

\n\n

示例 1:简单的类

\n
<?php\nclass Coffee\n{\n    public static $type = '阿拉比卡';\n    public $sugar = 2;\n\n    public function info()\n    {\n        // $this — 用于对象属性\n        echo "糖:{$this->sugar} 勺。";\n\n        // self — 用于静态属性\n        echo "咖啡类型:" . self::$type;\n    }\n}\n\n$cup = new Coffee();\n$cup->info(); // 输出:糖:2 勺。咖啡类型:阿拉比卡\n?>
\n\n

这里一切都很合理:$this->sugar 对每杯咖啡都是唯一的,而 self::$type 对所有咖啡都是通用的。

\n\n

继承的陷阱:self vs static

\n\n

这里开始变得有趣了。许多人认为 self 具有多态性,但事实并非如此。self 始终指向它被编写所在的类,即使你从子类调用方法。

\n\n

如果你需要代码考虑到调用它的类(后期静态绑定),请使用 static。

\n\n

示例 2:继承与陷阱

\n
<?php\nclass Animal\n{\n    public static $sound = '...';\n\n    public static function speak()\n    {\n        // 注意:self 是 Animal,而不是 Dog!\n        echo self::$sound;\n    }\n\n    public static function speakCorrect()\n    {\n        // static 是调用该方法的类\n        echo static::$sound;\n    }\n}\n\nclass Dog extends Animal\n{\n    public static $sound = '汪汪!';\n}\n\nDog::speak();       // 输出:...(因为 self = Animal)\nDog::speakCorrect(); // 输出:汪汪!(因为 static = Dog)\n?>
\n\n

这个示例是 bug 的常见原因。如果你在编写库并期望子类能够重写静态属性,请始终使用 static 而不是 self。

\n\n

什么时候必须使用 self?

\n\n

有些情况下 $this 根本不起作用,self 是唯一的选择:

\n\n
    \n
  • 静态方法:在声明为 public static function 的方法内部,没有对象,因此 $this 不可用。只能使用 self。
  • \n
  • 类常量:通过 self::CONSTANT(或 ClassName::CONSTANT)访问。
  • \n
  • 静态属性:self::$property。
  • \n
  • 在构造函数或析构函数内部:虽然那里可以使用 $this,但对于静态操作,最好使用 self。
  • \n

博客

书籍推荐