【问题标题】:Yii selecting only specified attributes in arrayYii 仅选择数组中的指定属性
【发布时间】:2012-07-18 23:11:13
【问题描述】:

我经常遇到这个问题..

假设..在博客应用程序中,我需要向所有活跃用户发送电子邮件..

我所做的是在用户上一次登录的某些条件大于某个值的情况下编写 findAll..并获取所有用户对象...然后通过所有用户模型对象运行 foreach 并将电子邮件存储在一个数组中,然后使用数组..

换句话说,后端发生的事情是我正在加载整个模型,而我只需要几乎没有0.5% 的信息,然后运行脏代码以获取数组中的值,然后对其进行处理..

在性能和脏代码方面是不是很糟糕..

现在我能想到的其他方法是使用commandBuilder 并编写查询,然后运行相同的脏代码以获取数组中的值..解决了一个性能问题..但正如人们所说在 mvc 框架中编写 sql,不是真是个好主意..

我真正想要的...一些类似的函数,如果它是单列,则为我提供数组中的列值,如果是多列,则以列名作为索引的数组..

所以我想做的是通过扩展 ActiveRecord 或类似的东西来实现它,我想检查的是是否有人已经实现了类似的东西,或者对它有一些想法..:)强>

【问题讨论】:

标签: php activerecord yii


【解决方案1】:

您必须深入研究 CDbCriteria,它们就是您所看到的一切。

举个例子::

$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 也是一个数组输出。

【讨论】:

  • 请把你的问题说清楚,我是根据我的理解回答的。
  • 为什么设置 't.first_name' 而不是 'a.first_name'。我尝试了“a.first_name”,但它与第一​​个不同。这是某种约定吗?
  • Alex,这是一个默认的表别名。 Yii 创建类似“SELECT t.id FROM table t”的查询,但它可能会因查询复杂性(多表查询)而异。检查yiiframework.com/doc/api/1.1/CActiveRecord#getTableAlias-detail
  • @Копать_Шо_я_нашел 删除别名
【解决方案2】:

在 Yii2 中,你可以这样使用:

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

【讨论】:

  • 这应该是认可的答案
  • @realtebo 是的,这应该是经过批准的答案,但问题是针对 yii1 而不是 yii2
  • 假设你做$data = User::find()->select(['field1','field2']); 然后你打印$data->attributes。您会发现该表的所有列都将为空值。
【解决方案3】:

我创建了我所说的行为,它的工作方式是:

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

**returns array('rajat@gmail.com','rajatsinghal@gmail.com')..**

现在不需要遍历所有活动记录并收集 数组中的列,然后继续,并承担整个加载的重量 列..

你可以在 git 上找到扩展名 ..https://github.com/rajatsinghal/CAdvancedArFindBehavior

【讨论】:

    【解决方案4】:

    这也可以在没有任何行为或没有添加到 CActiveRecord 的情况下工作。不过我也喜欢这种行为的解决方案。

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

    【讨论】:

      【解决方案5】:

      需要使用array_filter函数过滤模型属性。试试这样,效果很好 -

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


      分配前使用array_filter。

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


      所以,你会得到这样的输出 -

      [{"first_name" : "Rohit", "email" : "rohitsuthar@gmail.com"}, {"first_name" : "Rajat", "email" : "rajat@example.com"}]
      

      【讨论】:

        【解决方案6】:

        与问题描述的情况相同。 在尝试了上述所有答案和其他一些资源之后,我正在做的是。

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

        【讨论】:

          猜你喜欢
          • 2018-08-09
          • 2013-05-10
          • 1970-01-01
          • 1970-01-01
          • 2015-11-05
          • 2018-03-26
          • 2012-09-02
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多