2016-04-15 55 views
0

我的Yii框架上的PHP腳本存在內存不足問題。我試圖做一些調試。我使用的是CDataProviderIterator因爲Yii的文件說,這一下:PHP內存不足與CDataProviderIterator(Yii)

例如,下面的代碼將所有註冊用戶(活動記錄類用戶)遍歷不會耗盡內存,即使有幾百萬的數據庫中的用戶。

該代碼迭代了大約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; 
} 
+0

快速修復,而我嘗試重新創建此 ini_set('memory_limit','-1'); – Midhun

+0

你正在將$ iterator轉換爲一個數組,所以它需要更多的內存! 我認爲這是什麼導致問題 – Midhun

+0

你解決了這個問題嗎? – Midhun

回答

1

我相信你試圖將CDataProviderIterator轉換爲Php數組。 所以用於放置數組,你需要更多的內存

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

這臺使用RAM來最大使用

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

這臺內存使用512MB的

可以使你的代碼像這樣只是爲了確保你沒有使用太多內存

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

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

+0

所以我不想將CDataProviderIterator轉換爲一個php數組。我將它迭代的每條記錄轉換爲一個數組。實際上,這應該保留內存,因爲CDataProviderIterator不會將所有對象存儲在內存中。在我的情況下,它一次只能在內存中存儲200個模型對象,然後它將放棄它們。我試過你的解決方案,現在我只是沒有得到迴應。我的主要問題是,爲什麼在現實中它佔用了太多的內存,它應該佔用較少的內存,基於文檔中的索賠。 – Sloganho

+1

因爲它看起來像你試圖在$ model_as_array中存儲150萬個數組 – georaldc

+0

是的,我可以看到,但你在做什麼$ model_as_array; – Midhun