|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2015-12-30 17:46 UTC] norbert at linuxnetworks dot de
Description: ------------ I ran into a weired problem with interfaces in combination with namespaces. In the Aimeos library, decorators can be wrapped around provider objects. The provider objects use this constructor signature: public function __construct( \Aimeos\MShop\Context\Item\Iface $context, \Aimeos\MShop\Service\Item\Iface $serviceItem ); Decorators use this one: public function __construct( \Aimeos\MShop\Service\Provider\Iface $provider, \Aimeos\MShop\Context\Item\Iface $context, \Aimeos\MShop\Service\Item\Iface $serviceItem ); Both have their own interfaces (Provider/Factory/Iface.php and Provider/Decorator/Iface.php) and the Factory interface isn't used for decorators and vice versa. Despite that fact, PHP7 complains that the decorators doesn't implement the Factory interface. I've stripped the source code down as much as possible (classes and interfaces are mostly empty) and pushed it to a GitHub repository: https://github.com/nos3/php7 Furthermore, on travis-ci a test against 5.6 and 7.0 have been done: https://travis-ci.org/nos3/php7 Expected result: ---------------- No error like for PHP 5.6 Actual result: -------------- PHP Fatal error: Declaration of Aimeos\MShop\Service\Provider\Decorator\Base::__construct(Aimeos\MShop\Service\Provider\Iface $provider, Aimeos\MShop\Context\Item\Iface $context, Aimeos\MShop\Service\Item\Iface $serviceItem) must be compatible with Aimeos\MShop\Service\Provider\Factory\Iface::__construct(Aimeos\MShop\Context\Item\Iface $context, Aimeos\MShop\Service\Item\Iface $serviceItem) in /home/vagrant/Code/Laravel/php7/Provider/Decorator/Base.php on line 20 PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Mon Nov 03 07:00:01 2025 UTC |
Here's a self-contained and somewhat reduced reproduce script. It seems to be important that the last class is defined in a separate file: <?php namespace Provider; interface Iface {} abstract class Base { public function __construct( \Aimeos\MShop\Context\Item\Iface $context, \Item\Iface $serviceItem ) { } } namespace Provider\Factory; interface Iface { public function __construct( \Aimeos\MShop\Context\Item\Iface $context, \Item\Iface $serviceItem); } namespace Provider\Delivery; interface Iface extends \Provider\Iface, \Provider\Factory\Iface { } abstract class Base extends \Provider\Base { } class Manual extends \Provider\Delivery\Base implements \Provider\Delivery\Iface { } namespace Provider\Decorator; interface Iface extends \Provider\Iface { public function __construct(\Provider\Iface $provider, $context, \Item\Iface $serviceItem); } $code = <<<'PHP' namespace Provider\Decorator; abstract class Base extends \Provider\Base { public function __construct(\Provider\Iface $provider, $context, \Item\Iface $serviceItem) { } } PHP; eval($code);Ooops, I pasted the non-reduced code. Here's the correct version: <?php namespace Provider; interface Iface { } abstract class Base { public function __construct(\Item\Iface $serviceItem) { } } namespace Provider\Factory; interface Iface { public function __construct(\Item\Iface $serviceItem); } namespace Provider\Delivery; interface Iface extends \Provider\Iface, \Provider\Factory\Iface { } abstract class Base extends \Provider\Base { } class Manual extends \Provider\Delivery\Base implements \Provider\Delivery\Iface { } $code = <<<'PHP' namespace Provider\Decorator; abstract class Base extends \Provider\Base { public function __construct(\Provider\Iface $provider, \Item\Iface $serviceItem) { } } PHP; eval($code);