Как добавить свойство к объекту в PHP>=5.3 строгий режим без создания ошибки
Это должно быть просто, но я, кажется, не могу найти ответ....
У меня есть универсальный объект класса STD $foo
без свойств. Я хочу добавить к нему новое свойство $bar
, которое еще не определено. Если я сделаю это:
$foo = new StdClass();
$foo->bar = '1234';
PHP в строгом режиме жалуется.
Как правильно (вне объявления класса) добавить свойство к уже созданному объекту?
ПРИМЕЧАНИЕ: Я хочу, чтобы решение работало с общим PHP-объектом типа Стандартный класс.
Небольшая справочная информация по этому вопросу. Я декодирую строку json, которая представляет собой массив объектов json. json_decode()
генерирует массив объектов класса STD. Мне нужно манипулировать этими объектами и добавлять свойство к каждому из них.
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' ) );
Сделайте это так:
$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: Я не тестировал свой код, просто общую идею...
Я всегда использую этот способ:
$foo = (object)null; //create an empty object
$foo->bar = "12345";
echo $foo->bar; //12345
Я не знаю, является ли это более новой версией 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
)
Да, возможно динамическое добавление свойств к объекту 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.