Silence "Declaration ... should be compatible" warnings in PHP 7

Viewed 48781

After upgrade to PHP 7 the logs almost choked on this kind of errors:

PHP Warning: Declaration of Example::do($a, $b, $c) should be compatible with ParentOfExample::do($c = null) in Example.php on line 22548

How do I silence these and only these errors in PHP 7?

  • Before PHP 7 they were E_STRICT type of warnings which could be easily dealt with. Now they're just plain old warnings. Since I do want to know about other warnings, I can't just turn off all warnings altogether.

  • I don't have a mental capacity to rewrite these legacy APIs not even mentioning all the software that uses them. Guess what, nobody's going to pay for that too. Neither I develop them in the first place so I'm not the one for blame. (Unit tests? Not in the fashion ten years ago.)

  • I would like to avoid any trickery with func_get_args and similar as much as possible.

  • Not really I want to downgrade to PHP 5.

  • I still want to know about other errors and warnings.

Is there a clean and nice way to accomplish this?

8 Answers

You can remove the parent class method definition altogether and intercept it with a magic method.

public function __call($name, $args)
{
    if($name == 'do') {
        // do things with the unknown # of args
    } else {
        throw new \Exception("Unknown method $name", 500);
    }
}

I just ran into this problem and went this route

If the base class has fewer arguments than the derived class, it is possible to add additional argument(s) to the derived class like this:

    $namespace = 'default';
    if (func_num_args() > 2) {
        $namespace = func_get_arg(2);
    }

In this way, you add a 3rd "defaulted" argument, but do not change the signature. I would only suggest this if you have a substantial amount of code that calls this and are unable to change that code, and want to maintain backward compatibility.

I found this situation in some old Joomla code (v1.5) where JSession::set added a $namespace param, but has JObject as a base class, where JObject::set has no such parameter.

Related