PHP静态方法

Cho*_*pic 6 php static-methods

我知道静态方法无法访问其类类型的实例对象的状态,因此$this在它们内部引用会导致错误.但是对象可以使用对象到成员运算符引用静态方法->

$obj->staticMethod();
Run Code Online (Sandbox Code Playgroud)

甚至可以通过参数传递它们的状态.

$para1 = $obj->para1;

$para2 = $obj->para2;

$obj->staticMethod($para1, $para2);
Run Code Online (Sandbox Code Playgroud)

在静态上下文中解析静态时,最后一个示例是如何实现的.如果有人可以向我解释一下php代码中静态的一般行为.你甚至可以谈论C相关的概念,如果它会有所帮助.

Jus*_*ent 2

既然你说你已经明白这static意味着什么,我就跳过它。

然而,参考 PHP 的有关关键字的文档static可能仍然是个好主意。特别是以下两个警报很重要(而且确实很难浏览)。

注意    在 PHP 5 中,静态调用非静态方法会生成E_STRICT级别警告。

还有这个(斜体强调我的)。

警告     在 PHP 7 中,不推荐静态调用非静态方法,并且会生成E_DEPRECATED警告。将来可能会删除对静态调用非静态方法的支持。

因此,长话短说:是的,您的示例将运行(暂时),因为 PHP 解释器将尝试为您修复错误。但是,您绝对不应该这样做。PHP 解释器将执行以下操作:

说你的$obj类型Foo。然后它会读取

$obj->staticMethod($para1, $para2);
Run Code Online (Sandbox Code Playgroud)

得出结论staticMethodstatic,而是执行

Foo::staticMethod($para1, $para2);
Run Code Online (Sandbox Code Playgroud)

传递作为 实例属性的参数当然是完全可以的FoostaticMethod参数从哪里来并不重要。


详细说明为什么它有效,但$thisstatic方法中使用是不允许的。

您可以将普通方法视为static具有一个额外功能的函数:它们接收一个隐式参数$this。的值$this就是调用该方法的对象。因此,$obj->do($a, $b, $c)相当于调用并命名,Foo::do($obj, $a, $b, $c)的第一个参数do$this这很方便,因为我们现在可以轻松定义适用于对象实例的方法,而不必一遍又一遍地显式声明该实例是我们方法的参数。伟大的。

现在回到static函数。与普通方法的唯一区别是它们不接收此隐式$this参数。因此,$this在它们内部使用是无效的。不是因为它被禁止,而是因为它没有引用任何东西。PHP 没有(也不能)知道$this应该引用什么。

另一种看待它的方式。假设我们的Foo类有两个属性:$para1$para2,都是数字。假设您编写了一个返回这些数字之和的方法。一种方法是这样做:

public static function sum($para1, $para2) {
  return $para1 + $para2;
}
Run Code Online (Sandbox Code Playgroud)

伟大的。作品。然而,不得不这样称呼它很烦人

$sum = Foo::sum($obj->para1, $obj->para2);
Run Code Online (Sandbox Code Playgroud)

所以,这就是方法的用途!

public function sum(/* implicit $this parameter */) {
  // write looking up the properties once inside the function, instead
  // of having to write it every time we call the function!
  return $this->para1 + $this->para2;
}

// ...

$sum = $obj->sum(); // $obj is passed implicitly as $this
Run Code Online (Sandbox Code Playgroud)

因为静态函数不接收隐式$this参数,所以$this在它们内部使用就像$undefined在从未定义它时尝试使用它一样。故无效。