Я пытаюсь создать службу под названием DataFileParser в моем приложении Symfony, которое читает файл csv. Я изменил функцию parse моей службы для целей этого вопроса, чтобы она выглядела более простой: в моих фрагментах кода моя функция просто перебирает строки файла csv и выгружает их.
Мой DataFileParser выглядит так:
class DataFileParser
{
/**
* @param string $filename
* @param array $expectedColumns
*
* @return EntryIterator
*/
public function parse($filename, $requiredColumns, $expectedColumns)
{
$splFileObject = new \SplFileObject($filename, 'r');
$splFileObject->setFlags(\SplFileObject::READ_CSV);
$splFileObject->setCsvControl(';');
foreach ($splFileObject as $line) {
var_dump($line);
}
die;
}
}
Мой CSV-файл выглядит так:
firstname;lastname;mail
john;small;[email protected]
Вывод моей функции синтаксического анализа выглядит так:
array(5) {
[0]=> string(9) "firstname"
[1]=> string(8) "lastname"
[2]=> string(9) "mail john"
[3]=> string(5) "small"
[4]=> string(23) "[email protected]"
}
Как вы можете видеть в индексе №2, SplFileObject не определяет конец строки между последним заголовком «mail» и строкой «john», поскольку он печатает [2]=> string(9) "mail john", тогда как я ожидал следующего
[2]=> string(4) "mail"
[2]=> string(4) "john"
Если я использую функцию дампа компонента var_dumper в Symfony вместо var_dump, я получаю следующее
array:5 [▼
0 => "firstname"
1 => "lastname"
2 => "mail\rjohn"
3 => "small"
4 => "[email protected]"
]
Как видите, SplFileObject не определяет \r как конец первой строки.
Если я вручную установил для параметра PHP 'auto_detect_line_endings' значение true, вызвав ini_set('auto_detect_line_endings',true); перед конструктором SplFileObject, тогда он будет работать нормально, и я получу следующий результат (правильный) с функцией дампа.
array:3 [▼
0 => "firstname"
1 => "lastname"
2 => "mail"
]
array:3 [▼
0 => "john"
1 => "small"
2 => "[email protected]"
]
И последнее: параметр $filename моей функции синтаксического анализа является экземпляром класса Symfony\Component\HttpFoundation\File\UploadedFile. Моя операционная система - Mac OS X El Capitan, я использую MAMP с PHP версии 7.1.8, и я использую PhpStorm для редактирования файла CSV (я проверил свою конфигурацию PhpStorm на предмет стиля кодирования и уже установил \n в качестве разделителя строк).
Как я могу настроить SPLFileObject для обнаружения \r как разрыва строки без необходимости изменять PHP-переменную auto_detect_line_endings? А также обнаружение всех типов разрывов строк (\r, \n, \n\r) во всех операционных системах в качестве разрывов строк?
(PS: Возможно, это проблема с моим редактором PhpStorm, поскольку я не могу понять, как вставить \n с помощью клавиши ввода. Итак, если кто-нибудь знает, почему мой PhpStorm не вставляет \n вместо \r, хотя я определил \n как разделитель строк , Буду рад поделиться знаниями).
Снимок экрана PHPStorm Конфигурация разрыва строки:
1) «Я проверил свою конфигурацию PhpStorm на предмет стиля кодирования и уже установил \ n в качестве разделителя строк» Где? Скриншот пожалуйста. 2) Вы создали этот файл в PhpStorm .. или это был какой-то существующий файл / созданный где-то еще? 3) Я спрашиваю, потому что вариант, который вы использовали (по крайней мере, я так думаю), влияет только на вновь созданные файлы внутри IDE. Для существующих файлов вам необходимо вручную изменить окончание строки для каждого файла (например, см. stackoverflow.com/a/21281924/783119 или stackoverflow.com/a/48423157/783119). Это означает, что ваш файл уже использует \r, поэтому IDE просто сохраняет его.
Спасибо @LazyOne за ответ. Вы были правы, на самом деле я сгенерировал csv с экспортом файла .xml в файл .csv с помощью Microsoft Excel, который поместил "\ r" вместо разрывов строк. Таким образом, PHPStorm сохранил его. Изменение File> Line Separators устранило проблему. Я также добавил снимок экрана, чтобы сообщество могло ответить на мой вопрос.
@MacBooc Я ценю вашу помощь и благодарю вас. К сожалению, предоставленное вами решение не сработало.






вместо установки флага вы можете сделать это по строке за строкой: secure.php.net/manual/fr/splfileobject.fgetcsv.php