4

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

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

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

我的问题是:为什么同样的警告也适用于非动态调度的静态方法?

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

在这个例子中,函数Y::bar()没有覆盖X::bar(),所以没有理由触发警告,但 PHP 仍然会。为什么?

4

3 回答 3

4

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

于 2013-05-13T17:57:46.370 回答
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);
}

将输出(在此处运行):

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()

等效的代码不会在 Java 中编译。)

于 2015-04-20T15:38:45.200 回答
-2

这个警告与现实世界无关。忘记学术例子,看看现实世界的例子。有 1000 家 LOCK 制造商制造带有组合触摸板和钥匙覆盖的门锁。他们是否使用 2 个锁舌 - 一个用于组合锁,一个用于钥匙锁?不。门闩锁被抽象为钥匙锁和密码锁。那是真实的世界。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();

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

// FIX PHP's bogus warning of: PHP Warning: Declaration of * should be compatible with
if (PHP_MAJOR_VERSION >= 7) {
    set_error_handler(function ($errno, $errstr) {
       return strpos($errstr, 'Declaration of') === 0;
    }, E_WARNING);
}
于 2017-04-22T13:05:38.053 回答