Допустим, у меня есть массив, который я хочу преобразовать в объект значения.
Класс объекта value имеет следующий вид:
/* file UserVO.php*/ class UserVO { public $id; public $email; public function __construct($data) { $this->id = (int)$data['id']; $this->email = $data['email']; } }
И я создаю свой массив объектов значений следующим образом:
/* file UserService.php*/ $array = array( array(...), array(...)); $count = count($array); for ($i = 0; $i < $count; $i++) { $result[] = new UserVO($array[$i]); } return $result;
Хорошо, так что все работает отлично. Тем не менее, я хотел бы указать VO, который должен быть создан динамически, так что у меня может быть одна динамическая функция для создания моих VO.
Что-то вроде:
$ret = create_vo($array, 'UserVO'); function create_vo($data, $vo) { $count = count($data); for ($i = 0; $i < $count; $i++) { $result[] = new $vo($data[$i]); //this obviously wont work...Class name must be a valid object or a string } return $result; }
Я понимаю, что могу сделать это с помощью оператора switch (итерации через все мои VO) … но, без сомнения, гораздо более элегантное решение. Это также было бы supercool, если бы я мог ленить загружать VO по мере необходимости, вместо того, чтобы иметь несколько «включений»,
Любая помощь очень ценится.
$result[] = new $vo($data[$i]); //this obviously wont work...Class name must be a valid object or a string
Ты это пробовал? Он работает так, как ожидалось (в php 5.1, я не знаю, как это было с ООП в php 4, но если вы используете __construct
для конструктора, это должно работать).
Чтобы избежать множественного __autoload
определите магическую функцию __autoload
перед использованием любого класса
function __autoload($className) { require_once 'myclasses/'.$className.'.php'; }
Итак, сначала вызовите new UserVo
чтобы эта функция включала файл myclasses / UserVo.php .
Похоже, что показатели include_once () и require_once () довольно плохие .
Мое предложение:
Убейте все «require_once» и «include_once» и создайте автозагрузчик. Зарегистрировать эту реализацию
Это работает
<? class UserVO { public $id; public $email; public function loadData($data) { $this->id = (int)$data['id']; $this->email = $data['email']; } } function create_vo($data, $vo) { $count = count($data); for ($i = 0; $i < $count; $i++) { $tmpObject = new $vo; $tmpObject->loadData($data[$i]); $result[] = $tmpObject; unset($tmpObject); } return $result; } $data = array(); $data[] = array('id'=>1,'email'=>'data@example.com'); $data[] = array('id'=>2,'email'=>'data@example.com'); $data[] = array('id'=>3,'email'=>'data@example.com'); $data[] = array('id'=>4,'email'=>'data@example.com'); $data[] = array('id'=>5,'email'=>'data@example.com'); $data[] = array('id'=>6,'email'=>'data@example.com'); $result = create_vo($data,'UserVO'); var_dump($result); ?>
с<? class UserVO { public $id; public $email; public function loadData($data) { $this->id = (int)$data['id']; $this->email = $data['email']; } } function create_vo($data, $vo) { $count = count($data); for ($i = 0; $i < $count; $i++) { $tmpObject = new $vo; $tmpObject->loadData($data[$i]); $result[] = $tmpObject; unset($tmpObject); } return $result; } $data = array(); $data[] = array('id'=>1,'email'=>'data@example.com'); $data[] = array('id'=>2,'email'=>'data@example.com'); $data[] = array('id'=>3,'email'=>'data@example.com'); $data[] = array('id'=>4,'email'=>'data@example.com'); $data[] = array('id'=>5,'email'=>'data@example.com'); $data[] = array('id'=>6,'email'=>'data@example.com'); $result = create_vo($data,'UserVO'); var_dump($result); ?>
Во-первых, преобразование данных в объект массива для UserVO должно выполняться с помощью ArrayObject
так
class UserVO extends ArrayObject { }
Вы пытаетесь использовать шаблон фабричного метода, и ваш код кажется правильным, хотя вы, похоже, забыли определить $ result как массив ($ result = array ()).
Вы также можете использовать ReflectionClass для передачи аргументов конструктора, а также таких:
$rc = new ReflectionClass($vo); $rc->newInstanceArgs($data[$i]);
Чтобы «автозагрузить» ваш объект UserVO, вы должны использовать функцию spl_autoload_register с помощью пути включения php.