PHP:为什么“严格的标准:x的声明应该与y兼容”应用于静态方法?

时间:2013-05-13 17:53:06

标签: php warnings strict

PHP警告,“严格的标准:x的声明应与y兼容”如果您编写如下代码,则会发出警告:

class A {
  function foo($x) {
    ..
  }
}
class B extends A {
  function foo() {
    ..
  }
}

这是明智的,因为您认为$a之类的“A”之类的对象引用可能在运行时变为B,因此动态调度的方法调用像$a->foo(3)这样的人最终可能会使用错误数量的参数调用B::foo()

我的问题是:为什么同样的警告应用于静态方法,而不是动态调度?

class X {
  static function bar($x) {
    ..
  }
}
class Y extends X {
  static function bar() {
    ..
  }
}

在此示例中,函数Y::bar()不会覆盖X::bar(),因此没有理由触发警告,但PHP仍然会这样做。为什么呢?

3 个答案:

答案 0 :(得分:4)

就像在Java中一样,您也可以在实例上调用静态方法。所以仍有混淆的余地。

答案 1 :(得分:2)

与Java不同,您可以在实例上调用静态方法,并通过该对象的运行时类型调度它们。因此,Y::bar()实际上会覆盖X::bar()并且它应该是兼容的。

<?php

class X {
  static function bar($x) {
    echo "X::bar() with x = $x\n";
  }
}
class Y extends X {
  static function bar() {
    echo "Y::bar()\n";
  }
}

echo "Static dispatch:\n";
X::bar(1);
Y::bar();

echo "Dynamic dispatch of a static method (surprise!):\n";
$arr = array(new X(), new Y());
foreach ($arr as $a) {
  $a::bar(1);
}

将输出(run it here):

Warning: Declaration of Y::bar() should be compatible with X::bar($x) in /in/phAWB on line 12
Static dispatch:
X::bar() with x = 1
Y::bar()
Dynamic dispatch of a static method (surprise!):
X::bar() with x = 1
Y::bar()

equivalent code不能用Java编译。)

答案 2 :(得分:-2)

此警告与现实世界无关。忘记学术范例,看看现实世界的例子。有1000个LOCK制造商使用组合触摸板和键覆盖来制作门锁。他们使用2个死锁 - 一个用于组合锁,一个用于钥匙锁?没有。 deadbolt锁被抽象到键锁和组合锁。这是真实的世界。 PHP(谁会很快拒绝任何关于这个主题的错误报告)想要坚持下去。

eNodeB Main Loop

PHP甚至不愿意讨论这个问题。因此,我的所有代码都将包含以下内容以消除此PHP 错误

class abstractLock
{
    private $locked = true;
    public function unlock()
    {
       $this->locked=false;
    }
    public function lockStatus()
    {
        if($this->locked) return "Locked\n";
        else return "Unlocked\n";
    }
}

class combinationLock extends abstractLock
{
    private $combination = '32-10-21'; // combination
    public function unlock($combination)        // unlock WITH combination
    {
        if($this->combination == $combination) parent::unlock();
    }
}

class paddleLock extends abstractLock
{
    private $key = '100,70,80,30,50,90,60,40,100'; // ridge heights
    public function unlock($key)                            // unlock WITH key
    {
        if($this->key == $key) parent::unlock();
    }
} 

$lock1 = new paddleLock();
echo "paddleLock is " . $lock1->lockStatus();
$lock1->unlock('100,70,80,30,50,90,60,40,100');
echo "paddleLock is " . $lock1->lockStatus();

$lock2 = new combinationLock();
echo "combinationLock is " . $lock2->lockStatus();
$lock2->unlock('32-10-21');
echo "combinationLock is " . $lock2->lockStatus();