Подтвердить что ты не робот

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

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

Мой класс объектов свойств выглядит следующим образом:

/* 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 по мере необходимости, вместо того, чтобы иметь несколько "включает"

Любая помощь очень ценится.

4b9b3361

Ответ 1

$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 перед использованием любого класса

function __autoload($className)
{
    require_once 'myclasses/'.$className.'.php';
}

Итак, первый вызов new UserVo приведет к включению этой функции в файл myclasses/UserVo.php.

Ответ 3

Сначала преобразование данных в объект массива для UserVO должно выполняться с помощью ArrayObject

так

class UserVO extends ArrayObject
{
}

Вы пытаетесь использовать шаблон factory, и ваш код кажется правильным, хотя вы, похоже, забыли define $result в виде массива ($ result = array()).

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

$rc = new ReflectionClass($vo);
$rc->newInstanceArgs($data[$i]);

Чтобы "автозагрузить" ваш объект UserVO, вы должны использовать функцию spl_autoload_register с помощью пути включения php.

Ответ 4

Это работает

<?

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'=>'[email protected]');
$data[] = array('id'=>2,'email'=>'[email protected]');
$data[] = array('id'=>3,'email'=>'[email protected]');
$data[] = array('id'=>4,'email'=>'[email protected]');
$data[] = array('id'=>5,'email'=>'[email protected]');
$data[] = array('id'=>6,'email'=>'[email protected]');

$result = create_vo($data,'UserVO');

var_dump($result);

?>