2015-05-20 9 views
5

Esiste un modo per ottenere le proprietà di classe e convertirlo utilizzando la trasmissione (array).Esiste un modo per convertire un array in proprietà di classe?

$user = (array) get_object_vars($userObject) 

Ma mi chiedo, non ho trovato alcun metodo diretto per convertire l'array in proprietà di classe.

Supponiamo che io ho classe utente con implementazione seguente:

class User 
{ 
    private $id = 0; 
    private $fname = ''; 
    private $lname = ''; 
    private $username = ''; 
} 

Ho seguente array:

$user = array(
    'id'=> 2, 
    'fname' => 'FirstName', 
    'lname' => 'LastName', 
    'username' => 'UserName' 
); 

Sto cercando un tipo di getto, proprio come abbiamo (object). Il problema è (object) tipo cast converte array in oggetto stdClass, ma qui voglio che il mio array venga convertito nella mia classe specificata.

L'esempio deve essere dichiarato come: (.. La mia ipotesi, che PHP dovrebbe avere questo o potrebbe già avere qualche cosa come questa e io non so)

$userobj = (object User) $user; 

E il risultato di sintassi di cui sopra dovrebbe essere proprio come:

$userobj->id = $user['id']; 
$userobj->fname = $user['fname']; 
$userobj->lname = $user['lname']; 
$userobj->username = $user['username']; 

Voglio sapere se esiste un metodo diretto, non una logica di mappatura. Stai cercando un trucco a livello di lingua.

Nota: Sono a conoscenza dell'uso di foreach per eseguire l'operazione in alto. Sto cercando un metodo diretto, se disponibile in PHP, ma non ancora messo a fuoco (potrebbe essere!).

seguito non risolve la mia domanda: Convert/cast an stdClass object to another class

+3

Dovrete scrivere il proprio metodo personalizzato per farlo. Il motivo è che l'oggetto non saprà come gestire proprietà o proprietà diverse che non sono state definite. Qualcosa come $ object-> load ($ array). –

+0

possibile duplicato di [Conversione di un array PHP in variabili di classe] (http://stackoverflow.com/questions/2715465/converting-a-php-array-to-class-variables) –

+0

possibile duplicato di [Convertire/cast di stdClass oggetto a un'altra classe] (http://stackoverflow.com/questions/3243900/convert-cast-an-stdclass-object-to-another-class) – Richard

risposta

0

Una matrice non è un oggetto. Quindi non puoi lanciarlo con un costrutto linguistico. Anche il casting di oggetti definiti dall'utente in PHP non è possibile.

Quindi devi scrivere la tua logica. Esistono alcuni approcci fantasiosi dell'oggetto serialize(), cambiare il nome della classe e unserialize() nuovamente per automatizzare il processo.

Inoltre, è possibile scrivere una funzione di fusione mediante la riflessione. Ma tutto ha bisogno della logica dell'utente.

Vedi anche questo post su SO: Type casting for user defined objects

Quindi, se vi piace veramente a lanciare oggetti Ho finito con questa funzione (see it in action):

function cast($to, $obj) 
{ 
    $toLength = strlen($to); 
    $serializedObj = preg_replace('/^O:\\d+:"[^"]+"/', 'O:' . $toLength . ':"' . $to . '"', serialize($obj)); 

    $serializedObj = preg_replace_callback('/s:(\\d+):"([^"]+)";(.+?);/', function($m) use($to, $toLength) { 
     $propertyName = $m[2]; 
     $propertyLength = $m[1]; 

     if(strpos($m[2], "\0*\0") === false && ($pos = strrpos($m[2], "\0")) !== false) { 
      $propertyName = "\0" . $to . "\0" . substr($m[2], $pos + 1); 
      $propertyLength = ($m[1] + $toLength - $pos + 1); 
     } 

     return 's:' . $propertyLength . ':"' . $propertyName . '";' . $m[3] . ';'; 
    }, $serializedObj); 

    return unserialize($serializedObj); 
} 

$user = array(
    'id'=> 2, 
    'fname' => 'FirstName', 
    'lname' => 'LastName', 
    'username' => 'UserName' 
); 

$userObj = cast(User::class, (object)$user); 

print_r($userObj); 

ma non avrei mai usare mai questa funzione in produzione. È solo una cosa sperimentale.

Aggiornamento

Ok ho ripensato come fusione è gestita in Java. In Java puoi effettivamente trasmettere da un oggetto a un oggetto figlio di esso. Non puoi lanciare da nessun oggetto a nessun altro.

Così si potrebbe fare questo in Java:

$apple = new Apple(); 
$macintoshApple = (MacintoshApple)$apple; 

dato che MacintoshApple extends Apple.

Ma non si può lanciare due oggetti non correlati come:

$apple = new Apple(); 
$pear = (Pear)$apple; 
+0

Funzione molto bella, ma qui un'altra domanda con la tua risposta è; che dire del confronto delle prestazioni con la logica 'foreach'? –

+0

Posso solo indovinare, ma dalla mia esperienza direi che né la serializzazione né l'approccio di riflessione battono in performance. – TiMESPLiNTER

+0

Hai ragione, ho appena confrontato entrambi e ho trovato che il metodo 'foreach' è quasi il doppio della velocità. –

0

Sulla base della sua risposta al commento da @AbraCadaver vorrei guardare utilizzando qualcosa di simile per caricare i risultati di DB in una classe istanziata di vostra scelta:

// using MySQLi 
$mysqli_result = ...; // your mysqli_result object 
while($class_obj = $mysqli_result->fetch_object('your_class_name')) { 
    // do something 
} 

// using PDO 
$pdo_statement = ...; // your PDOStatement object 
while($class_obj = $pdo_statement->fetch_object('your_class_name')) { 
    // do something 
} 
+0

Ciao Mike, il mio commento è stato quello di ottenere qualcosa come quello che abbiamo con 'fetch_object', ma non sto usando/recuperando dati da db. Il mio esempio lo spiega bene. :) –