2

I want to be able to set a private attribute's value in the parent constructor, and call the value in a child's constructor or method.

For example:

<?php


abstract class MainClass
{
    private $prop_1;
    private $prop_2;


     function __construct()
     {
            $this->prop_2 = 'this is  the "prop_2" property';
     }
}

class SubClass extends MainClass
{
    function __construct()
    {
        parent::__construct();
        $this->prop_1 = 'this is the "prop_1" property';
    }

    public function GetBothProperties()
    {
        return array($this->prop_1, $this->prop_2);
    }

}

$subclass = new SubClass();
print_r($subclass->GetBothProperties());

?>

Output:

Array
(
    [0] => this is the "prop_1" property
    [1] => 
)

However, if I change prop_2 to protected, the output will be:

Array
(
    [0] => this is the "prop_1" property
    [1] => this is  the "prop_2" property
)

I have basic knowledge of OO and php, but I can't figure out what is preventing prop_2 from being called (or shown?) when it's private; it can't be a private/public/protected issue, since 'prop_1' is private and able to be called and shown... right?

Is it an issue of assigning the values in the child class vs parent class?

I would appreciate help in understanding why.

Thank you.

  • I could be wrong here but it seems as though your code is creating a public property called prop_1 when your constructor of your SubClass runs. This is why you are getting output for prop_1 but not for prop_2. You should be able to use getters and setters to solve this problem by implementing them in the parent class. – Simon H Mar 28 '11 at 10:26
  • 1
    *(reference)* [PHP Manual, Classes and Objects: Visibility](http://de.php.net/manual/en/language.oop5.visibility.php) – Gordon Mar 28 '11 at 10:28
  • Thanks ZeSimon, that's what I was looking for (why I was getting prop_1). –  Mar 30 '11 at 14:26
  • So the prop_1 that is echoed isn't the prop_1 of the abstract class? –  Mar 30 '11 at 14:34

4 Answers4

6

Private properties of parent class can not be accessed in Child class and vice versa.

You can do like this

abstract class MainClass
{
   private $prop_1;
   private $prop_2;


   function __construct()
   {
        $this->prop_2 = 'this is  the "prop_2" property';
   }

   protected function set($name, $value)
   {
        $this->$name = $value;
   }

   protected function get($name)
   {
      return $this->$name;
   }

 }


class SubClass extends MainClass
{
    function __construct()
    {
        parent::__construct();
        $this->set('prop_1','this is the "prop_1" property');
    }

    public function GetBothProperties()
    {
        return array($this->get('prop_1'), $this->get('prop_2'));
    }

}
Gaurav
  • 28,447
  • 8
  • 50
  • 80
6

If you want to access the parent's properties from the child class, you must make the parent's properties protected NOT private. This way they are still inaccessible externally. You can't override the parent's private properties visibility in the child class in the way you are trying to.

James Butler
  • 3,852
  • 1
  • 26
  • 38
  • Thanks a lot, I do get that, but like I said, I was just wondering why I got the prop_1 not prop_2. Apparently it's because I assigned its value in the sub class. This is all kind of new to me, and I appreciate the help. :) –  Mar 30 '11 at 14:29
  • Yeah, sorry I couldn't help with that bit, I just saw the first code and bashed out a 10 second answer in a spare moment. It now looks as if its been answered above so hopefully you have all you need. As a general rule use protected for internal properties rather private where possible as it leads to less headaches in the future when you/someone need to extend something in a way you didn't predict. – James Butler Mar 30 '11 at 14:55
2

As others have noted, you'd need to change the parent's properties to protected. However, the other way is by implementing a get method for your parent class, which allows you access to the property, or implementing a set method if you want the ability to over-ride it.

So, in your parent class, you'd declare:

protected function setProp1( $val ) {
  $this->prop_1 = $val;
}

protected function getProp1() {
  return $this->prop_1;
}

Then, in your child class, you can access $this->setProp1("someval"); and $val = $this->getProp1(), respectively.

Craig Sefton
  • 903
  • 11
  • 20
0

There is a simple trick you an use with lambdas, which I found here: https://www.reddit.com/r/PHP/comments/32x01v/access_private_properties_and_methods_in_php_7/

basically you use a lambda and bind it to the instance and then you can access it's private methods and properties

Info on the lambda call: https://www.php.net/manual/en/closure.call.php

AntonioCS
  • 8,335
  • 18
  • 63
  • 92