【问题标题】:How to iterate over Yii CActiveDataProvider object?如何迭代 Yii CActiveDataProvider 对象?
【发布时间】:2012-08-23 14:25:28
【问题描述】:

如何迭代 dataprovider 对象?我想访问返回的每一行的“名称”字段并构建一个列表。你能帮忙吗?

表/模型categories的表结构

CREATE TABLE IF NOT EXISTS `categories` (
  `idCategory` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(64) NOT NULL,
  PRIMARY KEY (`idCategory`) USING BTREE
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=55 ;

*我的控制器类别中的函数*

    $names = array();
    public function returnCategoryNames()
{
    $dataProvider= new CActiveDataProvider('Categories');
    $dataProvider->setPagination(false);
    $count = $dataProvider->totalItemCount();

    for($i = 0; $i < $count; $i++){

             // this is where I am lost...
             $myname = $dataProvider->data[$i]->name;
             array_push($names, $myname);

    }   

       return $names;

}

【问题讨论】:

    标签: php mysql html yii


    【解决方案1】:

    在 Yii2 中这也发生了变化:

        $searchModel = new ModelSearch();
        $dataProvider = $searchModel->search(Yii::$app->request->queryParams);
    
        foreach($dataProvider->getModels() as $record) {
            echo $record->id . '<br>';
        }
    
        exit();
    

    参考:getModels()

    【讨论】:

      【解决方案2】:

      使用@ben-rowe 的解决方案,您可以一次查询所有行。您可能会遇到内存问题。

      使用以下解决方案,您将从十乘十获取类别(默认 CPagination.pageSize 值):

              $dataProvider = new CActiveDataProvider('Categories', array(
                  'pagination' => array(
                      'validateCurrentPage' => false
                  ),
              ));
              $pagination = $dataProvider->pagination;
              while ($categories = $dataProvider->getData(true)){
                  foreach ($categories as $category) {
                      //...
                  }
                  $pagination->currentPage++;
              }
      

      【讨论】:

      • 感谢这个解决方案!
      【解决方案3】:

      如果您需要大量数据收集并且担心内存使用情况,请执行以下操作:

      $dataProvider = new CActiveDataProvider('Categories');
      $iterator = new CDataProviderIterator($dataProvider);
      foreach($iterator as $category) {
         print_r($category);
      }
      

      CDataProviderIterator 允许对大型数据集进行迭代,而无需将整个数据集保存在内存中。

      一些性能测试

      测试时间(秒) 内存(字节) CDbDataReader 4.9158580303192 28339952 CActiveRecord::findAll() 5.8891110420227 321388376 CDataProviderIterator 6.101970911026 31170504

      【讨论】:

      • CDataProvider 仍然会调用 findAll(),它只是允许您指定要通过分页进行实际 sql 查询的次数。 CDbDataReader 只进行 1 次 sql 调用并以内存高效的方式迭代结果。
      • CDataProviderIterator 与 CDataProvider 不同
      【解决方案4】:

      试试这个:

      public function returnCategoryNames()
      {
        $dataProvider= new CActiveDataProvider('Categories');
        $dataProvider->setPagination(false);
        //$count = $dataProvider->totalItemCount();
        $names = array();
        foreach($dataProvider->getData() as $record) {
          $names[] = $record->name;
        }
        return array_unique($names);
      }
      

      但是您不需要使用数据提供者,而只需使用模型

      foreach(Categories::model()->findAll() as $record) {
      

      【讨论】:

      • 我真的很喜欢你给的第二个选项(Categories::model())。有没有办法用这个选项做 ORDER BY ?还是要求太多了
      • easy:Categories::model()-&gt;findAll(array('order' =&gt; 'name'));,您可以在以下位置找到有关 find() 命令的详细信息:yiiframework.com/doc/api/1.1/CActiveRecord#findAll-detail
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-09-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多