2010-09-10 3 views
11

Disons que j'ai un tableau que je veux convertir en objet de valeur.PHP dynamic class loading

Ma valeur classe d'objets est la suivante:

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

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

Je crée mon tableau d'objets de valeur comme suit:

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

OK, donc tout cela fonctionne très bien. Cependant, je voudrais spécifier la VO qui doit être créée dynamiquement, de sorte que je puisse avoir une seule fonction dynamique pour créer mes VO.

Quelque chose comme:

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

Je me rends compte que je pouvais le faire avec une instruction switch (itérer tout mon VO de) ... mais il ne fait aucun doute une solution beaucoup plus élégante. Ce serait aussi super cool si je pouvais paresser charger les VO au besoin, au lieu d'avoir plusieurs 'inclus'

Toute aide très appréciée.

Répondre

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

Avez-vous déjà essayé? Cela fonctionne comme prévu (en php 5.1, je ne sais pas comment c'était avec OOP en php 4, mais si vous utilisez __construct pour le constructeur cela devrait fonctionner).

Pour éviter de multiples comprend la fonction de définir la magie __autoload avant d'utiliser toute la classe

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

donc premier appel new UserVo déclenchera cette fonction d'inclure le fichier myclasses/UserVo.php.

0

En premier lieu, la conversion des données à un objet de tableau pour UserVO le factory method pattern et votre code doit être fait avec ArrayObject

si

class UserVO extends ArrayObject 
{ 
} 

Vous essayez d'utiliser semble avoir raison, si vous semblez avoir oublié de définir $ result en tableau ($ result = array()).

Vous pouvez également utiliser la ReflectionClass pour passer des arguments du constructeur, ainsi que par exemple:

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

Pour « autoload » votre objet UserVO, vous devez utiliser la fonction spl_autoload_register avec un php include chemin.

0

Cela fonctionne

<? 

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

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

Ma suggestion:

Tuez tous "require_once" et "include_once" et créer un chargeur automatique.Inscrivez-vous implementation

+0

votre chargeur automatique utilise encore include ou require it ne charge pas tout en permanence seulement quand ils sont nécessaires donc votre argument n'est pas le plus valide. comme l'utilisation de l'autochargeur est plus de charge. –