2017-02-11 7 views
0

Я разрабатываю приложение, которое должно читать большие файлы CSV и данные процесса. Это будет невозможно сделать в одном запросе, потому что обработка данных также требует времени, это не просто чтение.PHP: Как читать файл csv по частям с использованием запроса AJAX

Так что я пытался до сих пор, и что работает хорошо до сих пор является следующее:

// Open file 
$handle = fopen($file, 'r'); 

// Move pointer to a place where it stopped last time 
fseek($handle, $offset); 

// Read limited line and process 
for ($i = 0; $i < $limit; $i++) { 
    // Get length of line for offset purposes 
    $newlength = strlen(fgets($handle)); 

    // Move pointer back. fgets moves pointer so we move it back for fgetcsv to get that line again 
    fseek($handle, $offset); 

    $line = fgetcsv($handle, 0, $csv_delimiter); 

    // Process data here 

    // Save offset 
    $offset += $newlength; 
} 

Так что проблема здесь, на этой линии:

$newlength = strlen(fgets($handle)); 

Это терпит неудачу, когда столбец CSV имеет разрывы строк.

Я также пробовал $newlength = strlen(implode(';', fgetcsv($handle, 0, $csv_delimiter)));, но это не всегда работает. Обычно это заканчивается неудачей для нескольких персонажей. Вероятно, цитаты и конец строки здесь неправильно обрабатываются.

Все, что мне нужно, это получить длину строки csv, а не только одну строку, но csv-строку, которая может иметь разрывы строк в кавычках.

У кого-нибудь есть лучшее решение?

+0

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

+0

Это не связано с моим вопросом. Крон станет следующей. Сначала мне нужно исправить скрипт для обработки данных. – Jamol

ответ

2

сделать одну вещь, создать один MySQL временную таблицу с именем «my_csv_data», и добавить одно поле в этой таблице со всеми полями, которые находятся в CSV-файл и дополнительные добавить один «is_processed» с перечислением (0,1) значение по умолчанию '0'.

Теперь импортируйте все данные csv в эту таблицу sql. для одиночной вставки никогда не потребуется больше времени.

сейчас cerate одна функция/файл, который получает доступ к таблице my_csv_data 10 или 100 записей, где is_processed = '0', и обрабатывать его, и если процесс завершен успешно, обновите поле is_processed до '1'.

сейчас создайте один cronjob, который попал в этот файл/функцию. периодически.

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

0

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

if($_FILES["file"]["size"] > 0) 
        { 
         $file = fopen($filename, "r"); 
         while (($emapData = fgetcsv($file, 10000, ",")) !== FALSE) 
         { 

           $data = array(
            'reedumption_code' => $emapData[0], 
            'jb_note_id' =>$jbmoney_id, 
            'jbmoney' =>$jbamount, 
            'add_date'=>time(), 
            'modify_date'=>time(), 
            'user_id'=>0, 
            'status'=>1, 
            'assign_date'=>0, 
            'del_status'=>1, 
            'store_status'=>1 
           ); 
          $this->load->model('currency_model'); 
          $insertId = $this->currency_model->insertCSV($data); 
         } 
         fclose($file); 
         redirect('currency/add_currency?msg=Data Imported Successfully'); 
        }