2010-09-10 20 views
11

Digamos que tengo una matriz que quiero convertir a un objeto de valor.Clase dinámica de PHP cargando

Mi clase de objeto de valor es el siguiente:

/* file UserVO.php*/ 
class UserVO 
{ 
    public $id; 
    public $email; 

    public function __construct($data) 
    { 
     $this->id = (int)$data['id']; 
     $this->email = $data['email']; 
    } 
} 

Y creo mi matriz de objetos de valor de la siguiente manera:

/* file UserService.php*/ 
$array = array(
array(...), 
array(...)); 
$count = count($array); 
for ($i = 0; $i < $count; $i++) 
{ 
    $result[] = new UserVO($array[$i]); 
} 
return $result; 

OK, así que todo esto funciona bien. Sin embargo, me gustaría especificar el VO que se creará dinámicamente, de modo que pueda tener una sola función dinámica para crear mi VO.

Algo así como:

$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; 
} 

me di cuenta de que podía hacer esto con una instrucción switch (iteración a través de todo de mi VO) ... pero no hay duda de mucho mucho más elegante solución. También sería supercool si pudiera cargar perezosos los VO según sea necesario, en lugar de tener múltiples 'incluye'

Cualquier ayuda muy apreciada.

Respuesta

13
$result[] = new $vo($data[$i]); //this obviously wont work...Class name must be a valid object or a string 

¿Has probado? Funciona justo como se esperaba (en php 5.1, no sé cómo fue con OOP en php 4, pero si está usando __construct para constructor esto debería funcionar).

Para evitar múltiple incluye definir la función mágica __autoload antes de usar cualquier clase

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

Así primera llamada new UserVo que activa esta función para incluir archivos myclasses/UserVo.php.

0

En primer lugar, la conversión de datos a un objeto de matriz de UserVO debe hacerse con ArrayObject

por lo

class UserVO extends ArrayObject 
{ 
} 

Usted está tratando de utilizar el factory method pattern y su código parece estar en lo cierto, aunque pareces tener un olvidado para definir $ resultado como una matriz ($ result = array()).

También puede utilizar el ReflectionClass para pasar argumentos de constructor, así como tal:

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

Para "auto-carga" el objeto UserVO, se debe utilizar la función spl_autoload_register con un php incluye el camino.

0

Esto funciona

<? 

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); 

?> 
1

Parece que include_once()'s and require_once()'s performance is pretty bad.

Mi sugerencia:

matar a todos "require_once" y "include_once" y crear un cargador automático.Registre esta implementation

+0

su cargador automático sigue utilizando incluir o no requieren que no se carga cada cosa constante sólo cuando son necesarios para que su argumento no es la más válida. ya que usar el autocargador es más carga. –