Re: [Question] Variadic method signature compatibility between 5.6 and 7.0
| From: | Rowan Collins | Date: | Tue, 03 Nov 2015 09:20:54 +0000 |
| Subject: | Re: [Question] Variadic method signature compatibility between 5.6 and 7.0 | ||
| References: | 1 2 3 4 5 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-89048@lists.php.net to get a copy of this message | ||
Marc Bennewitz wrote on 02/11/2015 19:44:
Hi Rowan, On 11/02/2015 05:41 PM, Rowan Collins wrote:That's not equivalent, because the version with no arguments explicitly prohibits zero arguments, which the variadic signature doesn't. You have to compare the possible calls, not convert them into signatures: class Foo {Alexander Lisachenko wrote on 02/11/2015 11:12:In my opinion the warning is valid as the one method defines one optional argument and the overwritten method would accept no or more arguments where the no arguments is wrong: https://3v4l.org/6eMiu class Foo {First definition declares exactly one single parameter, which can be absent during the method call, so I can even write public static function test() {} Second definition defines zero or more arguments, so it can be also described by the same signature: public static function test() {}OK, I got a bit confused with the different optional parameters, and neither your explanation nor Andrea's quite did it for me. But, I think you're right that this should be compatible, if the rule is "any legal call on the parent should also be legal on the child". Currently, all versions of PHP enforce the following: - if parent accepts no parameters, child must accept zero, but could accept one or more optional parameters - if parent accepts zero or one (an optional parameter), child must accept zero, must accept one, but could accept more (so, two optional parameters is fine; no parameters at all is incompatible)public function test($foo = null) {}} class Bar extends Foo {public function test() {} }
public function test($foo = null) {}
}
class Bar extends Foo {
public function test(...$foo) {}
}
$a = new Foo;
$a->test(); // valid
$a->test(42); // valid
$a->test(42, 6, 9); // NOT VALID
$b = new Bar;
$b->test(); // valid
$b->test(42); // valid
$b->test(42, 6, 9); // valid
So any call which is valid on Foo is also valid on Bar. There are calls on Bar which are not valid on Foo, but that is not prohibited elsewhere:
class Baz extends Foo {
public function test($foo = null, $bar = null, $baz = null) {}
}
// no compilation warnings
$c = new Baz;
$c->test(); // valid
$c->test(42); // valid
$c->test(42, 6, 9); // valid
Regards,
--
Rowan Collins
[IMSoP]