2012-03-02 2 views
0

Я использую текущий код для чтения файла CSV и добавить его в массив:Использования FSEEK начать чтение CSV после определенного количества строк

echo "starting CSV import<br>"; 
    $current_row = 1; 
    $handle = fopen($csv, "r"); 
    while (($data = fgetcsv($handle, 10000, ",")) !== FALSE) 
    { 
     $number_of_fields = count($data); 
     if ($current_row == 1) { 
     //Header line 
      for ($c=0; $c < $number_of_fields; $c++) 
      { 
       $header_array[$c] = $data[$c]; 
      } 
     } else { 
     //Data line 
      for ($c=0; $c < $number_of_fields; $c++) 
      { 
       $data_array[$header_array[$c]] = $data[$c]; 
      } 

      array_push($products, $data_array); 

     } 
     $current_row++; 
    } 
    fclose($handle); 
    echo "finished CSV import <br>"; 

Однако при использовании очень большой CSV этот раза на сервере или имеет ошибку ограничения памяти.

Я хотел бы способ сделать это в несколько этапов, поэтому после первого скажем, 100 линий будет обновлять страницу, начиная с линии 101.

я, вероятно, будет делать это с помощью мета обновления и а URL-адрес.

Мне просто нужно знать, как адаптировать этот код выше, чтобы начать с строки, о которой я рассказываю.

Я искал fseek(), но я не уверен, как реализовать это здесь.

Не могли бы вы помочь?

ответ

3

timout можно обойти с помощью

ignore_user_abort(true); 
set_time_limit(0); 

При возникновении проблем с лимитом памяти, он может быть мудрым, чтобы сделать шаг назад и посмотреть на то, что вы на самом деле делаете с вы обработки данных , Вы подталкиваете данные в базу данных? вычислить что-то из данных, но не нужно хранить фактические данные, ...

Вам действительно нужно нажать (array_push($products, $data_array);) строки в массив (для последующей обработки)? можете ли вы вместо этого напрямую обращаться к базе данных? или рассчитывать напрямую? или построить html <table> напрямую? или что бы вы ни делали, а затем там, внутри цикла while(), не вдавливая все в массив сначала?

Если вы можете выполнить обработку, я думаю, вам не нужен этот массив вообще. В противном случае вам нужно будет восстановить массив для каждого фрагмента - не решить проблему памяти один бит.

Если вам удастся изменить алгоритм обработки, чтобы тратить меньше памяти/времени, вы должны серьезно подумать над тем, что любая обработка, требующая обратного перехода к браузеру (по многим причинам производительности и безопасности ...).

В любом случае вы можете в любое время идентифицировать текущее смещение потока с помощью ftell() и повторно установить его в эту позицию, используя fseek(). Вам нужно будет передать это целое число на следующую итерацию.


Также нет необходимости для внутренних for() петель. Это должно привести к таким же результатам:

<?php 

$products = array(); 
$cols = null; 
$first = true; 

$handle = fopen($csv, "r"); 
while (($data = fgetcsv($handle, 10000, ",")) !== false) { 
    if ($first) { 
     $cols = $data; 
     $first = false; 
    } else { 
     $products[] = array_combine($cols, $data); 
    } 
} 

fclose($handle); 
echo "finished CSV import <br>"; 
+0

Это замечательно, спасибо. – Shaun

Смежные вопросы