PHP Accessing Parent Class Variable - php

class A {
private $aa;
protected $bb = 'parent bb';
function __construct($arg) {
//do something..
}
private function parentmethod($arg2) {
//do something..
}
}
class B extends A {
function __construct($arg) {
parent::__construct($arg);
}
function childfunction() {
echo parent::$bb; //Fatal error: Undefined class constant 'bb'
}
}
$test = new B($some);
$test->childfunction();
Question:
How do I display parent variable in child?
expected result will echo 'parent bb'

echo $this->bb;
The variable is inherited and is not private, so it is a part of the current object.
Here is additional information in response to your request for more information about using parent:::
Use parent:: when you want add extra functionality to a method from the parent class. For example, imagine an Airplane class:
class Airplane {
private $pilot;
public function __construct( $pilot ) {
$this->pilot = $pilot;
}
}
Now suppose we want to create a new type of Airplane that also has a navigator. You can extend the __construct() method to add the new functionality, but still make use of the functionality offered by the parent:
class Bomber extends Airplane {
private $navigator;
public function __construct( $pilot, $navigator ) {
$this->navigator = $navigator;
parent::__construct( $pilot ); // Assigns $pilot to $this->pilot
}
}
In this way, you can follow the DRY principle of development but still provide all of the functionality you desire.

Just echo it since it's inherited
echo $this->bb;

With parent::$bb; you try to retrieve the static constant defined with the value of $bb.
Instead, do:
echo $this->bb;
Note: you don't need to call parent::_construct if B is the only class that calls it. Simply don't declare __construct in B class.

class A {
private $aa;
protected $bb = 'parent bb';
function __construct($arg) {
//do something..
}
private function parentmethod($arg2) {
//do something..
}
}
class B extends A {
function __construct($arg) {
parent::__construct($arg);
}
function childfunction() {
echo parent::$this->bb; //works by M
}
}
$test = new B($some);
$test->childfunction();`

$bb has now become the member of class B after extending class A.
So you access $bb like it's an attribute of class B.
class A {
private $aa;
protected $bb = 'parent bb';
function __construct($arg) {
//do something..
}
private function parentmethod($arg2) {
//do something..
}
}
class B extends A {
function __construct($arg) {
parent::__construct($arg);
}
function childfunction() {
echo $this->bb;
}
}
$test = new B($some);
$test->childfunction();

all the properties and methods of the parent class is inherited in the child class so theoretically you can access them in the child class but beware using the protected keyword in your class because it throws a fatal error when used in the child class.
as mentioned in php.net
The visibility of a property or method
can be defined by prefixing the
declaration with the keywords public,
protected or private. Class members
declared public can be accessed
everywhere. Members declared protected
can be accessed only within the class
itself and by inherited and parent
classes. Members declared as private
may only be accessed by the class that
defines the member.

PHP Accessing Parent Class Protected Variable & Methods
class A {
protected $bb = 'parent bb';
protected function sayHello(){
echo 'Say Hello';
}
}
class B extends A {
public function childfunction() {
echo $this->bb.'<br>';
echo $this->sayHello();
}
}
$test = new B();
$test->childfunction();

Through parent class contructor you can pass data to parent class from child class. Have a look below example for better understanding
<?php
class Student
{
public $name;
function __construct($name){
$this->name = $name;
}
}
class Test extends Student
{
public $age;
function __construct($name,$age){
$this->age = $age;
parent::__construct($name);
}
}
$obj = new Test("sajib khan" ,21);
echo $obj->name;
echo $obj->age;
?>

class A {
private $points = 100;
public function getPoints() {
return $this->points;
}
}
class B extends A {
protected $points = 70;
public function getPoints() {
return parent::getPoints();
}
}
$element = new B();
echo $element->getPoints();
change the visibility private or protected for test

Related

PHP: Accessing protected var from child class

I'm learning PHP and I'm stuck i the following code:
<?php
class dogtag {
protected $Words;
}
class dog {
protected $Name;
protected $DogTag;
protected function bark() {
print "Woof!\n";
}
}
class poodle extends dog {
public function bark() {
print "Yip!\n";
}
}
$poppy = new poodle;
$poppy->Name = "Poppy";
$poppy->DogTag = new dogtag;
$poppy->DogTag->Words = "My name is
Poppy. If you find me, please call 555-1234";
var_dump($poppy);
?>
This is what I got:
PHP Fatal error: Uncaught Error: Cannot access protected property poodle::$Name
This looks strange to me as I should access protected vars and functions from child classes.
Could please someone explain where I'm wrong?
Many thanks.
Protected variables can indeed be accessed from the child class. However you aren't accessing your variable from inside the child class.
If you make the variables public you can access them from outside the class.
Documentation: http://php.net/manual/en/language.oop5.visibility.php
Example:
Class Dog {
private $privateProperty = "private"; //I can only be access from inside the Dog class
protected $protectedProperty = "protected"; //I can be accessed from inside the dog class and all child classes
public $publicProperty = "public"; //I can be accessed from everywhere.
}
Class Poodle extends Dog {
public function getProtectedProperty(){
return $this->protectedProperty; //This is ok because it's inside the Poodle (child class);
}
}
$poodle = new Poodle;
echo $poodle->publicProperty; //This is ok because it's public
echo $poodle->getProtectedProperty(); //This is ok because it calls a public method.
You can't access the property 'Words', you need to make it public
you could add magic methods to your class - that would allow you to access and manipulate the private properties from outside the class.
class foo{
private $bah;
public function __construct(){
$this->bah='hello world';
}
public function __get( $name ){
return $this->$name;
}
public function __set( $name,$value ){
$this->$name=$value;
}
public function __isset( $name ){
return isset( $this->$name );
}
public function __unset( $name ){
unset( $this->$name );
}
}
$foo=new foo;
echo $foo->bah;
$foo->bah='banana';
echo $foo->bah;

override a static variable

I have two classes (Model and User) but I have a problem so I have tried to explain it in a simple example :
class person
{
protected static $todo ="nothing";
public function __construct(){}
public function get_what_todo()
{
echo self::$todo;
}
}
class student extends person
{
protected static $todo ="studing";
}
$s = new student();
$s->get_what_todo(); // this will show the word (nothing)
//but I want to show the word (studing)
Please give me a solution but without writing any function in the student class I only want to make declarations there :) and thank you :)
The principle is called "late static binding", and was introduced in PHP 5.3.0; with the self keyword to access the property defined in the calling class within the inheritance tree, or static to access the property defined in the child class within that inheritance tree.
class person
{
protected static $todo ="nothing";
public function __construct(){}
public function get_what_todo()
{
echo static::$todo; // change self:: to static::
}
}
class student extends person
{
protected static $todo ="studying";
}
class teacher extends person
{
protected static $todo ="marking";
}
class guest extends person
{
}
$s = new student();
$s->get_what_todo(); // this will show the "studying" from the instantiated child class
$t = new teacher();
$t->get_what_todo(); // this will show the "marking" from the instantiated child class
$g = new guest();
$g->get_what_todo(); // this will show the "nothing" from the parent class,
// because $todo is not overriden in the child class
The reliable way to override a static variable is to do it by redeclaring it. Some people may suggest modifying it in the construct method, but I don't think that's reliable.
It won't reflect the changes until the class is constructed at least once. And of course, in class methods, don't forget to call the static variable using "static::" instead of "self::" when you want to always access the overridden variable.
Here's an example of what I mean:
The class Foo is the base class, the class Bar is changing the variable inside its constructor, and the class Baz is overriding the variable in its declaration.
class Foo
{
public static $a = "base";
}
class Bar extends Foo
{
function __construct()
{
self::$a = "overridden";
}
}
class Baz extends Foo
{
public static $a = "overridden";
}
echo 'Foo: ' . Foo::$a . '<br>';
echo 'Bar: ' . Bar::$a . '<br>';
echo 'Baz: ' . Baz::$a . '<br>';
new Bar();
echo 'Bar after instantiation: ' . Bar::$a;
This is the output from phptester.net
Foo: base
Bar: base
Baz: overridden
Bar after instantiation: overridden
As you can see, Bar's way of changing the variable isn't taking effect until after the constructor is called at least once.
EDIT: However, there is another way to edit a variable permanently and reliably: do it after the class declaration. This is especially handy if you only need to modify a variable and not completely override it, like for example an array. It feels a bit dirty, but in theory should work everytime.
class Foo
{
public static $a = [
'a' => 'a'
];
}
class Bar extends Foo
{
public static $a;
}
Bar::$a = Foo::$a;
Bar::$a['b'] = 'b';
echo 'Foo: ' . print_r(Foo::$a, true) . '<br>';
echo 'Bar: ' . print_r(Bar::$a, true) . '<br>';
This is the output from phptester.net
Foo: Array ( [a] => a )
Bar: Array ( [a] => a [b] => b )
EDIT 2: This last method also gets picked up by ReflectionClass::getStaticPropertyValue in my tests.
you can try set variable in construction
class person
{
protected static $todo = null;
public function __construct(){
self::$todo = "nothing";
}
public function get_what_todo()
{
echo self::$todo;
}
}
class student extends person
{
public function __construct() {
self::$todo = "student";
}
}
$s = new student();
$s->get_what_todo();
you can try set parent variable in construction
class person
{
protected static $todo = null;
public function __construct(){
self::$todo = "nothing";
}
public function get_what_todo()
{
echo self::$todo;
}
}
class student extends person
{
public function __construct() {
parent::$todo = "student";
}
}
$s = new student();
$s->get_what_todo();

How to make the inherited class run a method from same class in PHP

Whats wrong with me OOP here.
I want to inherit from Class A
The return_output method will do something common so I don't want to write that in the inherited classes.
However when I do B->return_output() I want it to run the do_something method in Class B, but I see that it always runs the method from Class A.
Should I replace $this with something else?
class A {
private function do_something() {
// do something
}
public function return_output() {
$op = $this->do_something();
// add some wrappers to $op
return $op;
}
}
class B extends A {
private function do_something() {
// do something different
}
}
var newClass = new B;
echo B->return_output();
use protected and not private since you are running it inside of scope a and scope b can't access private scope a:
class A {
protected function do_something() {
echo('ado_something');
}
public function return_output() {
$op = $this->do_something();
// add some wrappers to $op
return $op;
}
}
class B extends A {
protected function do_something() {
echo('bdo_something');
}
}
$newClass = new B;
echo $newClass->return_output();

Access private properties in a class hierarchy from a common base function

I want to define a method once in a base class and call it in successive constructors in a class hierarchy. Each time is it called I want it to operate on the properties of the class from which it is called.
For example, A is the base class and the method is defined here. B inherits from A, and C inherits from B.
When I instantiate the concrete class C the constructor will call the base class method, and I want it to operate on the properties of C. (This will be a private array which I will populate when I initialise it).
The constructor of C then calls parent::__construct. When the B constructor calls the base class method, the method should operate on the properties of B. Before the B constructor is complete it will call parent::_construct, and the A constructor will operate on the properties of A.
I was looking into LSB, but it won't work correctly because parent::__construct is a forwarding call. I tried using the result of get_parent_class() in place of parent::, but my calls to static::propertyName error out because propertyName is not a constant.
How can I do this?
EDIT: Here's a code example. The code below outputs "P Q P Q P Q". I want it to output "P Q R S T U".
class A {
private $property = array('P','Q');
function __construct() {
$this->myMethod();
}
public function myMethod() {
foreach ($this->property as $value) {
echo $value . " ";
}
}
}
class B extends A {
private $property = array('R','S');
function __construct()
{
parent::__construct();
$this->myMethod();
}
}
class C extends B {
private $property = array('T','U');
function __construct()
{
parent::__construct();
$this->myMethod();
}
}
$c = new C();
As far as I know it is not possible. In case of private the variable is not available to method and in case of public/protected its overwritten.
You can get your desired result by passing
$this->property
in each myMethod call like this -
$this->myMethod($this->property)
and changing your myMethod definition accordingly.
If I got you right, this is your example:
class A {
public function __construct() {
}
public function someMethod($arg) {
$someProperty = $arg;
}
}
class B extends A {
public function __construct() {
parent::__construct();
}
}
class C extends B {
private $someProperty;
public function __construct() {
parent::__construct();
}
}
Everything works as you would expect. There is only one problem; class A has no property someProperty. If you want to use it in class A, you have to define it there. If you want to use it in subclasses, you have to make it protected. Your class A has therefore to look like this:
class A {
protected $someProperty;
public function __construct() {
}
public function someMethod($arg) {
$this->someProperty = $arg;
}
}
Now you can use it in class B and C, and class A can use the property with someMethod:
$instance = new C();
$instance->someMethod("test");
Because your example has $property defined as private and you never override myMethod, when an object of type C or B is instantiated, it runs class A's constructor, which calls myMethod() from class A where the value of $property is array('P', 'Q');.
If you want it to print 'P Q R S T U' you'll have to override myMethod() and call it from each individual class' __construct() method, OR declare $property to be protected so that the child classes can overwrite its value.
Something like this:
class A {
private $property = array('P','Q');
function __construct() {
$this->myMethod();
}
public function myMethod() {
foreach ($this->property as $value) {
echo $value . " ";
}
}
}
class B extends A {
private $property = array('R','S');
function __construct()
{
parent::__construct();
$this->myMethod();
}
public function myMethod() {
foreach ($this->property as $value) {
echo $value . " ";
}
}
}
class C extends B {
private $property = array('T','U');
function __construct()
{
parent::__construct();
$this->myMethod();
}
public function myMethod() {
foreach ($this->property as $value) {
echo $value . " ";
}
}
}
$c = new C();
OR THIS:
class A {
protected $property = array('P','Q');
function __construct() {
$this->myMethod();
}
public function myMethod() {
foreach ($this->property as $value) {
echo $value . " ";
}
}
}
class B extends A {
protected $property = array('R','S');
function __construct()
{
parent::__construct();
$this->myMethod();
}
}
class C extends B {
protected $property = array('T','U');
function __construct()
{
parent::__construct();
$this->myMethod();
}
}
$c = new C();
proptery cannot be overloaded in child classes. Once you have a C, it does not have the private properties of A anymore. It has no way to access them (outside of reflection). The only way you would be able to do this would be to pass the properties to someMethod in a chain, but this requires access to the desired property.
Using protected would not work either because then the children would just override the parent property.
The solution to this is not have have C be an a (is-a) but have C have the properties of an A (has-a .. composition). This would require some rework of your hierarchy, though, and your calls would have to be more explicit. Something like
class C {
private $b;
private $properties = array('T', 'U');
public function __construct(B $b) {
$this->b = $b;
}
public function someMethod() {
$this->b->someMethod($properties);
}
}
class B {
private $properties = array('R', 'S');
private $a;
public function __construct(A $a) {
$this->a = $a;
}
public function someMethod($properties) {
$this->a->someMethod(array_merge($this->properties, $properties));
}
}
class A {
private $properties = array('P', 'Q');
public function someMethod($properties) {
//your implementation plus an array_merge
}
}
This obviously increases verbosity in your definitions, which is bad. You may want to reconsider why you have to do some things the way you are doing them. You may be able to get around this with traits (assuming you have PHP 5.4)

Help with static::$value

I have been see this come up alot i think it has todo with late static binding but whats the point of doing it this way.
class {
public static $name = array();
function something() {
static::$name;
}
}
over
class {
public static $name = array();
function something() {
self::$name;
}
}
self::$name in the parent class will always refer to the parent class' property whereas static::$name in the parent class will refer to the property of the runtime class.
For example
class A
{
protected static $foo = 'foo';
public static function getSelfFoo()
{
return self::$foo;
}
public static function getStaticFoo()
{
return static::$foo;
}
}
class B extends A
{
protected static $foo = 'bar';
}
echo A::getSelfFoo(); // 'foo'
echo A::getStaticFoo(); // 'foo'
echo B::getSelfFoo(); // 'foo'
echo B::getStaticFoo(); // 'bar'
It matters if you create a subclass of your class. In your first example, the something function will refer to the $name variable on the subclass. In your second example it will refer to the $name variable on the base class.

Categories