如何在PHP中向对象添加属性>;=5.3严格模式,不产生错误


How to add property to object in PHP >= 5.3 strict mode without generating error

这必须很简单,但我似乎找不到答案。。。。

我有一个没有属性的通用stdClass对象$foo。我想添加一个尚未定义的新属性$bar。如果我这样做:

$foo = new StdClass();
$foo->bar = '1234';

PHP在严格模式下会抱怨。

向已经实例化的对象添加属性的正确方法是什么(在类声明之外)?

注意:我希望该解决方案能够使用stdClass类型的通用PHP对象。

关于这个问题的一些背景。我正在解码一个json字符串,它是json对象的数组。json_decode()生成StdClass对象的数组。我需要操作这些对象,并为每个对象添加一个属性。

如果您必须将属性添加到对象中,我相信您可以将其强制转换为数组,添加您的属性(作为新的数组键),然后将其强制重新转换为对象。唯一一次遇到stdClass对象(我相信)是当您将数组强制转换为对象时,或者当您从头开始创建新的stdClass对象时(当然还有当您json_decode()对象时——我忘了,真傻!)。

代替:

$foo = new StdClass();
$foo->bar = '1234';

你会做:

$foo = array('bar' => '1234');
$foo = (object)$foo;

或者,如果您已经有一个现有的stdClass对象:

$foo = (array)$foo;
$foo['bar'] = '1234';
$foo = (object)$foo;

也可作为1行:

$foo = (object) array_merge( (array)$foo, array( 'bar' => '1234' ) );

这样做:

$foo = new stdClass();
$foo->{"bar"} = '1234';

现在试试:

echo $foo->bar; // should display 1234

如果要编辑解码的JSON,请尝试将其作为关联数组,而不是对象数组。

$data = json_decode($json, TRUE);

这是另一种方式:

$foo = (object)null; //create an empty object
$foo->bar = "12345";
echo $foo->bar; //12345

您应该使用魔术方法__Set和__get。简单示例:

class Foo
{
    //This array stores your properties
private $content = array();
public function __set($key, $value)
{
            //Perform data validation here before inserting data
    $this->content[$key] = $value;
    return $this;
}
public function __get($value)
{       //You might want to check that the data exists here
    return $this->$content[$value];
}
}

当然,不要这样使用这个例子:根本没有安全性:)

编辑:看到你的评论,这里可能有一个基于反思和装饰的替代方案:

 class Foo
 {
private $content = array();
private $stdInstance;
public function __construct($stdInstance)
{
    $this->stdInstance = $stdInstance;
}
public function __set($key, $value)
{
    //Reflection for the stdClass object
    $ref = new ReflectionClass($this->stdInstance);
    //Fetch the props of the object
    $props = $ref->getProperties();
    if (in_array($key, $props)) {
        $this->stdInstance->$key = $value;
    } else {
        $this->content[$key] = $value;
    }
    return $this;
}
public function __get($value)
{
    //Search first your array as it is faster than using reflection
    if (array_key_exists($value, $this->content))
    {
        return $this->content[$value];
    } else {
        $ref = new ReflectionClass($this->stdInstance);
        //Fetch the props of the object
        $props = $ref->getProperties();
        if (in_array($value, $props)) {
        return $this->stdInstance->$value;
    } else {
        throw new 'Exception('No prop in here...');
    }
}
 }
}

附言:我没有测试我的代码,只是大致的想法。。。

我不知道这是否是php的新版本,但这是有效的。我使用的是php 5.6

    <?php
    class Person
    {
       public $name;
       public function save()
       {
          print_r($this);
       }
    }
   $p = new Person;
   $p->name = "Ganga";
   $p->age = 23;
   $p->save();

这就是结果。save方法实际上获得了新属性

    Person Object
    (
       [name] => Ganga
       [age] => 23
    )

是的,可以动态地向PHP对象添加属性。

当从javascript接收到部分对象时,这很有用。

JAVASCRIPT端:

var myObject = { name = "myName" };
$.ajax({ type: "POST", url: "index.php",
    data: myObject, dataType: "json",
    contentType: "application/json;charset=utf-8"
}).success(function(datareceived){
    if(datareceived.id >= 0 ) { /* the id property has dynamically added on server side via PHP */ }
});

PHP端:

$requestString = file_get_contents('php://input');
$myObject = json_decode($requestString); // same object as was sent in the ajax call
$myObject->id = 30; // This will dynamicaly add the id property to the myObject object

或者只是从javascript发送了一个伪属性,你将用PHP填充它。