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