Обычно, если стоимость создания интернет магазина достаточно высока или имеет большое количество товаров, заказчики просят сделать импорт товаров из их прайс листов. PHP как известно, не умеет работать с Excel-файлами стандартными средствами. Конечно есть множество различных классов и библиотек, которые могут читать и записывать информацию в Excel, но с ними возникает достаточно много проблем и неудобств. Гораздо проще и удобнее работать с CSV-файлами. Предлагаю разобрать простой способ чтения и записи данных в CSV-файл средствами PHP.
Как Вы знаете, CSV — текстовый формат, предназначенный для представления табличных данных. Каждая строка файла — это одна строка таблицы. Значения отдельных колонок разделяются разделительным символом — обычно запятой (,).
Как это работает?
Пример записи данных
Первым делом мы формируем двумерный массив значений $list. Функция fopen()закрепляет именованный ресурс, указанный в аргументе filename, за потоком, а также указываем режим работы с файлом. Со списком режимов работы с файлом Вы можете ознакомиться в конце статьи.
Запись в файл производится построчно, поэтому имея двумерный массив мы вызываем функцию записи fputcsv() в цикле.Функция fputcsv() форматирует строку (переданную в виде массива) в виде CSV и записывает её (заканчивая переводом строки) в указанный файл. Как видите, в этой функции мы указываем файл $fp, в который производим запись, строку $fields, которая содержит значения полей, а также такие параметры, как разделитель полей (в нашем случае это точка с запятой) и ограничитель полей (у нас это двойная кавычка).
После окончания записи, не забываем закрывать дескриптор файла fclose().
Пример чтения данных
С помощью функции fopen() мы пытаемся открыть файл для чтения и, если он есть, построчно заполняем массив данными с помощью функции fgetcsv(). Функция fgetcsv() читает строку из файла и производит разбор данных CSV. Данная функция похожа на функцию fgets(), с той разницей, что она производит анализ строки на наличие записей в формате CSV и возвращает найденные поля в качестве массива. В эту функцию мы передаем такие параметры как корректный файловый указатель на успешно открытый файл, длину строки (обычно указывается длина большая самой длинной строки в файле, в нашем случае мы указываем 0, т.е. длина не ограничена), а также разделитель поля (т.к. в примере для записи мы использовали точку с запятой, то и для чтения будем использовать её).
И опять же, после выполнения чтения из файла не забываем закрывать дескриптор файла fclose().
Список возможных режимов для fopen()
‘r’ — Открывает файл только для чтения; помещает указатель в начало файла.
‘r+’ — Окрывает файл для чтения и записи; помещяет указатель в начало файла.
‘w’ — Открывает файл только для записи; помещает указатель в начало файла и обрезает файл до нулевой длинны. Если файл не существует — пробует его создать.
‘w+’ — Открывает файл для чтения и записи; помещает указатель в начало файла и обрезает файл до нулевой длинны. Если файл не существует — пробует его создать.
‘a’ — Открывает файл только для записи; помещает указатель в конец файла. Если файл не существует — пробует его создать.
‘a+’ — Открывает файл для чтения и записи; помещает указатель в конец файла. Если файл не существует — пробует его создать.
‘x’ — Создаёт и открывает только для записи; помещает указатель в начало файла. Если файл уже существует, вызов fopen() закончится неудачей, вернёт FALSE и выдаст предупреждение уровня E_WARNING. Если файл не существует, пытается его создать.
‘x+’ — Создаёт и открывает для чтения и записи; помещает указатель в начало файла. Если файл уже существует, вызов fopen() закончится неудачей, вернёт FALSE и выдаст предупреждение уровня E_WARNING. Если файл не существует, пытается его создать.
Как видите, мы разобрали лишь теорию, но если вынести чтение из файла и запись в файл отдельными функциями, правильно организовать обработку ошибок, то можно реализовать неплохой функционал по импорту/экспорту товаров в свой интернет магазин с возможностью добавления новых товаров и обновления имеющихся. Самое главное, не забывайте про кодировку импортируемых/экспортируемых данных, а также правильно выбирайте разделитель поля, т.к. бывают ситуации, когда выбранный разделитель может встретиться просто в тексте, который Вы пытаетесь сохранить в CSV-файл, в результате чего все данные в такой строке могут отображаться некорректно.
blog-about.ru
to get an array with data from the MS Excel csv format (separated by ; and with string wich contains ; or " optionally delimited by " )
function getcsvxls($buffer)
{
$buffer = str_replace('""', '"', $buffer);
$n = strlen($buffer);
$i = $line = 0;
$del = false;
while($i < $n)
{
$part = substr($buffer, $i);
if(
(substr($part, 0, 1) == ';' && !$del) ||
(substr($part, 0, 2) == '";' && $del)
)
{
$i ++;
if($del)
{
$str = substr($str, 1, strlen($str) - 1);
$i ++;
}
$data[$line][] = $str;
$del = false;
$str = '';
} else if(substr($part, 0, 2) == "rn")
{
$data[$line][] = $str;
$str = '';
$del = false;
$line ++;
$i += 2;
} else
{
if($part[0] == '"')
$del = true;
$str .= $part[0];
$i ++;
}
}
return $data;
}
php.svchat.ru
Используя fgetcsv
, могу ли я каким-то образом сделать деструктивное чтение, где строки, которые я прочитал и обработал, будут отброшены, поэтому, если я не пройду через весь файл в первый проход, я могу вернуться и забрать, где я остановился раньше
the script timed out
?
Дополнительные детали:
- fgetcsv () игнорирует специальные символы, когда они находятся в начале строки!
- Как AUTOINCREMENT, начиная с определенного количества / смещения?
- Как получить полный путь к файлу при загрузке файлов в PHP?
- Получить ассоциативный массив из csv
- PHP Анализ файла .dat
Я получаю ежедневный фид продуктов от поставщика, который встречается как файл размером 200 МБ. Когда я распаковываю файл, он превращается в 1.5gb .csv с почти 500 000 строк и 20-25 полей.
x41C;не нужно прочитать эту информацию в MySQL db, в идеале с PHP, поэтому я могу запланировать CRON для запуска скрипта на моем веб-хостинге каждый день.
У меня есть жесткий тайм-аут на сервере, установленный на 180 секунд хостинг-провайдером, и максимальный максимальный объем использования памяти 128 МБ для любого отдельного скрипта.
x42D;ти ограничения меня не могут изменить.
Моя идея состояла в том, чтобы захватить информацию из .csv, используя функцию fgetcsv, но я ожидаю, что вам придется пройти несколько проходо&.
;льку я обрабатываю его, поэтому мне не нужно будет проводить циклы, пропускающие строки, которые уже обрабатывались в предыдущем проходе.
ruphp.com
Функция Fgetcsv читает строку из файла и производит разбор данных CSV.
array fgetcsv( resource $handle [, int $length = 0 [, string $delimiter = "," [, string $enclosure = '"' [, string $escape = "" ]]]] )
Функция Fgetcsv похожа на функцию Fgets, с той разницей, что она производит анализ строки на наличие записей в формате CSV и возвращает найденные поля в качестве массива.
Параметр Handle являет собой корректный файловый указатель на файл, успешно открытый при помощи Fopen, Popen или Fsockopen.
Параметр Length должен быть больше самой длинной строки (в символах), найденной в CSV-файле (включая завершающий символ конца строки). В противном случае, строка будет разбита на куски длиной в Length символов если только место разрыва не будет внутри ограничителей полей (Enclosure).
Необязательный параметр Delimiter устанавливает разделитель поля (только один символ).
Необязательный параметр Enclosure устанавливает символ ограничителя поля (только один символ).
Необязательный параметр Escape устанавливает экранирующий символ (только один символ).
Функция Fgetcsv возвращает индексированный массив с прочтенными полями или NULL, если передается неверный параметр Handle, или FALSE при других ошибках, в том числе и по достижении конца файла.
Пустая строка CSV-файла будет возвращена в качестве массива, содержащего единственный элемент NULL, ошибки в данном случае не возникнет.
Очень много фирм, организаций, и т.д. в своей работе используют расширение Microsoft Office — EXEL. В одних, в Exel сохраняются продукция, в других информация о товарах, пользователях, цены, или даже просто номера телефонов. Бывает необходимость эти данные перенести в другую базу данных, например для WEB.
Для начала, нужно открыть Ваш файл Exel с расширением .XLS. Потом сохранить его как .CSV. Теперь его можно использовать и в веб приложениях. Этот же файл можно открыть любим редактором, например Total comander, и вы увидите его содержимое. Если же открыть также XLS файл, то будут видны только множество неразборчивого и непонятного кода.
Также можно преобразовывать в CSV файли и таблицы из Microsoft Office и OpenOffice Writer.
Для OpenOffice Writer делается это следующим образом:
1. Создаем таблицу.
2. Выбираем в меню «Таблица» -> «Преобразовать» —> «Таблицу в текст».
3. Указываем разделитель текста, например «@» и подтверждаем действие нажатием на кнопку Ok.
4. Выбираем «Файл» —> «Сохранить как» —> «Тип файла: текст (.txt)» и сохраняем с названием, например test.txt.
5. Последнее что нужно сделать, это переименовать test.txt в test.csv.
Вот теперь мы создали файл, который доступен для импорта в скрипт PHP:
// открываем файл для чтения
$fh = fopen( 'test.csv', 'r' );
// читаем строку из файла и производим разбор данных CSV
$info = fgetcsv( $fh, 1000, "@" );
// выводим масив результат
print_r( $info );
// закрываем файл
fclose( $fh );
Результатом выполнения будет первая строка таблицы.
Для того, чтоб прочитать весь файл CSV, можно использовать цикл While:
// открываем файл для чтения
$fh = fopen( 'test.csv', 'r' );
while ( ( $info = fgetcsv( $fh, 1000, "@" ) ) !== false ) {
// выводим масив результат
print_r( $info );
}
// закрываем файл
fclose( $fh );
Для того, чтоб обратиться к каждому отдельному элементу, можно воспользоваться языковой конструкцией List:
// открываем файл для чтения
$fh = fopen( 'test.csv', 'r' );
while ( ( $info = fgetcsv( $fh, 1000, "@" ) ) !== false ) {
// сохнаряем значения массива в переменные
list( $var1, $var2 ) = $info;
}
// закрываем файл
fclose( $fh );
Благодаря функции Fgetcsv можно обработать большое количество данных из таблиц.
profiphp.ru
Старый вопрос, но все еще актуальный для пользователей PHP 5.2. str_getcsv доступен из PHP 5.3. Я написал небольшую функцию, которая работает с самим fgetcsv.
Ниже приведена моя функция из https://gist.github.com/4152628:
function parse_csv_file($csvfile) { $csv = Array(); $rowcount = 0; if (($handle = fopen($csvfile, "r")) !== FALSE) { $max_line_length = defined('MAX_LINE_LENGTH') ? MAX_LINE_LENGTH : 10000; $header = fgetcsv($handle, $max_line_length); $header_colcount = count($header); while (($row = fgetcsv($handle, $max_line_length)) !== FALSE) { $row_colcount = count($row); if ($row_colcount == $header_colcount) { $entry = array_combine($header, $row); $csv[] = $entry; } else { error_log("csvreader: Invalid number of columns at line " . ($rowcount + 2) . " (row " . ($rowcount + 1) . "). Expected=$header_colcount Got=$row_colcount"); return null; } $rowcount++; } //echo "Totally $rowcount rows foundn"; fclose($handle); } else { error_log("csvreader: Could not read CSV "$csvfile""); return null; } return $csv; }
Возвращает
Начать чтение CSV
Array ( [0] => Array ( [vid] => [agency] => [division] => Division [country] => [station] => Duty Station [unit] => Unit / Department [grade] => [funding] => Fund Code [number] => Country Office Position Number [wnumber] => Wings Position Number [title] => Position Title [tor] => Tor Text [tor_file] => [status] => [datetime] => Entry on Wings [laction] => [supervisor] => Supervisor Index Number [asupervisor] => Alternative Supervisor Index [author] => [category] => [parent] => Reporting to Which Position Number [vacant] => Status (Vacant / Filled) [index] => Index Number ) [1] => Array ( [vid] => [agency] => WFP [division] => KEN Kenya, The Republic Of [country] => [station] => Nairobi [unit] => Human Resources Officer P4 [grade] => P-4 [funding] => 5000001 [number] => 22018154 [wnumber] => [title] => Human Resources Officer P4 [tor] => [tor_file] => [status] => [datetime] => [laction] => [supervisor] => [asupervisor] => [author] => [category] => Professional [parent] => [vacant] => [index] => xxxxx ) )
qaru.site
Example of getcsv()
We will use our student table csv data.
You can read how the CSV data is prepared from the student table here.
Now the student data is available to us in a csv file
We will first open the csv file and keep the pointer
$f_pointer=fopen("student.csv","r"); // file pointer
Then we will use the pointer to loop through all the rows of the file till the end of the file is reached. Inside the loop we will use fgetcsv() to collect the array and then print the output. Here is the code.
<?php $f_pointer=fopen("student.csv","r"); // file pointer while(! feof($f_pointer)){ $ar=fgetcsv($f_pointer); echo print_r($ar); // print the array echo "<br>"; } ?>
The output is here.
Array ( [0] => 1 [1] => John Deo [2] => Four [3] => 75 [4] => female ) Array ( [0] => 2 [1] => Max Ruin [2] => Three [3] => 85 [4] => male ) Array ( [0] => 3 [1] => Arnold [2] => Three [3] => 55 [4] => male ) Array ( [0] => 4 [1] => Krish Star [2] => Four [3] => 60 [4] => female ) Array ( [0] => 5 [1] => John Mike [2] => Four [3] => 60 [4] => female ) Array ( [0] => 6 [1] => Alex John [2] => Four [3] => 55 [4] => male )
Generating a SQL file to insert records into database
Now we can separate data from the above code and using the data we will prepare series of SQL insert commands to store or add all these records to student table. Each loop will have one insert command. Here is the code.
<?php $f_pointer=fopen("student.csv","r"); // file pointer while(! feof($f_pointer)){ $ar=fgetcsv($f_pointer); $sql="INSERT INTO student(id,name,class,mark,sex)values('$ar[0]','$ar[1]','$ar[2]','$ar[3]','$ar[4]')"; echo $sql; echo "<br>"; } ?>
Part of the output is here
INSERT INTO student(id,name,class,mark,sex)values('1','John Deo','Four','75','female')
INSERT INTO student(id,name,class,mark,sex)values('2','Max Ruin','Three','85','male')
INSERT INTO student(id,name,class,mark,sex)values('3','Arnold','Three','55','male')
INSERT INTO student(id,name,class,mark,sex)values('4','Krish Star','Four','60','female')
www.plus2net.com
Import contacts from uploaded file:
<?
if (isset($_POST['add'])) {
set_time_limit(3600);
error_reporting(0);
echo '<p class="etop"> Importuję kontakty ... zaczekaj może to potrwać chwilę!</p>';
$grid = (int)$_POST['groupid'];
// from upload file
$csv = $_FILES['file']['tmp_name'];
$csvname = $_FILES['file']['name'];
$imp = 0;
$row = 1;
if (pathinfo(basename($csvname),PATHINFO_EXTENSION) == 'csv') {
if (($handle = fopen($csv, "r")) !== FALSE) {
fgetcsv($handle);
while (($row = fgetcsv($handle, 1000, ",")) !== FALSE) {
/// function with explode line and add to database
// return 1 - added, 0 - dont
$count = AddKontaktCSV($row[0], $grid);
// echo $row[0];
// ile kontaktów sie zaimportowało
$imp = $imp + $count;
}
fclose($handle);
$error1 = 'Zaimportowano '.$imp.' kontakty(ów)!';
}else{
$error1 = "Error csv";
}
}else{
$error1 = "Tylko pliki .csv";
}
// delete file
unlink($csv);
}
?>
<form method="POST" action="" enctype="multipart/form-data">
<p class="formerror"><?php echo $error1; ?></p>
<label>Nazwa grupy <span>*</span></label>
<select name="groupid">
<option value="123">Grupa 123</option>
<option value="999">Grupa 999</option>
</select>
<label>Plik csv (max. 100 000 kontaktów w pliku)*</label>
<input type="file" name="file">
<p style="font-size: 13px;"> * - pola wymagane <a href="import_kontaktow.csv" style="float: right; color: #393; font-weight: bold;"> Przykładowy plik .csv</a> </p>
<input type="submit" name="add" value="Wyślij plik .csv" class="btn">
</form>
php.net