PHP static 关键字
最后修改于 2025 年 4 月 16 日
PHP 的 static 关键字用于声明属于类本身的属性和方法,而不是类的实例。可以访问静态成员,而无需创建该类的对象。这使得它们对实用函数和类范围的数据非常有用。
基本定义
静态属性是属于类而不是任何特定实例的变量。它们在整个程序的执行过程中保持其值。静态属性在类的所有实例之间共享。
静态方法是在类级别而不是实例级别上运行的函数。它们可以在不创建对象的情况下被调用。静态方法不能直接访问非静态属性或方法。
语法:class ClassName { public static $property; public static function method() { } }。 静态成员使用范围解析运算符 :: 进行访问。
基本静态属性
此示例演示了一个简单的静态属性,用于跟踪实例计数。
<?php
declare(strict_types=1);
class Counter {
public static int $count = 0;
public function __construct() {
self::$count++;
}
}
new Counter();
new Counter();
new Counter();
echo "Total instances created: " . Counter::$count;
Counter 类有一个静态 $count 属性。每个新实例都会递增此计数器。该值在所有实例中保持不变。我们使用 ClassName::$property 语法访问静态属性。
静态方法
此示例显示了一个执行实用函数的静态方法。
<?php
declare(strict_types=1);
class MathUtils {
public static function square(int $num): int {
return $num * $num;
}
}
$result = MathUtils::square(5);
echo "Square of 5 is: " . $result;
MathUtils 类包含一个静态 square 方法。我们直接调用它,而无需创建实例。静态方法通常用于不需要对象状态的函数。它们使用 :: 访问。
带 Self 的静态属性
此示例演示了如何使用 self 访问静态属性。
<?php
declare(strict_types=1);
class Logger {
private static array $logs = [];
public static function addLog(string $message): void {
self::$logs[] = date('Y-m-d H:i:s') . ': ' . $message;
}
public static function showLogs(): void {
foreach (self::$logs as $log) {
echo $log . "<br>";
}
}
}
Logger::addLog("System started");
Logger::addLog("User logged in");
Logger::showLogs();
Logger 类使用 self 访问其静态 $logs 属性。self 指的是当前类。静态方法只能访问其他静态成员。日志在方法调用之间保持不变。
后期静态绑定
此示例显示了 static 关键字如何启用后期静态绑定。
<?php
declare(strict_types=1);
class ParentClass {
protected static string $name = 'Parent';
public static function getName(): string {
return static::$name;
}
}
class ChildClass extends ParentClass {
protected static string $name = 'Child';
}
echo ParentClass::getName() . "<br>";
echo ChildClass::getName();
getName 中的 static 关键字启用了后期静态绑定。它在运行时解析为被调用的类。没有它,self 将始终引用 ParentClass。这对继承至关重要。
静态工厂方法
此示例演示了用于对象创建的静态工厂方法。
<?php
declare(strict_types=1);
class User {
private string $name;
private function __construct(string $name) {
$this->name = $name;
}
public static function create(string $name): User {
return new self($name);
}
public function getName(): string {
return $this->name;
}
}
$user = User::create('John Doe');
echo "User created: " . $user->getName();
User 类使用静态工厂方法 create。这封装了对象创建逻辑。构造函数是私有的,强制使用工厂方法。此模式提供了对实例化的更多控制。
静态闭包
此示例显示了如何将 static 与闭包一起使用以防止绑定。
<?php
declare(strict_types=1);
class Example {
private string $property = 'instance value';
public function getClosure() {
return static function() {
// Cannot access $this->property here
return "Static closure called";
};
}
}
$example = new Example();
$closure = $example->getClosure();
echo $closure();
闭包之前的 static 关键字可防止绑定到 $this。这使得闭包独立于任何对象实例。尝试访问非静态成员将导致错误。对不需要上下文的回调非常有用。
带有静态的单例模式
此示例使用静态属性实现单例模式。
<?php
declare(strict_types=1);
class Database {
private static ?Database $instance = null;
private function __construct() {
// Private constructor
}
public static function getInstance(): Database {
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
public function query(string $sql): void {
echo "Executing: " . $sql;
}
}
$db = Database::getInstance();
$db->query("SELECT * FROM users");
Database 类通过静态 $instance 确保只存在一个实例。构造函数是私有的,以防止直接实例化。getInstance 控制对单个实例的访问。这是共享资源的常见模式。
最佳实践
- 目的: 将静态用于真正的类级别功能。
- 状态: 尽可能避免可变的静态状态。
- 测试: 静态方法会使测试更加困难。
- 范围: 适当时优先使用私有/受保护的静态成员。
- 性能: 静态调用比实例调用稍快。
来源
本教程介绍了 PHP static 关键字,并提供了实际示例,展示了静态属性和方法在各种场景中的应用,包括高级模式。
作者
列出 所有 PHP 教程。