如何动态创建新属性

如何从对象方法中的给定参数创建属性?

class Foo{


public function createProperty($var_name, $val){
// here how can I create a property named "$var_name"
// that takes $val as value?


}


}

我希望能够访问的财产,像:

$object = new Foo();
$object->createProperty('hello', 'Hiiiiiiiiiiiiiiii');


echo $object->hello;

还有,我是否有可能将财产设置为公有/受保护/私有?我知道在这种情况下它应该是公共的,但是我可能想添加一些魔法方法来获得受保护的属性和内容:)


我想我找到解决办法了:

  protected $user_properties = array();


public function createProperty($var_name, $val){
$this->user_properties[$var_name] = $val;


}


public function __get($name){
if(isset($this->user_properties[$name])
return $this->user_properties[$name];


}

你觉得这是个好主意吗?

98384 次浏览

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');

Property overloading is very slow. If you can, try to avoid it. Also important is to implement the other two magic methods:

__isset(); __unset();

If you don't want to find some common mistakes later on when using these object "attributes"

Here are some examples:

http://www.php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.members

EDITED after Alex comment:

You can check yourself the differences in time between both solutions (change $REPEAT_PLEASE)

<?php


$REPEAT_PLEASE=500000;


class a {}


$time = time();


$a = new a();
for($i=0;$i<$REPEAT_PLEASE;$i++)
{
$a->data = 'hi';
$a->data = 'bye'.$a->data;
}


echo '"NORMAL" TIME: '.(time()-$time)."\n";


class b
{
function __set($name,$value)
{
$this->d[$name] = $value;
}


function __get($name)
{
return $this->d[$name];
}
}


$time=time();


$a = new b();
for($i=0;$i<$REPEAT_PLEASE;$i++)
{
$a->data = 'hi';
//echo $a->data;
$a->data = 'bye'.$a->data;
}


echo "TIME OVERLOADING: ".(time()-$time)."\n";

Use the syntax: $object->{$property} where $property is a string variable and $object can be this if it is inside the class or any instance object

Live example: http://sandbox.onlinephpfunctions.com/code/108f0ca2bef5cf4af8225d6a6ff11dfd0741757f

 class Test{
public function createProperty($propertyName, $propertyValue){
$this->{$propertyName} = $propertyValue;
}
}


$test = new Test();
$test->createProperty('property1', '50');
echo $test->property1;

Result: 50

The following example is for those who do not want to declare an entire class.

$test = (object) [];


$prop = 'hello';


$test->{$prop} = 'Hiiiiiiiiiiiiiiii';


echo $test->hello; // prints Hiiiiiiiiiiiiiiii