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


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

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

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

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

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

ПРИМЕЧАНИЕ: Я хочу, чтобы решение работало с общим PHP-объектом типа Стандартный класс.

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

 56
Author: hakre, 2012-07-23

7 answers

Если вам абсолютно необходимо добавить свойство к объекту, я полагаю, что вы могли бы привести его в виде массива, добавить свое свойство (в качестве нового ключа массива), а затем привести его обратно в качестве объекта. Единственный раз, когда вы сталкиваетесь с объектами stdClass (я полагаю), это когда вы создаете массив в качестве объекта или когда вы создаете новый объект stdClass с нуля (и, конечно, когда вы json_decode() что-то - глупо, что я забыл!).

Вместо:

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

Вы бы сделали:

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

Или если у вас уже был существующий Объект класса STD:

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

Также в качестве 1 вкладыша:

$foo = (object) array_merge( (array)$foo, array( 'bar' => '1234' ) );
 80
Author: Crontab, 2013-04-22 22:50:47

Сделайте это так:

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

Теперь попробуйте:

echo $foo->bar; // should display 1234
 51
Author: jmnerd, 2015-09-15 08:55:00

Если вы хотите отредактировать декодированный JSON, попробуйте получить его в виде ассоциативного массива вместо массива объектов.

$data = json_decode($json, TRUE);
 11
Author: Rocket Hazmat, 2012-07-23 18:57:02

Вы должны использовать магические методы __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: Я не тестировал свой код, просто общую идею...

 1
Author: Benjamin Dubois, 2012-07-23 18:58:24

Я всегда использую этот способ:

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

echo $foo->bar; //12345
 1
Author: Ragnar, 2016-08-17 18:18:40

Я не знаю, является ли это более новой версией 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
    )
 0
Author: Ganga, 2015-12-18 07:49:46

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

 -3
Author: Adrian Cumpanasu, 2014-07-19 12:07:33