[英]skip n rows of csv file in php
我有一個csv文件,其行數約為500000。 我需要做的是在第一個循環中獲取前100行並處理行(例如,將前100個ID發送給API並保存響應)。 在第二個循環中,跳過前100行(已占用),再跳過另外100行並將請求發送到Web服務。 同樣,在第三個循環中,跳過前200行,再跳過另外100行,然后將請求發送到Web服務,依此類推...
我可以用下面的代碼每行一行。 (經過測試:效果很好)
if (($handle = fopen($filename, "r")) !== FALSE) {
$id = 1;
$line = fgetcsv($handle); //skip first row
//fetch data from each row
while (($data = fgetcsv($handle, ",")) !== FALSE) {
$hotel_id = $data[0];
//call service to request to web service
$hotelDetailRequest = (new \Services\Hotel\Hotel)->getHotelStaticData($hotel_id);
//do stuff to response
}
}
同樣,我可以跳過一些初始行,就像跳過第一行添加一樣
$line = fgetcsv($handle);
$line = fgetcsv($handle);
$line = fgetcsv($handle);
但是,這不是如上所述的預期結果。 我正在使用PHP(Laravel)。 我用谷歌搜索,但找不到符合我條件的合適內容。 有沒有人遇到同樣的問題?
任何幫助,將不勝感激。 謝謝
這是為您提供的解決方案:
<?php
$filename = "the_data.csv";
$chunk_size = 200;
// parse csv file into an array
$csv_data = array_map('str_getcsv', file($filename));
// split data array into chunks
$chunked_data = array_chunk($csv_data, $chunk_size);
foreach($chunked_data as $chunk){
// here you have $chunk_size row data
// iterate in chunk
foreach($chunk as $row ){
$hotel_id = $row[0];
// send request to web service
// do stuff to response
}
sleep(1);
}
?>
您可以將SplFileObject
與->seek($start)
結合使用。 我們可以參考您將在普通MySQL數據庫中使用的limit/offset
關系。 這是一個例子:
$file = SplFileObject("myfile.csv");
$rules = DB::query("select * from file_rules where id = 1");
if ($rules->limit) {
$file->seek($rules->offset);
}
此時,您可以執行一個簡單的循環,然后將索引計數與偏移值進行比較。
foreach ($file as $index => $row ) {
if ($file->valid() && $index <= $rules->limit ) {
//perform your calls to do your API request
}
}
完成后,只需更新數據庫記錄:
DB::query('update file_rules set offset='.$rules->offset+$rules->limit.' where id =1');
這是關鍵。 用您自己的替換我的數據庫偽代碼。 這將允許你執行它作為一個cron和使用數據庫作為一個互動點,讓您的limit/offset
,並將其與應用到你的循環seek
進一步節省存儲空間。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.