|  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
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:


Add a Patch

Pull Requests

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2017-07-21 18:40 UTC]
Automatic comment from SVN on behalf of cmb
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 (

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

Related to bug #50892.

Some stupid broke the documentation in
Fixed with <>
 [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
        // 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() {
class B extends A {
    public function onSomethingHook($someEventData) {
        // ...
PHP Copyright © 2001-2023 The PHP Group
All rights reserved.
Last updated: Fri Sep 29 14:01:24 2023 UTC