Подтвердить что ты не робот

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

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

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

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

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

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

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

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

4b9b3361

Ответ 1

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

Ответ 2

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

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

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

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

Ответ 3

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

$data = json_decode($json, TRUE);

Ответ 4

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

Ответ 5

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

Ответ 6

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

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

echo $foo->bar; //12345

Ответ 7

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