如何在PHP> = 5.3严格模式下将属性添加到对象中,而不会产生错误
这一定很简单,但我似乎无法find答案….
我有一个通用的stdClass对象$foo
没有属性。 我想添加一个新的属性$bar
到它尚未定义。 如果我这样做:
$foo = new StdClass(); $foo->bar = '1234';
PHP在严格的模式下抱怨。
什么是正确的方法(在类声明之外)添加一个属性到一个已经实例化的对象?
注:我希望解决scheme与typesstdClass的通用PHP对象一起工作。
关于这个问题的一点背景。 我正在解码一个jsonstring,这是一个json对象的数组。 json_decode()
生成一个StdClass对象的数组。 我需要操纵这些对象,并为每个对象添加一个属性。
如果你绝对必须将属性添加到对象,我相信你可以将它转换为一个数组,添加你的属性(作为一个新的数组键),然后把它作为一个对象。 唯一一次你运行stdClass
对象(我相信)是当你把一个数组作为一个对象,或者当你从头开始创build一个新的stdClass
对象的时候json_decode()
当然,当你使用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;
也作为1class轮:
$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);
你应该使用魔术方法__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...'); } } } }
PS:我没有testing我的代码,只是一般的想法…
我不知道是否它的新版本的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();
这是结果。 保存方法实际上获取新的属性
Person Object ( [name] => Ganga [age] => 23 )
我总是用这种方式:
$foo = (object)null; //create an empty object $foo->bar = "12345"; echo $foo->bar; //12345
是的,可以dynamic添加属性到一个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中发送一个DUMMY PROPERTY,你将填入PHP。