CSV файлы на PHP — создание и чтение
CSV очень удобный формат с точки зрения генерации, поскольку он очень просто устроен. В этой заметке разберемся как устроены файлы с расширением .csv , как их создавать и разбирать (парсить) в PHP. Делается это очень просто.
Ниже приведены простые PHP функции для создания и парсинга csv файлов. Никаких библиотек - для CSV это лишнее!
- Формат CSV
- Создание CSV файла в PHP
- Чтение CSV файла в PHP
- Конвертация .lsx , .xlsx файла в .csv
Формат CSV
Чтобы понимать суть вещей, нужно разобраться в спецификации CSV файлов, как устроен формат. Давайте коротко.
CSV (Comma-Separated Values — значения, разделённые запятыми) — текстовый формат, предназначенный для представления табличных данных.
Каждая строка файла — это одна строка таблицы.
Разделителем значений колонок является символ: , (запятая). Для русского языка используется ; (точка с запятой), потому что в русском запятая используется в дробных числах.
Значения, содержащие зарезервированные символы: " , ; \r\n или \n или \r (двойная кавычка, запятая, точка с запятой, новая строка) обрамляются двойными кавычками " .
Если в значении встречаются двойные кавычки " , то они должны выглядеть как двое кавычек подряд "" .
Это все что нужно знать, чтобы работать с CSV!
Пример для рус. языка:
Пример для англ. языка:
Wiki-справка
Большинство программ под CSV понимают более общий формат DSV (delimiter-separated values — значения разделённые разделителем), допускающий использование иных символов в качестве разделителя. В частности, в русской и других локалях запятая по умолчанию зарезервирована под десятичный разделитель. Поэтому как разделитель используется точка с запятой или табуляция (формат TSV).
Сегодня под CSV понимают набор значений, разделенных какими угодно разделителями, в какой угодно кодировке с какими угодно окончаниями строк. Это значительно затрудняет перенос данных из одних программ в другие, несмотря на всю простоту формата.
Создание CSV файла в PHP
Для создания CSV файла, достаточно создать текстовый файл, используя в нужных местах необходимые разделители столбцов и строк.
Важным моментом, является кодировка файла. Для корректного отображения кириллицы следует использовать кодировку cp1251 (windows-1251).
Разделитель колонокДля русского языка символом-разделителем является ; (точка с запятой). Для англ. , (запятая).
Строки содержащие спец символы: " , ; \r\n или \n или \r должны быть в двойных кавычках "строка" .
Двойные кавычки внутри строки, нужно «очистить» поставив перед кавычкой еще одну такую же кавычку: строка "csv" превратиться в "строка ""csv""" . Обрамление в кавычки нужно, чтобы можно было внутри значений колонок использовать разделители ; , , и не переживать что что-то сломается при чтении файла.
Разделитель строкДля разделения строк в csv файлах можно использовать \r\n (возврат каретки и перенос строки, CR LF). В этом случае, если нужен перенос строки внутри значения колонки, то там используется просто \n .
Также, для разделения строки, может использоваться просто \n (перенос строки, LF). В этом случае, перенос строки внутри значения колонки должен обозначаться как \r (возврат каретки CR).
Функция для создания CSV файлаЧтение CSV файла в PHP
Когда нужно получить данные из CSV файла, т.е. разобрать его и получить данные в переменную, можно использовать встороенную в PHP функцию str_getcsv() .
Есть еще функция fgetcsv() , но она оказалась капризной и не всегда работает как нужно (может перепутать переносы строк).
Вариант на базе функции str_getcsv() :
Конвертация .lsx , .xlsx файла в .csv
Чтобы перевести Excel файл в CSV, нужно открыть его в Excel и сохранить в формате .csv :
Если такую конвертацию нужно сделать программно, смотрите в сторону онлайн конвертеров с API или готовых библиотек.
Сталкивались с такой задачей и знаете более универсальный способ? Прошу поделиться в комментариях.
Я столкнулся и потратил несколько часов перебирая всякий не универсальный «мусор» из гугла - то одно не работает, то другое, то библиотеку нужно ставить «хитро-мудрую». Так и появилась эта заметка.
До этого из: Код (коддинг)Тема, конечно, интересная. Только этот код в реальных условиях работать не будет.
Что с ним не так?
1) Разделитель поля может быть любой. Например, '\', '|' или ещё что похуже. 2) Символ ограничителя поля может быть как двойная, так и одинарная ковычка. 3) Неплохо бы использовать unset в коде. Память на сервере всё-таки не резиновая. Одно дело загрузка файла с пару сотен строк кода, а другое если их пару десятков миллионов.
1) Ты параметр $col_delimiter не увидел похоже, суй туда какой угодно разделитель!
2) Для текущего кода (обоих) это учитывается: в первом создается строка с двойной кавычкой и только. Во втором строка парсится PHP функцией str_getcsv() которая обе кавычки понимает.
3) В каком месте там unset по твоему поможет хорошо избавится от потерь памяти? Если у тебя файл выходит за пределы памяти, что редкость с текущими параметрами серверов, то это пожалуй экстра случай и подход уже нужен будет принципиально другой. Файл читать или записывать нужно будет частями или построчно, а не так целиком. По аналогии ты в ВП запихай 50 000 рубрик и все приехали, нужно будет костыли вставлять для нормальной работы. Но ВП почему-то самая популярная CMS, как же так? Я не писал код на все случаи жизни, код покрывает 80% случаев, остальное уже требует отдельного подхода, а этот код можно взять за основу.
Этот код в реальных условиях у меня работает! Может там и есть баги, но я их не встречал.
П.С. просмотрел второй код, добавил unset() маловероятно что много толку от этого, но лишним не будет.
Не "суй туда какой угодно разделитель", а все возможные разделители для csv файлов. Ты бы ещё менеджеру предложил указывать разделитель для файла, который он загружает
"с текущими параметрами серверов". Поверь, кривым кодом можно положить сервер даже с очень хорошими характеристиками. Я обычно беру за правило, если переменная больше не будет использоваться она должна умереть (или обнулиться). Когда поработаешь с хайлоудом, то начинаешь понимать цену памяти)
И вообще, если пишешь рабочую программу, нужно это делать хорошо, а не в стиле "мой первый скрипт"!