web-dev-qa-db-fra.com

Yii ne sélectionnant que les attributs spécifiés dans le tableau

Je fais souvent face à ce problème ..

Disons .. Dans l'application du blog, je dois envoyer un courriel à tous les utilisateurs actifs ..

Ce que je fais est d’écrire findAll sur les utilisateurs avec certaines conditions de leur dernière connexion dépassant certaines valeurs ... et d’obtenir tous les objets User ... Ensuite, exécutez un foreach à travers tous les objets de modèle utilisateur et stockez les emails dans un tableau, puis utilisez le tableau ..

En d’autres termes, ce qui se passe dans le back-end, c’est que je charge tout le modèle, alors que je n’ai besoin que de peine0.5% de cette information, puis d’un code corrompu pour obtenir des valeurs dans un tableau, puis le traiter.

N'est-ce pas assez mauvais en performance et code sale ..

Maintenant, une autre approche à laquelle je peux penser est d'utiliser commandBuilder et d'écrire une requête, puis d'exécuter le même code sale pour obtenir des valeurs dans array..on un problème de performance résolu..mais comme les gens disent écrire SQL dans les frameworks mvc, ce n'est pas une très bonne idée. .

Ce que je veux vraiment ... des fonctions similaires qui me donnent des valeurs de colonne dans array s'il s'agit d'une seule colonne, ou array avec le nom de colonne comme index si plusieurs colonnes ..

Donc, ce que je pense faire, c'est de le mettre en œuvre en étendant ActiveRecord ou quelque chose de similaire, ce que je veux vérifier, c'est si quelqu'un a déjà implémenté quelque chose de similaire, ou si vous avez des idées pour cela .. :)

13
Rajat Singhal

J'ai créé le comportement comme je l'ai dit, la façon dont cela fonctionne est la suivante:

$active_users_emails = User::model()->findColumn('email', 'active = 1');

**returns array('[email protected]','[email protected]')..**

Maintenant, il n'est pas nécessaire de passer par tous les activerecords et de collecter colonne en tableau, puis continuez et supportez également le poids du chargement entier colonne..

Vous pouvez trouver l'extension sur git .. https://github.com/rajatsinghal/CAdvancedArFindBehavior

11
Rajat Singhal

Vous devez étudier les critères CDb en profondeur, leur apparence est tout ce que vous cherchez. 

Avoir un exemple ::

$criteria = new CDbCriteria;
$criteria->select = 't.first_name, t.email'; // select fields which you want in output
$criteria->condition = 't.status = 1';

$data = Users::model()->findAll($criteria);

$ data est aussi une sortie de tableau.

16
Onkar Janwa

En Yii2, vous pouvez utiliser comme ceci:

User::find()->select(['field1', 'field2']);
12
Zhang Buzz

Cela fonctionnerait également sans aucun comportement ou sans l'ajout de CActiveRecord. Néanmoins, j'aime aussi la solution au comportement.

$active_users_emails=CHtml::listData(User::model()->findAllByAttributes(array('active'=>1)), 'id', 'email');
6
hurz

Besoin de filtrer les attributs du modèle en utilisant array_filter function. Essayez comme ça, ça marche très bien -

$criteria = new CDbCriteria;
$criteria->select = 't.first_name, t.email'; // select fields which you want in output
$criteria->condition = 't.status = 1';

$data = Users::model()->findAll($criteria);


Utilisez array_filter avant assign.

foreach($data as $model){
      $rows[] = array_filter($model->attributes);
   }

echo CJSON::encode($rows)


Ainsi, vous obtiendrez une sortie comme celle-ci - 

[{"first_name" : "Rohit", "email" : "[email protected]"}, {"first_name" : "Rajat", "email" : "[email protected]"}]
2
Rohit Suthar

Dans la même situation que la question décrit… .. Après avoir essayé toutes les réponses ci-dessus et quelques autres ressources, voici ce que je suis en train de faire.

$emailIds = Yii::app()->db->createCommand(
                 'SELECT email FROM users WHERE is_active = 1'
            )->queryAll();

$emailIds = array_column( $emailIds, 'email' ) );
0
BKY