2

我想问一下如何启用完整的错误报告,php.ini 中的 E_ALL 和启动错误对我的情况没有影响。

我的代码:

class A
{
   function funcA(arg1=null, arg2=null, arg3=false, arg4=null) {}
}

class B extends A
{
   function funcB() {}
}

class C extends B
{
   function funcA(arg1=null, arg2=null, arg3=false) {}
}

使用 php 7.0,它被允许并且正在工作,升级到 php 7.2.15 后,出现某种 php 崩溃,脚本执行停止,错误日志中没有错误。使用 php 7.2 必须有与父类中相同数量的方法参数,这对我来说不是问题,但问题是我没有任何来自 php 的关于此错误的反馈。你有什么想法为什么没有错误或异常?我正在使用启用了所有错误显示的开发 php.ini。

4

1 回答 1

1

从 7.0.33 到 7.3,此代码始终会产生不兼容的签名警告。

可以在这里确认:https ://3v4l.org/Ifmbk

实际上,您无意中违反了SOLIDL的规则,它代表Liskov 的替换原则

程序中的对象应该可以用其子类型的实例替换,而不会改变该程序的正确性。

C和在您的示例中的实例A实际上是不可互换的,即使在签名中有可选参数。

尽管如此,您至少有两个选项,它们都需要更改设计,并且警告本身可以确认气味的存在。

如果确实有很少的通用功能,请删除继承并使用组合:

class B
{
   /**
    * A
    */ 
   private $a;

   public function __construct(A $a) {
       $this->a = $a;
   }
}

或者将功能拆分为不同的方法,并有一个更宽松的接口AbcInterface在其他地方接受并验证您在实际实现中获得的实例类型:

interface AbcInterface
{
    public function B();
}

class A implements AbcInterface
{
    public function funcA($arg1=null, $arg2=null, $arg3=false, $arg4=null)
    {
    }

    public function funcAWithLessArgs($arg1=null, $arg2=null, $arg3=false)
    {
    }
}

实际上,这里需要的是函数重载,这在 PHP 生态系统中从一开始就不存在。

于 2019-02-28T10:36:28.130 回答