三十的博客

PHP 类中 this 和 self 的区别

发布时间
最后更新
阅读量 加载中...

在 php 中, $this$self 都与面向对象编程有关,但是它们的用途和上下文完全不同

$this

作用: $this 是一个指向当前对象实例的引用(类的实例化对象)
使用场景: 在类的实例方法中访问当前对象的属性和方法
注意点:

php
class User
{
    private string $name;

    public function __construct(string $name)
    {
        $this->name = $name;
    }

    public function getName(): string
    {
        return $this->name;
    }
}

$user = new User('zs');
$userName = $user->getName();

self

作用: $self 是一个指向当前类本身的引用(而非实例)
使用场景:

注意点:

php
 class Counter
{
    private static int $count = 0;

    public static function getCount(): int
    {
        return self::$count;
    }

    public function increment(): void
    {
        self::$count++;
    }
}

$count1 = Counter::getCount(); // 0
$counter1 = new Counter();
$counter1->increment();
$count2 = Counter::getCount(); // 1

扩展阅读 self vs static

self 严格指向定义方法的类,适合不需要继承动态性的场景 static 动态绑定到实际调用的类,适合需要支持多态和继承的场景

self 例子

self 始终指向定义方法的类,即使在子类中调用也不会改变

php
class ParentClass
{
    public static function who(): void
    {
        echo "ParentClass\n";
    }

    public function callWho(): void
    {
        self::who(); // 始终调用 ParentClass::who()
    }
}

class ChildClass extends ParentClass
{
    public static function who(): void
    {
        echo "ChildClass\n";
    }
}

$obj = new ChildClass();
$obj->callWho(); // 输出 "ParentClass"(因为 self 指向 ParentClass)

static 例子

static 支持后期静态绑定,会指向实际调用的类

php
class ParentClass
{
    public static function who(): void
    {
        echo "ParentClass\n";
    }

    public function callWho(): void
    {
        static::who(); // 动态绑定到实际调用的类
    }
}

class ChildClass extends ParentClass
{
    public static function who(): void
    {
        echo "ChildClass\n";
    }
}

$obj = new ChildClass();
$obj->callWho(); // 输出 "ChildClass"(因为 static 动态绑定到 ChildClass)

更复杂的继承场景

php
class Grandparent
{
    public static function who()
    {
        echo "Grandparent\n";
    }
}

class ParentClass extends Grandparent
{
    public static function who(): void
    {
        echo "Parent\n";
    }

    public function callWhoWithSelf(): void
    {
        self::who(); // 始终调用 Parent::who()
    }

    public function callWhoWithStatic(): void
    {
        static::who(); // 动态绑定到实际调用的类
    }
}

class Child extends ParentClass
{
    public static function who(): void
    {
        echo "Child\n";
    }
}

$child = new Child();
$child->callWhoWithSelf();   // 输出 "Parent"(self 绑定到 Parent)
$child->callWhoWithStatic(); // 输出 "Child"(static 动态绑定到 Child)

实际应用场景

self - 单例模式

php
class Singleton
{
    private static ?Singleton $instance = null;

    private function __construct()
    {
    }

    public static function getInstance(): Singleton
    {
        if (self::$instance === null) {
            self::$instance = new self(); // 固定创建 Singleton 实例
        }
        return self::$instance;
    }
}

$s1 = Singleton::getInstance();
$s2 = Singleton::getInstance();

static - 工厂模式

php
abstract class Logger
{
    /**
     * Title: 写日志
     */
    public static function log($message): void
    {
        static::writeToLog($message); // 动态调用子类的实现
    }

    /**
     * Title: 具体写日志的抽象方法
     */
    protected abstract static function writeToLog($message);
}

class FileLogger extends Logger
{
    /**
     * Title: 写文件日志方法
     */
    protected static function writeToLog($message): void
    {
        file_put_contents('log.txt', $message, FILE_APPEND);
    }
}

FileLogger::log("Hello");
#Php