Can You Create Instance Properties Dynamically in PHP

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



Leave a reply



Submit