phpphp-7php-7.2php-7.0

Different number of parameters in function overriding


I want to ask how to enable full error reporting, E_ALL and startup errors in php.ini don't have effect in my case.

My code:

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

With php 7.0 it was allowed and it was working, after upgrading to php 7.2.15 there is some kind of crash of php, script execution stops, no errors in error logs. With php 7.2 there must be the same number of method parameters like in parent class, that's not a problem for me, but problem is that I don't have any feedback from php about this error. Do you have any ideas why there is no error or exception? I'm using development php.ini with all errors display enabled.


Solution

  • This code always produces an incompatible signature warning from version 7.0.33 to 7.3.

    It can be confirmed here: https://3v4l.org/Ifmbk

    Actually, you are unintentionally breaking the L rule of the SOLID, which stands for Liskov's Substitution Principle:

    Objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program.

    Instances of C and A in your example are not literally interchangeable, even having optional arguments in the signature.

    Still, you have at least two options and both of them requires a design change and the warning's itself confirming the existence of a smell.

    Remove the inheritance if there is a really few common functionality and go with the composition:

    class B
    {
       /**
        * A
        */ 
       private $a;
    
       public function __construct(A $a) {
           $this->a = $a;
       }
    }
    

    Or split the functionality to different methods and have a more relaxed interface to accept AbcInterface in other places and validate the instance type you got in actual implementation:

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

    In reality, what you need here is function overloading which is does not exists in PHP ecosystem since the beginning.