Intereting Posts
как конвертировать www.example.com/posts/123 в example.com/posts/123? Ошибка DOMDocument :: loadHTML Скрипт загрузки Php Image Как загрузить содержимое / изображение / данные файла типа ввода? PHP simpleXML как сохранить файл в отформатированном виде? Yahoo Social SDK Помощь по настройке PHP? Кодовое обозначение: код автоинкремента ошибок Пользовательский доступ к конфигурационному файлу в конфигурационных файлах Laravel 5 Как прикреплять и показывать изображение по почте с помощью php? «Неопределенная константа / переменная» Ошибка при использовании Laravel с угловым JS … Невозможно показать переменную в лезвии Получить только элементы массива с определенными ключами Путь к папке с localhost Проверка формы ajax с помощью mysqli_query Будет ли Nginx в качестве обратного прокси для справки Apache только для динамического контента Zend Framework дополнительно Получить параметры с помощью NGINX

Загрузка динамического класса PHP

Допустим, у меня есть массив, который я хочу преобразовать в объект значения.

Класс объекта 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.