Can you create instance properties dynamically in PHP?
Sort of. There are magic methods that allow you to hook your own code up to implement class behavior at runtime:
class foo {
public function __get($name) {
return('dynamic!');
}
public function __set($name, $value) {
$this->internalData[$name] = $value;
}
}
That's an example for dynamic getter and setter methods, it allows you to execute behavior whenever an object property is accessed. For example
print(new foo()->someProperty);
would print, in this case, "dynamic!" and you could also assign a value to an arbitrarily named property in which case the __set() method is silently invoked. The __call($name, $params) method does the same for object method calls. Very useful in special cases. But most of the time, you'll get by with:
class foo {
public function __construct() {
foreach(getSomeDataArray() as $k => $value)
$this->{$k} = $value;
}
}
...because mostly, all you need is to dump the content of an array into correspondingly named class fields once, or at least at very explicit points in the execution path. So, unless you really need dynamic behavior, use that last example to fill your objects with data.
This is called overloading
http://php.net/manual/en/language.oop5.overloading.php
How to create new property dynamically
There are two methods to doing it.
One, you can directly create property dynamically from outside the class:
class Foo{
}
$foo = new Foo();
$foo->hello = 'Something';
Or if you wish to create property through your createProperty
method:
class Foo{
public function createProperty($name, $value){
$this->{$name} = $value;
}
}
$foo = new Foo();
$foo->createProperty('hello', 'something');
PHP set object properties dynamically
http://www.php.net/manual/en/reflectionproperty.setvalue.php
You can using Reflection
, I think.
<?php
function set(array $array) {
$refl = new ReflectionClass($this);
foreach ($array as $propertyToSet => $value) {
$property = $refl->getProperty($propertyToSet);
if ($property instanceof ReflectionProperty) {
$property->setValue($this, $value);
}
}
}
$a = new A();
$a->set(
array(
'a' => 'foo',
'b' => 'bar'
)
);
var_dump($a);
Outputs:
object(A)[1]
public 'a' => string 'foo' (length=3)
public 'b' => string 'bar' (length=3)
Dynamically creating instance variables in PHP classes
Yes that will indeed work. Auto-created instance variables are given public visibility.
How do you access a dynamic property in an object?
This won't work in PHP < 7.2.0 and the issue is that the string-integer array keys are actually converted to integer property names, not strings. An alternate way to get an object from an array that will work:
$var = json_decode(json_encode(array('1' => 'Object one','2' => 'Object two')));
$num = "2";
var_dump( $var->$num );
See the Demo, in PHP < 7.2.0 the (object)
cast converts to integer properties but json_decode
creates string properties.
How do I dynamically write a PHP object property name?
Update for PHP 7.0
PHP 7 introduced changes to how indirect variables and properties are handled at the parser level (see the corresponding RFC for more details). This brings actual behavior closer to expected, and means that in this case $obj->$field[0]
will produce the expected result.
In cases where the (now improved) default behavior is undesired, curly braces can still be used to override it as shown below.
Original answer
Write the access like this:
$obj->{$field}[0]
This "enclose with braces" trick is useful in PHP whenever there is ambiguity due to variable variables.
Consider the initial code $obj->$field[0]
-- does this mean "access the property whose name is given in $field[0]
", or "access the element with key 0
of the property whose name is given in $field
"? The braces allow you to be explicit.
Dynamically Create Instance Method in PHP
You are assigning the anonymous function to a property, but then try to call a method with the property name. PHP cannot automatically dereference the anonymous function from the property. The following will work
class Foo{
function __construct() {
$this->sayHi = create_function( '', 'print "hi";');
}
}
$foo = new Foo;
$fn = $foo->sayHi;
$fn(); // hi
You can utilize the magic __call
method to intercept invalid method calls to see if there is a property holding a callback/anonymous function though:
class Foo{
public function __construct()
{
$this->sayHi = create_function( '', 'print "hi";');
}
public function __call($method, $args)
{
if(property_exists($this, $method)) {
if(is_callable($this->$method)) {
return call_user_func_array($this->$method, $args);
}
}
}
}
$foo = new Foo;
$foo->sayHi(); // hi
As of PHP5.3, you can also create Lambdas with
$lambda = function() { return TRUE; };
See the PHP manual on Anonymous functions for further reference.
Dynamically create PHP object based on string
But know of no way to dynamically create a type based on a string. How does one do this?
You can do it quite easily and naturally:
$type = 'myclass';
$instance = new $type;
If your query is returning an associative array, you can assign properties using similar syntax:
// build object
$type = $row['type'];
$instance = new $type;
// remove 'type' so we don't set $instance->type = 'foo' or 'bar'
unset($row['type']);
// assign properties
foreach ($row as $property => $value) {
$instance->$property = $value;
}
dynamic class property $$value in php
You only need to use one $ when referencing an object's member variable using a string variable.
echo $this->$string;
Related Topics
Trouble Using Posix_Kill in PHP
PHP Commands Out of Sync Error
Unserialize PHP Array in JavaScript
How to Find Unused Functions in a PHP Project
Get Custom Product Attributes in Woocommerce
File_Get_Contents Returns 403 Forbidden
Int((0.1+0.7)*10) = 7 in Several Languages. How to Prevent This
Why Are "Echo" Short Tags Permanently Enabled as of PHP 5.4
Prevent Innodb Auto Increment on Duplicate Key
My Magento Extension Install Script Will Not Run
PHP Failed to Open Stream: Is a Directory
MySQL Statement Takes More Than Minute to Execute
Call to a Member Function Fetch() on Boolean
Getting Http Code in PHP Using Curl
How to Install PHP-Curl in Ubuntu 16.04
Can't Send Email to Addresses at My Own Domain
PHP Create a Multidimensional Array from an Array with Relational Data