Piszemy trait, który pozwoli nam zmienić dowolną klasę na tablicę asocjacyjną albo jej JSONowy format. Do dzieła.
Struktura wygląda tak:
trait toArray {
public function toArray(){
//(...)
}
public function toJSON(){
//(...)
}
}
class Person {
use toArray;
public function __construct(public $name, public $age)
{
}
}
class Item {
use toArray;
public function __construct(public $name, public $price)
{
}
}
Musimy napisać funkcję, która zamieni pola obiektu na tablicę asocjacyjną:
public function toArray(){
$vars = get_object_vars($this);
$output_array = [];
foreach($vars as $key => $value){
if(!is_null($value))
$output_array[$key] = $value;
}
return $output_array;
}
Pola pozyskujemy z get_object_vars, przekazując mu $this. Dalej działamy standardowo. Możemy już napisać metodę toJSON:
public function toJSON(){
return json_encode([__CLASS__ => $this->toArray()]);
}
Teraz możemy wypróbować działanie naszych metod:
$john = new Person("John", 22);
print_r($john->toArray());
//Array ( [name] => John [age] => 22 )
echo $john->toJSON();
//{"Person":{"name":"John","age":22}}
Zawsze też warto mieć z tyłu głowy myślenie, czy aby nie wynajdujemy koła na nowo i nie mamy już gotowych narzędzi, aby osiągnąć to, czego chcemy:
trait toArray {
public function toArray(){
return (array)get_object_vars($this);
}
public function toJSON(){
return json_encode([__CLASS__ => (array)get_object_vars($this)]);
}
}
Z drugiej strony – warto umieć tworzyć logikę różnych działań samemu, nie polegać całkowicie na gotowych rozwiązaniach, bo te mogą mieć jakieś wady.