пропустить n строк файла csv в переполнении стека

У меня есть CSV-файл, который имеет около 500000 строк. Что мне нужно сделать, это взять первые 100 строк в первом цикле и манипулировать строками (скажем, отправить первые 100 идентификаторов в API и сохранить ответ). Во втором цикле пропустите первые 100 строк (уже занятых), возьмите еще 100 строк и отправьте запрос в веб-службу. Точно так же в третьем цикле пропустите первые 200 строк, возьмите еще 100 строк и отправьте запрос в веб-службу и так далее …

Я могу взять по одной каждой строке с кодом ниже. (проверено: отлично работает)

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). Я погуглил, но не смог найти ни одного подходящего, соответствующего моим критериям. Кто-нибудь сталкивался с такой же проблемой?

Любая помощь будет оценена. Благодарю вас

0

Решение

вот решение для вас:

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

Другие решения

Вы можете использовать SplFileObject в сочетании с ->seek($start), Мы можем сделать ссылку на limit/offset отношения, которые вы бы использовали с обычной базой данных MySQL; вот пример:

$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');

Это суть этого. Замените мой код psuedo БД своим. Это позволит вам выполнить его как CRON и использовать базу данных в качестве точки взаимодействия, чтобы получить ваш limit/offset и применить его к вашей петле с seek для дальнейшего сохранения памяти.

0

По вопросам рекламы [email protected]