skip to Main Content

If I use Constructor Property Promotion, I can call the constructor automatically. I don’t need write parent::_constructor(). But the children class can access to the attribute private. That is an error that could be solve just don’t use Propery Promotion. Am I wrong on something?

class Parent {
    public function __construct(
        protected $protected,
        private $private
    ) {
    }
}

class Child extends Parent {
    public function __construct(
        protected $protected,
        private $private
    ) {
    }

    function myFunc() {
        echo $this->private; // This works!!
    }
}

2

Answers


  1. Constructor property promotion just means "declaring the property and the constructor argument at the same time". It doesn’t change how inheritance and private properties work.

    Your code is equivalent to this:

    class Parent {
        protected $protected;
        private $private;
    
        public function __construct(
            $protected,
            $private
        ) {
            $this->protected = $protected;
            $this->private = $private;
        }
    }
    
    class Child extends Parent {
        protected $protected;
        private $private;
    
        public function __construct(
            $protected,
            $private
        ) {
            $this->protected = $protected;
            $this->private = $private;
        }
    
        function myFunc() {
            echo $this->private; // This works!!
        }
    }
    

    The child class is never touching the private property on the parent class, it’s just declaring its own private property that happens to have the same name. If you try to echo $this->private in a method defined in Parent, you’ll find that it’s uninitialised: you didn’t run the Parent constructor, so nothing wrote to it.

    Login or Signup to reply.
  2. Constructor property promotion is just a shortcut for declaring the properties and assigning them. So Child declares its own $protected and $private properties, which override the properties inherited from Parent. So Child::$private is private to the Child class, and can be accessed from methods of the Child class.

    Note that you still need to call Parent::__construct(). The initialization of the Child properties doesn’t initialize the Parent properties with the same names. If you don’t call it, Parent methods that try to access $this->private or $this->protected will get an error for the undefined variable.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search