php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #74932 ascending visibility
Submitted: 2017-07-16 22:17 UTC Modified: 2017-07-21 18:42 UTC
From: vuk dot kulvar+php at gmail dot com Assigned: cmb (profile)
Status: Not a bug Package: Class/Object related
PHP Version: 7.1.7 OS: Windows 10
Private report: No CVE-ID: None
 [2017-07-16 22:17 UTC] vuk dot kulvar+php at gmail dot com
Description:
------------
When a parent class has a static method.

From the static method of the parent class, you can access protected methods & properties added from the child class.

I'm not talking about redeclaration, but methods & properties that doesn't exists in the parent class.

Test script:
---------------
class Alpha {
	public static function Render($object) {
		echo $foo->property;
		echo $object->method();
	}
}
class Omega extends Alpha {
	protected $property = 'Property';
	protected function method() {
		return 'Method';
	}
}
Alpha::Render(new Omega());

Expected result:
----------------
Fatal error: Cannot access protected property Omega::$property
Fatal error: Call to protected method Omega::method()

Actual result:
--------------
Property
Method

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-07-21 18:40 UTC] cmb@php.net
Automatic comment from SVN on behalf of cmb
Revision: http://svn.php.net/viewvc/?view=revision&revision=342692
Log: Reverted revision(s) 337719 from phpdoc/en/trunk/language/oop5/visibility.xml:
Protected members cannot be accessed by parent classes

--
Provided by anonymous 62572 (tunght13488@gmail.com)
........

If we like it or not, that's how it is. See also bug #74932.
 [2017-07-21 18:42 UTC] cmb@php.net
-Status: Open +Status: Not a bug -Assigned To: +Assigned To: cmb
 [2017-07-21 18:42 UTC] cmb@php.net
This is expected, but currently undocumented[1] and maybe
undesirable behavior. I don't think we can change that in a minor
version.

Related to bug #50892.

[1]
Some stupid broke the documentation in
<http://svn.php.net/viewvc?view=revision&revision=337719>
Fixed with <http://svn.php.net/viewvc?view=revision&revision=342692>
 [2018-05-26 13:26 UTC] rowan dot collins at gmail dot com
This is a consequence not of visibility, but of "duck typing". There is no difference in PHP between "redeclaration" or "overriding" and simply adding a new member - all lookups are dynamic at runtime.

It may seem odd at first that a parent class can access protected members of a child class at all, but consider this pattern:

class A {
    public function something() {
        // important logic
        $this->onSomethingHook($someEventData);
        // more important logic
    }
    protected function onSomethingHook($someEventData) {
        // No logic; extension point provided for sub-classes to add custom behaviour
    }
}
class B extends A {
    protected function onSomethingHook($someEventData) {
        // Custom logic here, which will be called from class A
   }
}

At a glance, you might say that A::something() is calling B::onSomethingHook(), but in fact the run-time behaviour would be identical if we declared A::onSomethingHook as abstract, or didn't declare it at all - as far as PHP is concerned, the lookup is against whatever $this resolves to at run-time.

If we required a declaration of onSomethingHook in A (or its ancestors), would we also require it with a public member? If not, why not?

class A {
    public function something() {
        $this->onSomethingHook($someEventData);
    }
}
class B extends A {
    public function onSomethingHook($someEventData) {
        // ...
   }
}
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Sat Jul 20 16:01:26 2019 UTC