2010-12-14 5 views
31

Come posso convertire il risultato di Trips::model()->findAll() in un array?Modello Yii in array?

+2

proposito da attuare https://github.com/yiisoft/yii/issues/531 – Lamy

risposta

1

utilizzare DAO per gli array

$array = Yii::app()->db->createCommand('SELECT * FROM tbl')->queryAll(); 
3

sono abbastanza sicuro si può fare questo:

$trips = Trips::model()->findAll(); 
$arr = array(); 
foreach($trips as $t) 
{ 
    $arr[$t->id] = $t->attributes; 
} 

sto assumendo che abbiate l'attributo 'id' come chiave primaria del modello.

+3

ahem, non dimenticate di controllare se $ viaggi è vuoto oppure no: D – ZaQ

+1

i viaggi $ restituiranno sempre un array, perché ognuno non restituirà un errore, anche l'iterazione è un array vuoto. – GusDeCooL

+1

ZaQ - se findAll() restituisce un array vuoto, il controllo per vuoto prima di utilizzare foreach è uno spreco. – grantwparks

23

Questo è il modo giusto per farlo, ne consegue convenzioni Yii

$trips = Trips::model()->findAll(); 
$arr = array(); 
foreach($trips as $t) 
{ 
    $arr[$t->id] = $t->attributes; 
} 

Questo viene utilizzato quando si dispone di query complesse, quelle che si trovano difficile creare con le convenzioni Yii.

Yii::app()->db->createCommand('SELECT * FROM tbl')->queryAll(); 

Ad esempio, quando è necessario passare tutti i dati dal modello a un array. Non puoi passarlo direttamente poiché passa alcune informazioni di dati di ActiveRecord che non ti servono.

+0

Non consiglierei di utilizzare la prima soluzione che hai fornito. findAll metodo crea l'oggetto del modello per ogni riga e poi popola la proprietà degli attributi. È un'operazione inutile perché hai solo bisogno di dati grezzi dal database. createCommand è preferibile. – vooD

33

Qui partendo dal presupposto che è necessario recuperare solo gli array nudi e non tutti gli oggetti modello associati.

Questo lo farà:

$model = Trips::model(); 
$trips = $model->getCommandBuilder() 
       ->createFindCommand($model->tableSchema, $model->dbCriteria) 
       ->queryAll(); 

Questo è come i Yii::app()->db->createCommand('SELECT * FROM tbl')->queryAll(); esempi, ad eccezione di:

  • E chiederò il modello per il nome della tabella; non è necessario scrivere il nome della tabella sia nel modello che nella query.

  • È possibile chiamare le funzioni scoping su $model prima, ad es.
    $model = Trips::model()->short()->destination('Austin, TX');
    Ciò significa che è possibile utilizzare le scorciatoie di query esistenti del modello, anziché inserirle direttamente nella query.

Al contrario, il $trips = Trips::model()->findAll(); (utilizzando foreach) è un po 'uno spreco, in quanto si sta tirando le righe dal database, la creazione di un gruppo di oggetti, e poi li buttare via. Funzionerà bene per piccoli set di risultati, ma non lo userei se stai guardando una lunga lista di Viaggi.

Caveat:
Se questo è solo un prototipo rapido, anche se, con tutti i mezzi utilizzare i createCommand() o findAll() - Esempi di e-ciclo.

+1

Avviso rapido per chiunque usi questo approccio: dopo aver cambiato la selezione in $ model-> dbCriteria per ottenere solo le colonne che mi servivano .. questo ha influito (e rimosso altri attributi da) tutte le chiamate standard $ model-> find() nel stessa richiesta Insetto particolarmente difficile da trovare. – Arth

+0

@Arth: Sono confuso; stai dicendo che stai modificando '$ model-> dbCriteria' direttamente prima di chiamare? –

+0

Anch'io, l'ho scritto tanto tempo fa! Immagino di dover avere! – Arth

4
$model = Trips::model()->findAll(); 
$arr = CHtml::listData($model, 'trip_id', 'trip_name'); 
var_dump($arr); 

CHTML :: listData() restituirà un valore di matrice.

+3

Il '$ trips = Trips :: model() -> findAll()' in combinazione con 'listData()' (che sta facendo un foreach sui modelli) è un po 'dispendioso, in quanto stai tirando le righe da il database, creando un sacco di oggetti e poi gettandoli via tutti. –

13

Questo è lo stesso.

$array = CHtml::listData(Trips::model()->findAll(), 'trip_id', 'trip_name'); 
+9

'' Trips :: model() -> findAll() 'in combinazione con' listData() '(che sta facendo un foreach sui modelli) è un po 'dispendioso, nel senso che stai tirando le righe dal database, creare un mucchio di oggetti e poi buttarli via tutti. –

2
$cats = Category::model()->findAll(); 
$count_cats = count($cats); 
if($count_cats > 0){ 
    $arr_category = array(); 
    foreach($cats as $cat) 
     array_push($arr_category,$cat->attributes); 
} 
print_r($arr_category); 

-> risultato

Array(
[0] => Array 
    (
     [cat_id] => 2 
     [title] => Đương đại 
     [title_full] => Đương đại 
     [desc] => 
     [alias] => duong-dai 
     [p_id] => 0 
     [type] => 1 
     [status] => 1 
     [sort_order] => 2 
     [selected] => 0 
    ) 
[1] => Array 
    (
     [cat_id] => 164 
     [title] => Nhiệt đới 
     [title_full] => Nhiệt đới 
     [desc] => 
     [alias] => nhiet-doi 
     [p_id] => 0 
     [type] => 1 
     [status] => 1 
     [sort_order] => 0 
     [selected] => 0 
    ) 
[...]) 
+0

ciao, grazie questa è la migliore soluzione. –

2

Supponendo dalla tua domanda che si desidera che tutti gli attributi, una soluzione più compatta per darvi tutti gli attributi hash per ID, è possibile utilizzare 'gli attributi di CActiveRecord 'pseudoproperty come segue:

CHtml::listData(Trips::model()->findAll(), 'id', 'attributes') 
2

i usano $array = CJSON::decode(CJSON::encode($model)); per convertire $ modello per $ array.

+0

Quel fantastico.Funziona –

6

facile e semplice modo: io uso listData() metodo per rendere array menu a discesa, e credo che questo vi aiuterà a controllare .. questo esempio:

codice:

<?php 
    /*you can use here any find method you think 
    proper to return your data from db*/ 
    $models = Trips::model()->findAll(); 

    // format models resulting using listData  
    $tripsArray = CHtml::listData($models, 'id', 'name');  

    print_r($tripsArray); 
?> 

uscita:

array(
'1'=>'trip1', 
'2'=>'trip2', 
'3'=>'trip3', 
) 
0

Non utilizzare CHtml :: listData per questo. Deve essere usato per altri scopi. C'è un indice indice proprietà di CDbCriteria che è adatto per voi requisito.

//1st option 
Trips::model()->findAll(array('index'=>'trip_id')); 

//2nd option 
$c = new CDbCriteria(); 
$c->index = 'trip_id'; 
Trips::model()->findAll($c); 
3

È possibile creare raccolte CMap continuano a lavorare con lei

$collections = new CMap(); 
foreach (YourModel::model()->findAll(['index' => 'id']) as $key => $row) { 
    $collections->add($key,$row->attributes); 
} 
var_dump($collections ->toArray()); 
+1

La migliore soluzione. +1. – Gogol

3

È possibile utilizzare questo.

$Trips::model()->findAll(array('index'=>'trip_id')); 
if(count($Trips)>0) 
      {     
       $TripsArrayList=array(); 
       foreach($Tripsas as $singleTrip) 
       {     
        $TripsArrayList[]=array('trip_id'=>$singleTrip->trip_id,'name'=>$singleTrip->name);   
       }     
      } 

L'output sarà

Array 
    (
     [0] => Array 
       (
        [trip_id] => 1 
        [name] => Nashik 
       ) 
     [1] => Array 
       (
        [trip_id] => 2 
        [name] => Puna 
       ) 
     [2] => Array 
       (
        [trip_id] => 3 
        [name] => Mumbai 
       ) 
    )