PHP – как эффективно читать большие удаленные файлы и использовать буфер в цикле

Я хотел бы понять, как использовать буфер чтения файла.

Предполагая, что у нас есть большой файл со списком писем по строкам (разделитель классический \n )

теперь мы хотим сравнить каждую строку с каждой записью таблицы в нашей базе данных в виде проверки типа line_of_file == table_row .

это простая задача, если у вас нормальный файл, иначе, если у вас есть огромный файл, сервер обычно останавливает операцию через несколько минут.

так что лучший способ делать такие вещи с файловым буфером?

что у меня до сих пор есть что-то вроде этого:

 $buffer = file_get_contents('file.txt'); while($row = mysql_fetch_array($result)) { if ( preg_match('/'.$email.'/im',$buffer)) { echo $row_val; } } 

 $buffer = file_get_contents('file.txt'); $lines = preg_split('/\n/',$buffer); //or $lines = explode('\n',$buffer); while($row = mysql_fetch_array($result)) { if ( in_array($email,$lines)) { echo $row_val; } } 

Solutions Collecting From Web of "PHP – как эффективно читать большие удаленные файлы и использовать буфер в цикле"

Как уже было предложено в моих близких словах на ваш вопрос (отсюда CW):

Вы можете использовать SplFileObject, который реализует Iterator для итерации по файлу по очереди для сохранения памяти. См. Мои ответы на

  • Наименее интенсивный способ чтения файла в PHP и
  • Как сохранить память при чтении файла в Php?

Например.

Не используйте file_get_contents для больших файлов. Это полностью вытаскивает весь файл в память. Вы должны прочитать его на куски

 $fp = fopen('file.txt', 'r'); while(!feof($fp)){ //get onle line $buffer = fgets($fp); //do your stuff } fclose($fp); в $fp = fopen('file.txt', 'r'); while(!feof($fp)){ //get onle line $buffer = fgets($fp); //do your stuff } fclose($fp); 

Откройте файл с помощью fopen() и прочитайте его пошагово. Вероятно, одна строка за раз с fgets() .

file_get_contents читает весь файл в памяти, что нежелательно, если файл превышает несколько мегабайт

В зависимости от того, сколько времени это займет, вам может потребоваться беспокоиться о сроке выполнения PHP или о том, как отключить браузер, если он не получит какой-либо вывод в течение 2 минут.

Что вы можете попробовать:

  1. set_time_limit(0) чтобы избежать превышения времени PHP
  2. Обязательно выводить некоторые данные каждые 30 секунд или около того, чтобы браузер не отключился; убедитесь, что вы flush(); и возможно ob_flush(); поэтому ваш вывод фактически отправляется по сети (это kludge)
  3. запустите отдельный процесс (например, через exec() ), чтобы запустить это в фоновом режиме. Честно говоря, все, что занимает больше секунды или два, лучше всего использовать в фоновом режиме