Я довольно хорошо знаком с функцией Strtok () в PHP, и у меня не было проблем с настройкой функции для правильной работы со строками в прошлом. Однако в настоящее время мне нужно прочитать текстовый файл .csv (что я успешно сделал), где каждая строка состоит из 6 полей, например: фамилия, имя, адрес, город, район, почтовый индекс \ r \ n <- возврат каретки и перевод строки в конце
Я должен использовать Strok (), чтобы разделить их на разделители и пометить слова как поля (то есть, last, first, address и т. Д.). Я планирую использовать ассоциативный массив, используя фамилию в качестве первичного ключа, чтобы я мог вставить данные в таблицу HTML, которая создается и работает. Моя проблема сейчас заключается в правильном разделении файла, так как в нем содержится около 200 строк, сделанных из этих 6 полей, и правильном хранении строк в виде полей для массива, поэтому в структуре данных возникают некоторые проблемы. Вот что у меня так далеко:
$inputFile = fopen("input.csv","r");
$delimiters = ",";
$token = strtok($inputFile, $delimiters);
$n=1;
while ($token){
echo "Token $n: $token <br>";
$token = strtok($delimiters);
$n++;
}
Очевидно, таблица создается под ней, но, поскольку я еще не выполнил структуру данных, у меня нет полей для нее. Я думаю, что мой цикл токенов может быть неправильным для этой проблемы, но я взял некоторые из более раннего примера в своей книге и упражнения, которые я выполнял, где мой процесс токенов работал, но структура файла была другой. Спасибо за любое направление или помощь в этом.
В PHP есть функции CSV, такие как fgetcsv
, так что это действительно неправильный подход, чтобы заново изобрести колесо.
Обратите внимание, что в вашем коде вы фактически не читаете содержимое файла, так как вы получаете только указатель файла.
Если вам действительно нужно сделать это с strtok
, и ваш CSV прост, в том смысле, что в нем нет строк в кавычках, которые могут содержать встроенные символы-разделители, вы можете использовать:
file_get_contents()
читать содержимое файла в одну строку. Конечно, file()
сделает это проще для вас, так как это уже разделит линии. Но я предполагаю, что если функции CSV вам недопустимы, то и этого не будет.
strtok
для получения полей, но в конце цикла, а не в начале, так как первоначальный вызов с двойными аргументами уже получает первое значение перед циклом.
Код:
$input = file_get_contents("input.csv");
$delimiters = ",\n\r";
$token = strtok($input, $delimiters);
$result = [];
$row = [];
while ($token){
echo "Token $token <br>";
$row[] = $token;
if (count($row) == 6) { // write record
$result[] = $row;
$row = [];
}
$token = str_replace('\r', '', strtok($delimiters));
}
print_r($result);
Обратите внимание, что это не создает ассоциативный массив. Если вам это нужно, используйте этот код:
$columns = ['last', 'first', 'address1', 'address2', 'address3', 'zip'];
а затем в вашей петле, заменить $row[] = $token
от:
$row[$columns[count($row)]] = $token;
Вы можете увидеть, что версия работает на eval.in. Вывод данных, которые вы указали в комментариях:
Array (
[0] => Array (
[last] => SELBY
[first] => AARON
[address1] => 1519 Santiago de los Caballeros Loop
[address2] => Mwene-Ditu
[address3] => East Kasai
[zip] => 22025
)
[1] => Array (
[last] => GOOCH
[first] => ADAM
[address1] => 230 Urawa Drive
[address2] => Adoni
[address3] => Andhra Pradesh
[zip] => 2738
)
)
Опять же, это не рекомендуется. Вы должны использовать fgetcsv
. Это также лучше работает со строками, которые могут содержать запятые, двойные кавычки или даже переводы строк.
Ну, я собирался пропустить этот вопрос, потому что fgetcsv (), но мне было скучно
$lines = file($inputFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$delimiters = ",";
foreach($lines as $line) {
$values = array(strtok($line, $delimiters));
while($token = strtok($delimiters)){
$values[] = $token;
}
$result[] = $values;
}
Я добавил array_combine()
потому что вы сказали что-то об ассоциативном массиве. Вы можете использовать что-то вроде этого при необходимости:
$result[] = array_combine(array('last name',
'first name',
'address',
'city',
'district',
'postal code'), $values);
Если бы вы хотели Фамилия быть ключом для каждой строки результатов, что не рекомендуется, поскольку ключи уникальны, и я не думаю, что вы можете гарантировать уникальность фамилий:
$result[$values[0]] = $values;
//or to remove it from the array but use as the key
$result[array_unshift($values)] = $values;