To musi być proste, ale nie mogę znaleźć odpowiedzi ....
Mam ogólny obiekt stdClass $foo
bez właściwości. Chcę dodać do niego nową właściwość $bar
, która nie jest jeszcze zdefiniowana. Jeśli to zrobię:
$foo = new StdClass();
$foo->bar = '1234';
PHP w trybie ścisłym narzeka.
Jaki jest właściwy sposób (poza deklaracją klasy), aby dodać właściwość do już utworzonego obiektu?
UWAGA: Chcę, aby rozwiązanie działało z ogólnym obiektem PHP typu stdClass.
Trochę tła w tej kwestii. Dekoduję ciąg JSON, który jest tablicą obiektów JSON. json_decode()
generuje tablicę obiektu StdClass. Muszę manipulować tymi obiektami i do każdego z nich dodać właściwość.
TRUE
jako drugi parametr dojson_decode
. Otrzymasz tablicę asocjacyjną zamiast tablicy obiektów.Odpowiedzi:
Jeśli absolutnie musisz dodać właściwość do obiektu, uważam, że możesz rzucić ją jako tablicę, dodać swoją właściwość (jako nowy klucz tablicy), a następnie odrzucić ją z powrotem jako obiekt. Jedyny przypadek, kiedy napotkasz
stdClass
obiekty (jak sądzę), to rzutowanie tablicy jako obiektu lub tworzenie nowegostdClass
obiektu od zera (i oczywiście, gdyjson_decode()
coś - głupi, że zapomniałem!).Zamiast:
$foo = new StdClass(); $foo->bar = '1234';
Zrobiłbyś:
$foo = array('bar' => '1234'); $foo = (object)$foo;
Lub jeśli masz już istniejący obiekt stdClass:
$foo = (array)$foo; $foo['bar'] = '1234'; $foo = (object)$foo;
Również jako 1 wkładka:
$foo = (object) array_merge( (array)$foo, array( 'bar' => '1234' ) );
źródło
error_reporting(E_STRICT);
naPHP 5.3.15-1~dotdeb.0 with Suhosin-Patch
, ja nie otrzymuję żadnych błędów lub powiadomień, gdy próbuje ustawić właściwość nieistniejącego na obiekcie stdClass. Jakiej wersji PHP używasz?Zrób to tak:
$foo = new stdClass(); $foo->{"bar"} = '1234';
Spróbuj teraz:
echo $foo->bar; // should display 1234
źródło
Jeśli chcesz edytować zdekodowany JSON, spróbuj uzyskać go jako tablicę asocjacyjną zamiast tablicy obiektów.
$data = json_decode($json, TRUE);
źródło
Zawsze używam w ten sposób:
$foo = (object)null; //create an empty object $foo->bar = "12345"; echo $foo->bar; //12345
źródło
powinieneś użyć magicznych metod __Set i __get. Prosty przykład:
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]; } }
Oczywiście nie używaj tego przykładu w ten sposób: brak zabezpieczeń :)
EDYCJA: widziałem twoje komentarze, tutaj może być alternatywa oparta na refleksji i dekoratorze:
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: Nie testowałem swojego kodu, tylko ogólny pomysł ...
źródło
Nie wiem, czy to nowsza wersja php, ale to działa. Używam 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();
To jest wynik. Metoda save faktycznie pobiera nową właściwość
Person Object ( [name] => Ganga [age] => 23 )
źródło
Tak, możliwe jest dynamiczne dodawanie właściwości do obiektu PHP.
Jest to przydatne, gdy część obiektu jest otrzymywana z javascript.
Strona 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 */ } });
Strona 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
LUB PO PROSTU WYŚLIJ DUMMY PROPERTY z javascript, który wypełnisz w PHP.
źródło