Возврат каретки не распознан SplFileObject - PullRequest
0 голосов
/ 06 июня 2018

Я пытаюсь создать службу под названием 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;jonh.small@fakemail.com

Вывод моей функции синтаксического анализа выглядит следующим образом:

array(5) {
    [0]=> string(9) "firstname"
    [1]=> string(8) "lastname"
    [2]=> string(9) "mail john"
    [3]=> string(5) "small"
    [4]=> string(23) "jonh.small@fakemail.com"
}

Как видно из индекса № 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 => "jonh.small@fakemail.com"
]

Как вы можете видеть, 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 => "jonh.small@fakemail.com"
]

В заключение, параметр $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 Конфигурация разрыва строки:

enter image description here

...