PHP 类中 this 和 self 的区别
在 php 中, $this
和 $self
都与面向对象编程有关,但是它们的用途和上下文完全不同
$this
作用: $this
是一个指向当前对象实例的引用(类的实例化对象)
使用场景: 在类的实例方法中访问当前对象的属性和方法
注意点:
- 只能在实例方法中使用(静态方法中不可用)
- 用于区分局部变量和对象属性(例如
$this->property
$property
)
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
是一个指向当前类本身的引用(而非实例)
使用场景:
- 在类的静态方法或实例方法中访问静态成员(静态属性或静态方法)
- 用于在类内部调用自身的静态方法或访问静态属性,避免因为继续导致的意外行为(类似
static
但self
严格指向定义时的类)
注意点:
- 可以用于静态和非静态方法中
- 访问静态成员时需用
::
操作符(例如self::$staticProperty
)
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");