2012-01-03 117 views
0

我的腳本運行着我們的內存時遇到了連續的問題。當大量數據被批量寫入文件時,php腳本內存不足

我需要腳本循環訪問數據庫中的每個客戶,然後獲取所有產品數據並生成文本文件。每個客戶可以擁有1到100,000個產品。

我以1,000批爲單位顯示產品數據並寫入文件以嘗試停止腳本超時。這已經得到了很大的改善,但是,我仍然遇到有大量產品的客戶問題。對於擁有5000多種產品的客戶來說,這似乎有問題。

它似乎停止在第5批次(5,000 prods)後寫入文件,但瀏覽器掛起,好像它仍在生成文件,但文件中的產品no不會增加。

任何人都可以幫忙嗎?

set_time_limit(0); 

$db = new msSqlConnect('db'); 

$select = "SELECT customer FROM feeds "; 

$run = mssql_query($select); 

while($row = mssql_fetch_array($run)){ 
    $arg = $row['customer']; 
    $txt_file = 'shopkeeper/'. $arg . '.txt'; 
    $generated = generateFeed($db, $arg, $txt_file); 

    if ($generated){ 
     $update = "UPDATE feeds SET lastGenerated = '$generated' WHERE customer = '$arg' "; 
     mssql_query($update); 
    } 

} 

function generateFeed($db, $customer, $file){ 
    //if file already exists then delete file so can write new file 
    if (file_exists($file)){ 
     unlink($file); 
    } 

    $datafeed_separator = "|"; 

    //get product details  
    $productsObj = new Products($db, customer) 

    //find out how many products customer has 
    $countProds = $productsObj->countProducts(); 

    $productBatchLimit = 1000;   

     //create new file 
    $fh = fopen($file, 'a'); 

    $counter = 1; 

    for ($i = 0; $i < $countProds; $i += $productBatchLimit) { 

     $txt = ''; 

     $limit = $productBatchLimit*$counter; 

     $products = $productsObj->getProducts($i, $limit);  

      foreach($products as $product){ 

        $txt .= 
        $prod_name . $datafeed_separator . 
        $prod_brand . $datafeed_separator . 
        $prod_desc . $datafeed_separator . 
        $prod_price . $datafeed_separator . "\n"; 
       } 
      } 

     fwrite($fh, $txt); 
     flush(); 
     $counter++;  
    } 
    fclose($fh); 

    $endTime = date('Y-m-d H:i:s'); 

    return $endTime; 
} 
+3

也許你最好不要從瀏覽器運行這個腳本,而是從命令行運行? – 2012-01-03 13:41:32

+0

是的我也試過這個,它的行爲完全一樣。 – LeeTee 2012-01-03 13:53:15

+0

對於CLI,應將超時硬編碼爲「0」,即永不超時。你是否收到錯誤信息?你有沒有檢查你的日誌?也許你正在耗盡記憶,而不是時間。 – 2012-01-03 13:55:15

回答

1

我可以看到一個東西,可能你的內存使用幫助。如果你在foreach循環中移動fwrite(),你可以在循環中釋放$ txt。所以它會是這樣的:

foreach($products as $product){ 
    $txt = 
    $prod_name . $datafeed_separator . 
    $prod_brand . $datafeed_separator . 
    $prod_desc . $datafeed_separator . 
    $prod_price . $datafeed_separator . "\n"; 

    fwrite($fh, $txt); 
} 

這將防止$ txt增長,如果你有很多產品。

+0

應該只有1000個產品一次添加到$ txt,然後將其寫入該文件,因此我不認爲這會導致內存問題,爲什麼它只會在5000個產品之後成爲問題? – LeeTee 2012-01-03 14:47:57

相關問題