使用CDataProviderIterator(Yii)的PHP内存不足


PHP out of memory with CDataProviderIterator (Yii)

Yii框架上的PHP脚本内存不足。我试着做了很多调试。我使用CDataProviderIterator,因为Yii文档中这样描述它:

例如,以下代码将在不耗尽内存的情况下迭代所有注册用户(活动记录类User),即使数据库中有数百万用户。

这段代码迭代了大约150万条记录,在尝试时内存不足。我正在寻求任何帮助来解释它为什么会这么做。谢谢

public function foo($model, $relations) {
    $dataProvider = new CActiveDataProvider($model, array('criteria' => $model->dbCriteria));
    $iterator = new CDataProviderIterator($dataProvider, 200);
    $this->modelsToArray($iterator, $relations, $model_as_array = array());
}
public function modelsToArray($model, $relations, $model_as_array = array()) {
    $preparedRelations = $this->prepareRelations($relations);
    if (is_null($model))
    {
        return array();
    }
    $model_as_array = array();
    if (get_class($model) === 'CDataProviderIterator') {
        foreach ($model as $row) {
            $model_as_array[] = $this->modelsToArrayHelper($preparedRelations, $row);
        }   
    }
    else {
        $model_as_array[] = $this->modelsToArrayHelper($preparedRelations, $model);
    }
    return $model_as_array;
}
private function modelsToArrayHelper($relations, $listOfModels) {
    $listOfArrayModels = array();
    if(!is_array($listOfModels)){
        return $this->modelToArrayHelper($listOfModels, $relations);
    }
    foreach ($listOfModels as $index => $model)
    {
        $listOfArrayModels[$index] = $this->modelToArrayHelper($model, $relations);
    }
    return $listOfArrayModels;
}
private function modelToArrayHelper($model, $relations){
    $model_as_array = $this->processAttributes($model);
    foreach ($relations as $relationIndex => $relation)
    {
        $relationName = is_string($relationIndex) ? $relationIndex : $relation;
        if(empty($model->$relationName)) 
            continue;
        if ($model->relations()[$relationName][0] != CActiveRecord::STAT)
        {
            $subRelations = is_array($relation) ? $relation : array();
            $model_as_array[$relationName] = $this->modelsToArrayHelper($subRelations, $model->$relationName);
        }
        else
        {
            $model_as_array[$relationName] = $model->$relationName;
        }
    }
    return $model_as_array;
}

我相信您正在尝试将CDataProviderIterator转换为Php数组。所以为了放置阵列,你需要更多的内存

ini_set('memory_limit', '-1');

这将ram的使用设置为最大使用

ini_set('memory_limit', '512M');

这将ram的使用设置为512 Mb

你能把你的代码做成这样吗,只是为了确保你没有使用太多的ram

public function foo($model, $relations) {
    $dataProvider = new CActiveDataProvider($model, array('criteria' => $model->dbCriteria));
    $iterator = new CDataProviderIterator($dataProvider, 200);
    $preparedRelations = $this->prepareRelations($relations);
    foreach ($iterator as $row) {
           print_r ($this->modelsToArrayHelper($preparedRelations, $row));
    }   
}