Bug #67851 [NEW]: Extending method visibility with a trait does not work with interfaces
| From: | awoody_02 at hotmail dot com | Date: | Sat, 16 Aug 2014 22:41:16 +0000 |
| Subject: | Bug #67851 [NEW]: Extending method visibility with a trait does not work with interfaces | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-187152@lists.php.net to get a copy of this message | ||
From: awoody_02 at hotmail dot com
Operating system: Windows 7 Ultimate SP1
PHP version: 5.5.15
Package: Class/Object related
Bug Type: Bug
Bug description:Extending method visibility with a trait does not work with interfaces
Description:
------------
Consider a class that implements an interface, thereby requiring a
public method, and that inherits a protected or private implementation
of that method from a base class.
Normally it is possible to extend the visibility of the inherited method
by overriding it with a public method of the same name that simply
defers the call to parent::method().
However if this overriding method is imported from a trait, PHP issues a
fatal error complaining that the visibility of the method in the base
class is insufficient to meet the requirements of the interface.
Removing the interface requirement from the class and using Reflection
shows that it successfully imports the public method from the trait and
overrides the protected/private inherited method, so the bug must be in
the checking for consistency with the interface. The line on which the
error is reported is the line that contains the opening brace of the
class definition that throws the error.
Test script:
---------------
interface IReadOnlyObject
{
public function GetValue();
}
interface IWritableObject extends IReadOnlyObject
{
public function SetValue($value);
}
trait ReadOnlyObjectMethods
{
private $value = null;
public function GetValue()
{
return $this->value;
}
protected function SetValue($value)
{
$this->value = $value;
}
}
trait WritableObjectMethods
{
public function SetValue($value)
{
parent::SetValue($value);
}
}
class ReadOnlyObject implements IReadOnlyObject
{
use ReadOnlyObjectMethods;
}
class WritableObject extends ReadOnlyObject implements IWritableObject
{
use WritableObjectMethods;
}
$o = new WritableObject();
$o->SetValue('hello');
echo $o->GetValue();
Expected result:
----------------
hello
Actual result:
--------------
Fatal error: Access level to ReadOnlyObject::SetValue() must be public
(as in class IWritableObject) in test.php on line 42
--
Edit bug report at https://bugs.php.net/bug.php?id=67851&edit=1
--