Как добавить свойство к объекту в PHP> = 5.3 строгий режим без генерации ошибки

Это должно быть просто, но я не могу найти ответ ….

У меня есть общий объект stdClass $foo без свойств. Я хочу добавить к нему новое свойство $bar которое еще не определено. Если я это сделаю:

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

PHP в строгом режиме жалуется.

Каким образом (вне объявления класса) можно добавить свойство к уже созданному объекту?

ПРИМЕЧАНИЕ. Я хочу, чтобы решение работало с универсальным объектом PHP типа stdClass.

Немного об этом. Я декодирую строку json, которая представляет собой массив объектов json. json_decode() генерирует массив объекта StdClass. Мне нужно управлять этими объектами и добавлять свойство к каждому из них.

Если вам абсолютно необходимо добавить свойство к объекту, я считаю, что вы можете использовать его как массив, добавить свое свойство (как новый массив), а затем отбросить его как объект. Единственный раз, когда вы запускаете объекты 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); 

вы должны использовать магические методы __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]; } } 

Конечно, не используйте этот пример как это: никакой безопасности вообще 🙂

EDIT: видел ваши комментарии, здесь может быть альтернатива, основанная на отражении и декораторе:

  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: Я не тестировал свой код, просто общая идея …

Я не знаю, является ли его более новая версия 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 

Да, возможно динамически добавлять свойства к объекту 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 

ИЛИ ТОЛЬКО ОТПРАВИТЬ DUMMY PROPERTY из javascript, который вы заполните PHP.