2010-09-10 11 views
11

Diciamo che ho una matrice che voglio convertire in un oggetto valore.Caricamento della classe dinamica PHP

il mio valore di classe di oggetto è la seguente:

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

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

E Creo il mio array di oggetti di valore come segue:

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

OK, quindi questo tutto funziona bene. Tuttavia, mi piacerebbe specificare il VO che deve essere creato dinamicamente, in modo che io possa avere una singola funzione dinamica per creare i miei VO.

Qualcosa di simile:

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

mi rendo conto che avrei potuto fare questo con un'istruzione switch (iterazione attraverso tutti i miei VO) ... ma non c'è alcun dubbio un molto molto più elegante soluzione. Sarebbe anche un supercool se potessi caricare i VO come necessario, invece di avere più "include"

Qualsiasi aiuto molto apprezzato.

risposta

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

Hai provato? Funziona esattamente come previsto (in php 5.1, non so come sia stato con OOP in php 4, ma se si utilizza __construct per il costruttore questo dovrebbe funzionare).

Per evitare multipla include definire la funzione magica __autoload prima di utilizzare qualsiasi classe

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

Quindi prima chiamata new UserVo attiverà questa funzione per includere file di myclasses/UserVo.php.

0

In primo luogo, la conversione dei dati in un oggetto array per UserVO dovrebbe essere fatto con ArrayObject

così

class UserVO extends ArrayObject 
{ 
} 

Si sta tentando di utilizzare la factory method pattern e il codice sembra essere giusto, anche se ti sembra avere un dimenticato per definire $ result come array ($ result = array()).

È inoltre possibile utilizzare il ReflectionClass per passare argomenti del costruttore, così come ad esempio:

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

Per "caricare automaticamente" l'oggetto UserVO, si dovrebbe utilizzare la funzione spl_autoload_register con un php include percorso.

0

Questo funziona

<? 

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

Sembra che include_once()'s and require_once()'s performance is pretty bad.

Il mio suggerimento:

Uccidete tutti "require_once" e "include_once" e creare un autoloader.Registra questo implementation

+0

il tuo caricatore automatico utilizza ancora include o richiede che non carichi ogni cosa costantemente solo quando sono necessari, quindi il tuo argomento non è il più valido. poiché l'uso del caricatore automatico è più carico. –

Problemi correlati