你理解 PHP 中的静态方法吗?
它仍然是一个有争议的话题。让我们尝试了解原因。
函数中的静态变量
您可能已经看过以下代码:
function testStatic() {
static $x = 0;
$x++;
return $x;
}
在这里,我们每次调用testStatic()
时,关键字static
允许递增$x
:
testStatic();
testStatic();
testStatic();
echo testStatic();
最后输出“4”。与其他局部变量不同,静态变量将其值保留在函数作用域之外。
关于这点有一些有趣的用法,例如备忘录。人们使用此技术存储复杂运算之后的结果来优化其脚本。
PHP 类中的静态
每次在 PHP 类中使用关键字 static
时,都在设置与类相关的内容。你无需实例化类即可访问它们:
class MyClass {
public static $myStaticVar;
public static function myStaticFunction() {}
}
MyClass::myStaticFunction();
MyClass::$myStaticVar;
换句话说,你不会将变量和函数绑定到特定对象示例上。
但是,它与过程编程有何不同?为什么还要通过类来使用呢?
静态方法与过程函数
你的代码经常需要一些辅助类,大多数时候,它们以静态调用的形式存在。
$title = TextUtils::normalizeTitle($title);
但是与下面这个有什么不同呢?
$title = normalizeTitle($title);
对于 PHP 而言,这可能没什么不同。静态方法相当于命名空间函数,仅此而已。
命名空间从 PHP 5.5 开始引入。从技术上讲,下面例子中的简单的函数与静态方法没什么不同。
$title1 = \TheNamespace\TextUtils::normalizeTitle($title);
$title2 = \TheNamespace\normalizeTitle($title);
所以如果类中的所有成员都是静态的,那么就可以改写成过程函数和命名空间的形式。但是总是如此吗?
静态 VS 面向对象
你不需要实例化类来访问其静态方法。因此,你的类的所有实例都共享相同的静态方法。
在PHP 类中,你可通过 $this
来获取当前实例,而静态方法无法访问它。
来看看下面这个例子
<?php
class Order {
public $price;
public function __construct($price) {
$this->price = self::formatPrice($price);
}
protected static function formatPrice($price) {
return round($price, 3);
}
}
$order = new Order('73.1111');
echo $order->price;
formatPrice()
不需要使用 $this
,因为该方法并没有涉及到实例的变更。它是静态的,所有的实例共享该方法。
利弊
许多开发更喜欢用非静态方法而不是静态方法。一些人认为静态方法会破坏类的封装性,另外一些则说静态方法会导致代码异味。
不要误解我,这些确实是事实。我的意思是对于该话题的讨论存在一些迷思,例如:
静态代码不安全。
相反,在应用中设置非可变元素似乎更安全。
如果你有大量的数据,使用静态可能不是一个好主意。如果你需要状态机制,也就是说,需要使用逻辑隔离的实例,这似乎也不是一个好主意。
总结
静态可能不错,但可能被误用了。只是在同等条件下,你不能将其应用于任何事情。
我喜欢 OOP,这是一个很棒的范例,但是我想知道是否所有的东西都需要一个对象。我想不是,我有想听听你的意见。
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。