Создание экземпляра объекта из опубликованных данных – PHP

Каков наилучший способ создания и заполнения объекта из значений, переданных из формы?

Если, например, у меня есть класс Car со свойствами Color, Model, Make, Year и метод Save, который либо вставляет, либо обновляет запись.

Затем у меня есть форма, которая имеет поля для всех этих значений и отправляется. Я хочу создать экземпляр класса Car с опубликованными значениями, а затем вызвать метод Save. Все хорошо и хорошо.

Но каков наилучший способ присвоения опубликованных значений внутренним свойствам объектов. Предполагая, что это упрощенный сценарий, и реальная ситуация будет иметь гораздо больше свойств, делая индивидуальные вызовы Set длинными.

Лучше всего просто вызвать метод Set для каждого из них? Или передать массив в метод (или конструктор), который затем вызывает методы Set? Или каким-то другим способом?

Любые рекомендации по передовым методам оцениваются

Приветствия Стюарта

Solutions Collecting From Web of "Создание экземпляра объекта из опубликованных данных – PHP"

Я бы выполнил магическую функцию __set_state() , поскольку он предназначен именно для этого варианта использования. Существует несколько преимуществ внедрения реализации в этот метод:

  1. Это очень хорошо определено, что делает эта функция (она определена в документах PHP, в отличие от вашего собственного исходного кода)
  2. Вы можете получить доступ к частным членам внутри функции
  3. Объекты, сбрасываемые с помощью var_export() будут автоматически восстановлены с использованием этой функции.

РЕДАКТИРОВАТЬ В комментариях:

 class A { private $member = 1000; public static function test(A $a) { echo $a->member; } } echo A::test(new A()); // outputs 1000 

EDIT Выполнение другого запроса из комментариев:

Вы не можете знать, на каком классе был вызван статический метод, если вы не используете php 5.3, в котором была введена требуемая функция ( поздняя статическая привязка ). Что вы можете сделать при эмуляции get_called_class() , анализируя текущий стек (используя debug_backtrace() ). Если у вас есть работающая get_called_class() , вы можете сделать следующее:

 class BaseClass { public static function __set_state($state) { $class = get_called_class(); // Assumption: Constructor can be invoked without parameters! $object = new $class(); foreach (get_class_vars($class) as $member) { if (!isset($state[$member])) { // Member was not provided, you can choose to ignore this case throw new Exception("$class::$member was not provided"); } else { // Set member directly // Assumption: members are all public or protected $object->$member = $state[$member]; // Or use the setter-approach given by Chaos. $setter = 'set' . ucfirst($member); $object->setter($state[$member]); } } return $object; } } 

Вы можете использовать немного магии Reflection :

 public function loadFromArray($array) { $class = new ReflectionClass(get_class($this)); $props = $class->getProperties(); foreach($props as $p) { if (isset($array[$p->getName()]) $p->setValue($this, $array[$p->getName]); } } 

Вы можете реализовать этот метод в базовом классе и сделать все, что вы наследуете от этого объекта, так что у вас есть эта функция в каждом объекте, не повторяясь в любом классе.

Если свойства общедоступны:

 foreach($_POST as $key => $value) $obj->$key = $value; 

Если им нужны сеттеры:

 foreach($_POST as $key => $value) { $set = 'Set' . $key; $obj->$set($value); } 

Ну, вы можете преобразовать массив сообщений в объект за один шаг …

 $mypostobject = (object) $_POST; echo $mypostobject->Colour; 

EDIT: добавлена ​​ссылка на документы PHP. http://uk.php.net/manual/en/language.types.object.php

Если вы хотите сделать это со своим классом объектов, то какой-то конструктор или функция, которая принимает массив сообщений и настроит ваш класс, будет в порядке.

 class MyCar { public function __construct($postdata) { $this->Colour = $postdata['Colour']; // etc } }; $car = new MyCar($_POST); 

В случае, если объект, который вы публикуете, может стать более сложным, чем плоский список свойств в будущем (думаю, вложенность, массивы как значения и т. Д.), Вы можете сначала создать объект JavaScript на стороне клиента и опубликовать его как JSON внутри один параметр. Затем вы можете просто десериализовать строку JSON в объект PHP. PHP 5+ имеет встроенную поддержку десериализации JSON. Использование JSON позволит вам быть гибким в том, насколько сложным может быть ваш объект.

создайте конструктор, который примет все атрибуты

 class Car { // private members … public function __construct($color, $type, $model, $make) { // assign your values here } // other methods }; 

если вы имеете дело с ассоциативными массивами, вы также можете использовать конструктор с массивом в качестве аргумента:

 public function __construct($car_properties) {} 

и затем соедините ваши свойства с помощью

 foreach($car_properties as $property => $value) { if(isset($value)) $this->property = $value } 

не забудьте заранее проработать / подтвердить свой ввод! (не может этого достаточно подчеркнуть)