I'm not sure if this is even possible but here goes. I want to set the value of a protected variable from within a child class and then access that value from the parent class. This is what I have tried:
class A {
protected $a;
public function __construct() {
new B;
echo "Parent Value: {$this->a}";
}
protected function setter($value) {
$this->a = $value;
}
}
class B extends A {
public function __construct() {
$this->setter('set value');
echo "Child Value: {$this->a}<br />";
}
}
new A;
I'm expecting the output for the above code to be:
Child Value: set value
Parent Value: set value
However I get the following instead:
Child Value: set value
Parent Value:
Is it possible to set the value of a protected variable from within a child class and then access that value in the parent class? If not how would I accomplish this?
You can set the value and access it from the child class without any problems - you are actually doing that when you generate your B-class object in the A-class constructor - but the problem with your code is that you are generating a parent object and in the constructor of that parent object you generate a new object of the child class.
So what is happening is:
You generate an A object, the constructor of the A class runs;
In the constructor you generate a B object. This is a new object, unrelated to your current A object;
The constructor of the B object you set the value and echo it (basically answering your own question), the first line of your output is as expected;
Continuing in the constructor of the A object, you discard the generated B-class object and echo the value of $this->a but that value is not set for that object, so you get nothing.
I am kind of confused why you would want to construct a child object in the constructor of the parent. Normally I would construct a B object and in the constructor of that object, first call the parent constructor before doing B-specific stuff.
Related
I need some help. This code doesn't mean to do anything I was just trying to learn how these inheriting functions work.
So both parents and child class have $wheels variable and set to private (It doesn't make sense but I was just playing around with the code).
A method is used to print the number of wheels of the Instance. This method is not overridden in the child class. Parent and child objects were created and wheel_details() were invoked using each object.
However, when invoked using the child object, the method doesn't use the child object's private var. Instead it prints the parent object's var.
How and why do you think it accesses the parent class's private var instead of its own private var.
Appreciate an insight on this. TIA
class Bicycle {
private $wheels = 2;
public function wheel_details(){
return " It has {$this->wheels} wheels. Invoked by ". get_class($this) ;
}
}
class Unicycle extends Bicycle {
private $wheels = 1;
}
$b1 = new Bicycle;
$b2 = new Unicycle;
echo "Bicycle1 wheels ". $b1->wheel_details(). " <br />";
echo "Bicycle2 wheels ". $b2->wheel_details(). " <br />";
/*Output
=======
Bicycle1 wheels It has 2 wheels. Invoked by Bicycle
Bicycle2 wheels It has 2 wheels. Invoked by Unicycle
*/
This is by design:
Members declared as private may only be accessed by the class that defines the member.
If you want to override the value from a child class, use protected instead.
Say there are three member variable $a, $b,$c, where $a & $b are from base class and & c is in child class ... values are assigning to $a,$b,$c from child class..Thus when outputting the values in this format $a.$b.$c but the output is coming in format $c.$a.$b....the child class variable is coming first.
You have a method that should be returning a value but is instead echoing it:
function getname()
{
echo $this->pub_name;
}
As such you're getting an unexpected result when using it as part of another echo statement.
Change:
echo $this->pub_name;
To:
return $this->pub_name;
I'm creating global setters and getters for my parent class since I don't want to create them for each child class variable (but I will occasionally overwrite the parent global setter / getter).
I'm using __call with it and I'm parsing the method name like this:
if (strtolower(substr($method, 0, 3)) == "set") {
$variable = strtolower(substr($method, 3));
}
The question is how can I check if the $variable is set for the child class (the one that is extending the main one);
If I do:
if ($this->$variable)
I suppose it first check if it exists on the child class and then it checks if it exists on the main class. I want it only to check the child class, is this possible to do?
I know there's parent:: but is there an equivalent for child?
EDIT:
People are not understanding what I'm asking.
I know how to check if the property exists. What I want to know is how to check if the property exists for the CHILD class, not for the MAIN class.
(class CHILD extends MAIN)
In common case there's isset() function, but is will not fit this case. Use property_exists() instead:
class Foo
{
public $pub = null;
}
$obj = new Foo();
var_dump(isset($obj->pub), property_exists('Foo', 'pub')); //false, true
-that's because if proprty exists, but is null, isset() will return false - and you'll not be able to differ the case, when it does not exist.
If it's about dynamic properties - then you should pass object and not class name to property_exists() since property may absent in class and then dynamically added to object.
Now, if we're saying about which class is declaring property, you can use Reflection in PHP, like this:
class Foo
{
public $pub = null;
}
class Bar extends Foo
{
}
$obj = new Bar();
$ref = new ReflectionObject($obj);
var_dump($ref->getProperty('pub')->getDeclaringClass()->getName() == 'Bar');//false
var_dump($ref->getProperty('pub')->getDeclaringClass()->getName() == 'Foo');//true
Why don't you make use of isset ??
if (isset($this->$variable))
This works for me:
if(property_exists($get_class($this),$variable)){}
How to combine two variables to obtain / create new variable?
public $show_diary = 'my';
private my_diary(){
return 1;
}
public view_diary(){
return ${"this->"}.$this->show_diary.{"_diary()"}; // 1
return $this->.{"$this->show_diary"}._diary() // 2
}
both return nothing.
Your class should be like following:
class Test
{
public $show_diary;
function __construct()
{
$this->show_diary = "my";
}
private function my_diary(){
return 707;
}
public function view_diary(){
echo $this->{$this->show_diary."_diary"}(); // 707
}
}
It almost looks from your question like you are asking about how to turn simple variables into objects and then how to have one object contain another one. I could be way off, but I hope not:
So, first off, what is the differnce between an object and a simple variable? An object is really a collection of (generally) at least one property, which is sort of like a variable within it, and very often functions which do things to the properties of the object. Basically an object is like a complex variable.
In PHP, we need to first declare the strucutre of the object, this is done via a class statement, where we basicaly put the skeleton of what the object will be into place. This is done by the class statement. However, at this point, it hasn't actually been created, it is just like a plan for it when it is created later.
The creation is done via a command like:
$someVariable= new diary();
This executes so create a new variable, and lays it out with the structure, properties and functions defined in the class statement.
From then on, you can access various properties or call functions within it.
class show_diary
{
public $owner;
public function __construct()
{
$this->owner='My';
}
}
class view_diary
{
public $owner;
public $foo;
public function __construct()
{
$this->foo='bar';
$this->owner=new show_diary();
}
}
$diary= new view_diary();
print_r($diary);
The code gives us two classes. One of the classes has an instance of the other class within it.
I have used constructors, which are a special type of function that is executed each time we create a new instance of a class - basically each time we declare a variable of that type, the __construct function is called.
When the $diary= new view_diary(); code is called, it creates an instance of the view_diary class, and in doing so, the first thing it does is assigns it's own foo property to have the value 'bar' in it. Then, it sets it's owner property to be an instance of show_diary which in turn then kicks off the __construct function within the new instance. That in turn assigns the owner property of the child item to have the value 'My'.
If you want to access single properties of the object, you can do so by the following syntax:
echo $diary->foo;
To access a property of an object inside the object, you simply add more arrows:
echo $diary->owner->owner;
Like this?
$diary = $this->show_diary . '_diary';
return $this->$diary();
I am new to php and currently I am reading Wrox Professional PHP 5.
Can anyone explain me the following code ?
<? php
abstract class PropertyObject
{
//Stores name/value pairs that hook properties to database field names
protected $propertyTable=array();
//List of properties that have been modified.
protected $changedProperties=array();
//Actual data from the database.
protected $data;
//Any validation errors that might have occured.
protected $errors=array();
public function __construct($arData)
{
$this->data=$arData;
}
function __get($propertyName)
{
if(!array_key_exits($propertyName,$this->propertyTable))
{
throw new Exception("Invalid property \"$propertyName\" !");
}
if(method_exists($this,'get'.$propertyName))
{
return call_user_func(array($this,'get'.$propertyName));
}
else
{
return $this->data[$this->propertyTable[$propertyName]];
}
}
function __set($propertyName,$value)
{
if(!array_key_exits($propertyName,$this->propertyTable))
{
throw new Exception("Invalid property \"$propertyName\" !")
}
if(method_exits($this,'set'.$propertyName))
{
return call_user_func(array($this,'set'.$propertyName),$value);
}
else
{
//If the value of the property really has changed and it's not already in the changedProperties array, add it.
if($this->propertyTable[$propertyName] !=$value && !in_array($propertyName,$this->changedProperties))
{
$this->changedProperties[]=$propertyName;
}
//Now set the new value
$this->data[$this->propertyTable[$propertyName]]=$value;
}
}
}
?>
I can't understand the code inside assessor get and set methods.
The __get magic method is called when a property of the object is requested but it wasn't declared or specifically assigned (for dynamic properties). This implementation:
First tries to see if the logical property exists as an entry in the actual declared property named $propertyTable.
If it doesn't exist, it throws an exception, therefore leaving the method,
If it exists and additionaly exists a method named 'get'.$propertyName (i.e., "get" concatenated with the request property name), that method is called and its value is returned.
If it exists but there's no such method, it returns the value of the entry with key $propertyName in the declared property $propertyTable.
Given this, I think you can figure __set out. See Magic Methods in the PHP manual.
This is a really common way of setting up a DB storage class. What happens is you instantiate an object based on PropertyObject (as PropertyObject is abstract)
class MyObj extends PropertyObject {
}
$m = new MyObj();
Which inherits the __get() and __set() methods. Any time the object's data is accessed via the -> operator, the __get() and __set() methods are called, respectively.
$m->foo; #calls MyObject::__get('foo');
$m->bar = 'baz'; #calls MyObject::__set('bar','baz');
The __get() method first checks to see if the there is a key defined in the property table (which here models fields from the DB), and if one does not exist, throws an exception.
Then, get() will see if there is a function defined with the word 'get' prepended. So, assuming foo was a key in the propertyTable, __get() would see if we had defined a method getfoo, and if we had, call it for us, and return its value.
//if(method_exists($this,'get'.$propertyName))
//{
// return call_user_func(array($this,'get'.$propertyName));
//}
$m->foo; # checks if MyObj::getfoo is defined, and if so, calls it
Lastly, if there is a key foo in the propertyTable but no method named getfoo, it would simply return the value of the array position in $m->data whose key is the value of the array position in propertyTable whose key is foo
__set() is defined much the same way, but rather than returning the value stored in the data array instead checks for a prepended 'set', and checks to see if the value being set on the object is any different from the value in the data array, and if it is, adds the property name to the changedProperties array before setting the new value.