I know accessing object's properties dynamically using string e.g.
$obj->{$string};
But what about objects themselves?
Like I have string
$obj = '$model->property';
How to use this?
For example in if statement, to have something like
if($model->property) but by using this string?
Tried if({$obj}), if(${$obj})... nothing works.
I don't know if it even possible, but maybe?
I've set up a small test case...
class A {
public $b = 5;
}
$test = new A();
$var = "test";
echo ${$var}->b;
I think this last line is what your after.
Update:
If you want the object and the property, then the nearest I could get is to use...
class A {
public $b = 5;
}
$test = new A();
$var = "test->b";
list($var, $property) = explode("->", $var);
echo ${$var}->$property;
Related
Today, I realised that I could use variables to access property names in a class, i.e. instead of using $object->foo I can set a string variable as $propname="foo" and then access the property with $object->$propname.
Is this method okay to use, or is it possible that I will get unexpected behaviours/errors that I haven't thought of?
Example code:
<?php
class MyClass {
public $a = "Hello world!";
public $b = "Bye bye!";
}
$obj = new MyClass();
$property = "a";
echo $obj->$property; // Hello world!
$property = "b";
echo $obj->$property; // Bye bye!
?>
As a note: I want to use this method in my code where I have classes with many properties and I whish to be able to return diff-responses between objects, like compare_properties($propertyname, $obj1, $obj2)
I've got the following class:
class Foo
{
$bar1 = 'a';
$bar2 = 'b'
public function Update($updateInfo)
{
$this->$updateInfo['property'] = $updateInfo[$updateInfo['property']];
}
}
In my code, I've created a Foo object:
$objFoo = new Foo();
Now, I want to be able to update either of the properties, without the update function knowing which. The array would look like this:
$updateInfo['bar1'] = 'newVal';
$updateInfo['property'] = 'bar1';
I remember hearing or reading that something like this is possible in PHP, but I'm currently getting the error:
Object of class could not be converted to string
Am I mistaken in thinking this can be done? Or is there a better way of doing this?
You must be using PHP 7+. This is because of a backwards incompatible change in the handling of indirect variables, properties, and methods. In PHP 5, your code works as is because it's being interpreted as
$this->{$updateInfo['property']} = $updateInfo[$updateInfo['property']];
which is your intended behavior. However, in PHP 7+ it's interpreted as
($this->$updateInfo)['property'] = $updateInfo[$updateInfo['property']];
so it gives you the error you're getting.
Make the behavior you want explicit and it will work fine in both versions:
class Foo
{
private $bar1 = 'a';
private $bar2 = 'b';
public function Update($updateInfo)
{
$this->{$updateInfo['property']} = $updateInfo[$updateInfo['property']];
}
}
$objFoo = new Foo();
$updateInfo['bar1'] = 'newVal';
$updateInfo['property'] = 'bar1';
$objFoo->Update($updateInfo);
var_dump($objFoo);
Demo
Put braces around the value being used as the property:
$this->{$updateInfo['property']} = $updateInfo[$updateInfo['property']];
I want to use variables inside class names.
For example, let's set a variable named $var to "index2".
Now I want to print index2 inside a class name like this:
controller_index2, but instead of doing it manually, I can just print the var name there like this:
controller_$var;
but I assume that's a syntax error.
How can I do this?
function __construct()
{
$this->_section = self::path();
new Controller_{$this->_section};
}
It's a hideous hack, but:
php > class foo { function x_1() { echo 'success'; } };
php > $x = new foo;
php > $one = 1;
php > $x->{"x_$one"}();
^^^^^^^^^^^^
success
Instead of trying to build a method name on-the-fly as a string, an array of methods may be more suitable. Then you just use your variables as the array's key.
Echo it as a string in double quotes.
echo "controller_{$var}";
Try this (based on your code in the OP):
function __construct()
{
$this->_section = self::path();
$controller_name = "Controller_{$this->_section}";
$controller = new $controller_name;
}
You can do this.... follow this syntax
function __construct()
{
$this->_section = self::path();
$classname = "Controller_".$this->_section;
$instance = new $classname();
}
Another way to create an object from a string definition is to use ReflectionClass
$classname = "Controller_".$this->_section;
$reflector = new ReflectionClass($classname);
and if your class name has no constructor arguments
$obj = $reflector->newInstance();
of if you need to pass arguments to the constructor you can use either
$obj = $reflector->newInstance($arg1, $arg2);
or if you have your arguments in an array
$obj = $reflector->newInstanceArgs($argArray);
try this:
$name = "controller_$var";
echo $this->$name;
just to add on the previous answers, if you're trying to declare new classes with variable names but all the construction parameters are the same and you are treating the instanced object all alike maybe you don't need different classes but just different instances of the same.
Is it possible to add to PHP objects on the fly? Say I have this code:
$foo = stdObject();
$foo->bar = 1337;
Is this valid PHP?
That's technically not valid code. Try something like:
$foo = new stdClass();
$foo->bar = 1337;
var_dump($foo);
http://php.net/manual/en/language.types.object.php
It is valid as long as you use valid class eg stdClass instead of stdObject:
$foo = new stdClass();
$foo->bar = 1337;
echo $foo->bar; // outputs 1337
You had these problems:
Using stdObject instead of stdClass
Not instantiating your object using new keyword
More Info:
http://php.net/manual/en/language.types.object.php
You're close.
$foo = stdObject();
This needs to be:
$foo = new stdClass();
Then it will work.
Yes it is. The only problem in your code is that it's missing a new before calling stdClass, and you're using stdObject, but you mean stdClass
<?php
class A {
public $foo = 1;
}
$a = new A;
$b = $a; // $a and $b are copies of the same identifier
// ($a) = ($b) = <id>
$b->newProp = 2;
echo $a->newProp."\n";
is there a way to create an array containing all the public vars from a class without having to add them manually in PHP5?
I am looking for the quickest way to sequentially set a group of vars in a class
Have a look at:
get_class_vars
With this you get the public vars in an array.
get_class_vars() is the obvious one - see get_class_vars docs on the PHP site.
Edit: example of setting using this function:
$foo = new Foo();
$properties = get_class_vars("Foo");
foreach ($vars as $property)
{
$foo->{$property} = "some value";
}
You could also use the Reflection API - from the PHP docs:
<?php
class Foo {
public $foo = 1;
protected $bar = 2;
private $baz = 3;
}
$foo = new Foo();
$reflect = new ReflectionClass($foo);
$props = $reflect->getProperties(ReflectionProperty::IS_PUBLIC);
foreach ($props as $prop) {
print $prop->getName() . "\n";
}
var_dump($props);
?>
...example taken straight from the PHP docs linked above but tweaked for your purpose to only retrieve public properties. You can filter on public, protected etc as required.
This returns an array of ReflectionProperty objects which contain the name and class as appropriate.
Edit: example of setting using the above $props array:
$props = $reflect->getProperties(ReflectionProperty::IS_PUBLIC);
foreach ($props as $prop)
{
$foo->{$prop->getName()} = "some value";
}
Take a look at PHP's Reflection API. You can get the properties with ReflectionClass::getProperties.
To set the properties you do something like this:
$propToSet = 'somePropName';
$obj->{$propToSet} = "newValue";
try get_class_vars($obj);