Считать файл csv в php. Чтение нескольких файлов CSV
Я использую класс parseCSV для чтения данных из файлов csv. Это может обеспечить большую гибкость при чтении csv-файла.
это не проверено … но что-то вроде этого должно сделать трюк:
$row = 1; if (($handle = fopen("xxxxxxxxx.csv", "r")) !== FALSE) { while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { $num = count($data); echo "
$num fields in line $row:
$fp = fopen("ReadMe.csv","r") or die("can"t open file"); print "
".$csv_line[$i]." | "; } print "
Подробнее
Попробуй это….
В PHP часто бывает полезно читать CSV-файл и получать доступ к его данным. Вот где функция fgetcsv () пригодится, она будет считывать каждую строку файла CSV и присваивать каждое значение массиву ARRAY. Вы можете определить разделитель в функции, а также просмотреть документы PHP для fgetcsv () для получения дополнительных опций и примеров.
Function readCSV($csvFile){ $file_handle = fopen($csvFile, "r"); while (!feof($file_handle)) { $line_of_text = fgetcsv($file_handle, 1024); } fclose($file_handle); return $line_of_text; } // Set path to CSV file $csvFile = "test.csv"; $csv = readCSV($csvFile); echo "
"; print_r($csv); echo "";
Один лайнер для разбора CSV-файла в массив с помощью str_getcsv .
$csv = array_map("str_getcsv", file("qryWebsite.csv"));
Чтобы создать запрос базы данных, который сразу импортирует все значения в базу данных:
$query = "INSERT INTO tbl_name (a,b,c) VALUES " . implode(",", array_map(function($params) use (&$values) { $values = array_merge((array) $values, $params); return "(" . implode(",", array_fill(0, count($params), "?")) . ")"; }, $csv));
Это создаст подготовленное заявление с заполнителями вопросительных знаков, например:
INSERT INTO tbl_name (a,b,c) VALUES (?,?,?),(?,?,?),(?,?,?),(?,?,?)
А переменные $values будут одномерным массивом, который содержит значения для оператора. Одно из предостережений здесь состоит в том, что файл csv должен содержать менее 65 536 записей (максимальное количество заполнителей).
Один лайнер для разбора CSV-файла в массив
$csv = array_map("str_getcsv", file("data.csv"));
Вы можете попробовать приведенный ниже код. Он отлично подходит для меня. У меня есть комментарий, чтобы сделать его более понятным. Вы можете получить ссылку на этот код.
"; $id++; } echo "
"; fclose($handle); } //close the connection mysql_close($conn); в Entered data having id = " .$id. " successfully
"; $id++; } echo "
Congratulation all data successfully inserted
"; fclose($handle); } //close the connection mysql_close($conn);Я искал одно и то же, не используя какой-то неподдерживаемый класс PHP. Excel CSV не всегда использует разделители цитат и избегает цитат с использованием "", потому что алгоритм, вероятно, был возвращен 80 или что-то в этом роде. Посмотрев на несколько парсеров.csv в разделе комментариев на PHP.NET, я видел те, которые даже использовали обратные вызовы или код eval"d, и они либо не работали, как необходимо, либо просто не работали вообще. Итак, я написал для себя свои подпрограммы, и они работают в самой базовой конфигурации PHP. Ключи массива могут быть либо числовыми, либо именованными как поля, заданные в строке заголовка. Надеюсь это поможет.
Function SW_ImplodeCSV(array $rows, $headerrow=true, $mode="EXCEL", $fmt="2D_FIELDNAME_ARRAY") // SW_ImplodeCSV - returns 2D array as string of csv(MS Excel .CSV supported) // AUTHOR: [email protected] // RELEASED: 9/21/13 BETA { $r=1; $row=array(); $fields=array(); $csv=""; $escapes=array("\r", "\n", "\t", "\\", "\""); //two byte escape codes $escapes2=array("\r", "\n", "\t", "\\", "\""); //actual code if($mode=="EXCEL")// escape code = "" { $delim=","; $enclos="""; $rowbr="\r\n"; } else //mode=STANDARD all fields enclosed { $delim=","; $enclos="""; $rowbr="\r\n"; } $csv=""; $i=-1; $i2=0; $imax=count($rows); while($i < $imax) { // get field names if($i == -1) { $row=$rows; if($fmt=="2D_FIELDNAME_ARRAY") { $i2=0; $i2max=count($row); while(list($k, $v) = each($row)) { $fields[$i2]=$k; $i2++; } } else //if($fmt="2D_NUMBERED_ARRAY") { $i2=0; $i2max=(count($rows)); while($i2<$i2max) { $fields[$i2]=$i2; $i2++; } } if($headerrow==true) { $row=$fields; } else { $i=0; $row=$rows;} } else { $row=$rows[$i]; } $i2=0; $i2max=count($row); while($i2 < $i2max)// numeric loop (order really matters here) //while(list($k, $v) = each($row)) { if($i2 != 0) $csv=$csv.$delim; $v=$row[$fields[$i2]]; if($mode=="EXCEL") //EXCEL 2quote escapes { $newv = """.(str_replace(""", """", $v))."""; } else //STANDARD { $newv = """.(str_replace($escapes2, $escapes, $v))."""; } $csv=$csv.$newv; $i2++; } $csv=$csv."\r\n"; $i++; } return $csv; } function SW_ExplodeCSV($csv, $headerrow=true, $mode="EXCEL", $fmt="2D_FIELDNAME_ARRAY") { // SW_ExplodeCSV - parses CSV into 2D array(MS Excel .CSV supported) // AUTHOR: [email protected] // RELEASED: 9/21/13 BETA //SWMessage("SW_ExplodeCSV() - CALLED HERE -"); $rows=array(); $row=array(); $fields=array();// rows = array of arrays //escape code = "\" $escapes=array("\r", "\n", "\t", "\\", "\""); //two byte escape codes $escapes2=array("\r", "\n", "\t", "\\", "\""); //actual code if($mode=="EXCEL") {// escape code = "" $delim=","; $enclos="""; $esc_enclos=""""; $rowbr="\r\n"; } else //mode=STANDARD {// all fields enclosed $delim=","; $enclos="""; $rowbr="\r\n"; } $indxf=0; $indxl=0; $encindxf=0; $encindxl=0; $enc=0; $enc1=0; $enc2=0; $brk1=0; $rowindxf=0; $rowindxl=0; $encflg=0; $rowcnt=0; $colcnt=0; $rowflg=0; $colflg=0; $cell=""; $headerflg=0; $quotedflg=0; $i=0; $i2=0; $imax=strlen($csv); while($indxf < $imax) { //find first *possible* cell delimiters $indxl=strpos($csv, $delim, $indxf); if($indxl===false) { $indxl=$imax; } $encindxf=strpos($csv, $enclos, $indxf); if($encindxf===false) { $encindxf=$imax; }//first open quote $rowindxl=strpos($csv, $rowbr, $indxf); if($rowindxl===false) { $rowindxl=$imax; } if(($encindxf>$indxl)||($encindxf>$rowindxl)) { $quoteflg=0; $encindxf=$imax; $encindxl=$imax; if($rowindxl<$indxl) { $indxl=$rowindxl; $rowflg=1; } } else { //find cell enclosure area (and real cell delimiter) $quoteflg=1; $enc=$encindxf; while($enc<$indxl) //$enc = next open quote {// loop till unquoted delim. is found $enc=strpos($csv, $enclos, $enc+1); if($enc===false) { $enc=$imax; }//close quote $encindxl=$enc; //last close quote $indxl=strpos($csv, $delim, $enc+1); if($indxl===false) { $indxl=$imax; }//last delim. $enc=strpos($csv, $enclos, $enc+1); if($enc===false) { $enc=$imax; }//open quote if(($indxl==$imax)||($enc==$imax)) break; } $rowindxl=strpos($csv, $rowbr, $enc+1); if($rowindxl===false) { $rowindxl=$imax; } if($rowindxl<$indxl) { $indxl=$rowindxl; $rowflg=1; } } if($quoteflg==0) { //no enclosured content - take as is $colflg=1; //get cell // $cell=substr($csv, $indxf, ($indxl-$indxf)-1); $cell=substr($csv, $indxf, ($indxl-$indxf)); } else// if($rowindxl > $encindxf) { // cell enclosed $colflg=1; //get cell - decode cell content $cell=substr($csv, $encindxf+1, ($encindxl-$encindxf)-1); if($mode=="EXCEL") //remove EXCEL 2quote escapes { $cell=str_replace($esc_enclos, $enclos, $cell); } else //remove STANDARD esc. sceme { $cell=str_replace($escapes, $escapes2, $cell); } } if($colflg) {// read cell into array if(($fmt=="2D_FIELDNAME_ARRAY") && ($headerflg==1)) { $row[$fields[$colcnt]]=$cell; } else if(($fmt=="2D_NUMBERED_ARRAY")||($headerflg==0)) { $row[$colcnt]=$cell; } //$rows[$rowcnt][$colcnt] = $cell; $colcnt++; $colflg=0; $cell=""; $indxf=$indxl+1;//strlen($delim); } if($rowflg) {// read row into big array if(($headerrow) && ($headerflg==0)) { $fields=$row; $row=array(); $headerflg=1; } else { $rows[$rowcnt]=$row; $row=array(); $rowcnt++; } $colcnt=0; $rowflg=0; $cell=""; $rowindxf=$rowindxl+2;//strlen($rowbr); $indxf=$rowindxf; } $i++; //SWMessage("SW_ExplodeCSV() - colcnt = ".$colcnt." rowcnt = ".$rowcnt." indxf = ".$indxf." indxl = ".$indxl." rowindxf = ".$rowindxf); //if($i>20) break; } return $rows; }
Bob теперь может вернуться к своим речам
Разберём ещё несколько практических задач из области разработки PHP парсеров, связанных с импортом, сортировкой и экспортом CSV данных. Часто требуется представить результаты парсинга в виде CSV файла, далее такой файл можно импортировать в базу данных сайта. Средства импорта CSV данных часто поддерживаются стандартными средствами различных CMS.
CSV (Comma-Separated Values ) — текстовый формат, предназначенный для представления табличных данных. Из названия следует, что данные разделены запятыми, но могут использоваться и другие разделители, например, точка с запятой (DSV формат).
CSV файлы можно открывать разными текстовыми редакторами, а также программой EXCEL. Но бывают проблемы с кодировкой. Например, EXCEL плохо переваривает UTF-8 без BOM. Под EXCEL нужно данные просто в UTF-8 сохранять.
В тестовой задаче нам нужно отсортировать ряд CSV файлов по столбцу email. Файлы содержат списки организаций с различными контактными данными, при этом не у всех фирм есть электронная почта. Так, чтобы облегчить работу со списками удобно скриптом отсортировать списки и наверх поставить компании с известными почтовыми ящиками.
Скрипт index.php и каталог с входными данными следует разместитьть в папке csv-sorter .
Обработанные файлы будут записываться в директорию output .
Импорт и экспорт CSV данных на PHP
Листинг файла index.php
Сортировка CSV файлов
count($row)) { $difference = count($header) - count($row); for ($i = 1; $i <= $difference; $i++) { $row = ""; } } } if($row != "sep=") { $data = $row; } } fclose($handle); } return $data; } /** * Функция сортировки массива по 1-му полю или N полей * * @param string|array $keys, string $order * * @return int */ function sort_arr_ncol($keys, $order = "ASC") { $order = ($order == "DESC") ? -1: 1; if(is_array($keys)) { //если сортировка по нескольким полям return function($a, $b) use ($keys, $order) { foreach($keys as $k) { if($a[$k] != $b[$k]) { return $order * (($a[$k] < $b[$k]) ? 1: -1); } } return 0; }; } else { //если сортировка по одному полю return function($a, $b) use ($keys, $order) { if ($a[$keys] == $b[$keys]) { return 0; } return $order * (($a[$keys] < $b[$keys]) ? 1: -1); }; } } /** * Функция преобразования массива в строку в CSV формате * * @param @param string $input, int $file_size, string $delimiter, string $enclosure * * @return string */ function str_putcsv($input, $file_size, $delimiter = ";", $enclosure = """) { // Open a memory "file" for read/write... $fp = fopen("php://temp", "r+"); // ... write the $input array to the "file" using fputcsv()... fputcsv($fp, $input, $delimiter, $enclosure); // ... rewind the "file" so we can read what we just wrote... rewind($fp); // ... read the entire line into a variable... $data = stream_get_contents($fp); // ... close the "file"... fclose($fp); // ... and return the $data to the caller, with the trailing newline from fgets() removed. return $data; //rtrim($data, "\r"); } // Параметры сортировщика $data_dir_name = "input"; // Каталог с исходными файлами $res_dir_name = "output"; // Каталог с отсортированными файлами $key_list_str = "email"; // Название столбца для сортировки (с нуля) if(!empty($_REQUEST["action"]) && $_REQUEST["action"] = "run") { if(!isset($_REQUEST["charset"])) { $charset = "no"; } else { $charset = $_REQUEST["charset"]; } $k = 0; $er = 0; $error_file_names = array(); $all_file_count = 0; $entries = scandir($data_dir_name); foreach($entries as $entry) { if(mb_strpos($entry, ".csv") !== false) { // Обрабатываем только CSV файлы $filepath_in = $data_dir_name . "/" . $entry; $file_size = filesize($filepath_in); $csv_data_arr = csv2array($filepath_in, $file_size); $header_arr = array_shift($csv_data_arr); $key_list = array_keys($header_arr, $key_list_str); usort($csv_data_arr, sort_arr_ncol($key_list, "ASC")); $csv_data_arr = array_merge($header_arr, $csv_data_arr); // Формируем строку для CSV файла $res_csv_file = ""; foreach($csv_data_arr as $key_row => $csv_data_arr_row) { $res_csv_file .= str_putcsv($csv_data_arr_row, $file_size); } if($charset == "yes") { $res_csv_file = iconv("WINDOWS-1251", "UTF-8", $res_csv_file); if($res_csv_file == false) { $res_csv_file = iconv("WINDOWS-1251", "UTF-8//IGNORE", $res_csv_file); $error_file_names = $entry; } } $filepath_out = $res_dir_name . "/" . $entry; file_put_contents($filepath_out, $res_csv_file) ? $k++ : $er++; $all_file_count++; } } echo "" . implode("
", $error_file_names) . "