【问题标题】:Different number of parameters in function overriding函数覆盖中的参数数量不同
【发布时间】:2019-07-21 18:34:20
【问题描述】:

我想问一下如何启用完整的错误报告,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 并启用所有错误显示。

【问题讨论】:

  • 警告:C::funcA($arg1 = NULL, $arg2 = NULL, $arg3 = false) 的声明应该与 A::funcA($arg1 = NULL, $arg2 = NULL 兼容, $arg3 = false, $arg4 = NULL) 在 (...)/rubbish.php 第 19 行
  • 您是否介意向我指出一些 PHP 参考资料,其中说您尝试做的事情在 PHP7.0 中是允许的? I tried with PHP 7.0.1
  • @Dharman 您的测试运行并打印了警告,问题是脚本根本没有运行。
  • 真的是所有代码吗? Dharman 的测试用例在 7.0 和 7.2 中运行时出现警告,但不会崩溃。因此问题可能与您应用程序中的其他代码有关。

标签: php php-7 php-7.2 php-7.0


【解决方案1】:

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

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

实际上,您无意中打破了SOLIDL 规则,它代表Liskov's Substitution Principle

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

在您的示例中,CA 的实例实际上不能互换,即使在签名中有可选参数。

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

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

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)
    {
    }
}

实际上,这里需要的是function overloading,它从一开始就不存在于 PHP 生态系统中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-07
    • 1970-01-01
    • 2016-04-19
    • 2019-07-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多