ZetCode

PHP static 关键字

最后修改于 2025 年 4 月 16 日

PHP 的 static 关键字用于声明属于类本身的属性和方法,而不是类的实例。可以访问静态成员,而无需创建该类的对象。这使得它们对实用函数和类范围的数据非常有用。

基本定义

静态属性是属于类而不是任何特定实例的变量。它们在整个程序的执行过程中保持其值。静态属性在类的所有实例之间共享。

静态方法是在类级别而不是实例级别上运行的函数。它们可以在不创建对象的情况下被调用。静态方法不能直接访问非静态属性或方法。

语法:class ClassName { public static $property; public static function method() { } }。 静态成员使用范围解析运算符 :: 进行访问。

基本静态属性

此示例演示了一个简单的静态属性,用于跟踪实例计数。

static_property.php
<?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 语法访问静态属性。

静态方法

此示例显示了一个执行实用函数的静态方法。

static_method.php
<?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 访问静态属性。

static_self.php
<?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 关键字如何启用后期静态绑定。

late_binding.php
<?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。这对继承至关重要。

静态工厂方法

此示例演示了用于对象创建的静态工厂方法。

static_factory.php
<?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 与闭包一起使用以防止绑定。

static_closure.php
<?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。这使得闭包独立于任何对象实例。尝试访问非静态成员将导致错误。对不需要上下文的回调非常有用。

带有静态的单例模式

此示例使用静态属性实现单例模式。

singleton.php
<?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 static 关键字,并提供了实际示例,展示了静态属性和方法在各种场景中的应用,包括高级模式。

作者

我叫 Jan Bodnar,是一位充满激情的程序员,拥有丰富的编程经验。自 2007 年以来,我一直在撰写编程文章。迄今为止,我撰写了 1,400 多篇文章和 8 本电子书。我拥有超过十年的编程教学经验。

列出 所有 PHP 教程