PHP - strtok(),关联数组关系
PHP - strtok(), associative array relationship
我对 PHP 中的 Strtok() 函数非常熟悉,并且在过去让该函数正确处理字符串时我没有遇到任何问题。但是,我目前必须读取一个 .csv 文本文件(我已成功完成),其中每一行由 6 个字段组成,如下所示:姓氏、名字、地址、城市、地区、邮政 code\r\n < --carriage return and linefeed at the end
我必须使用 Strok() 将它们按分隔符拆分并将单词标记为字段(即最后、第一个、地址等)。我计划使用一个以姓氏作为主键的关联数组,这样我就可以将数据插入一个 HTML Table,它已创建并可以正常工作。我现在的问题是正确拆分文件,因为它有大约 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++;
}
显然,table 是在它下面创建的,但是由于我还没有完成数据结构,所以我没有它的字段。我认为我的令牌循环对于这个问题可能不正确,但我从我书中的早期示例和我所做的练习中提取了一些,其中我的令牌过程有效但文件结构不同。感谢您对此的任何指导或帮助。
好吧,我本来打算跳过这个问题的,因为 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);
如果您希望 last name 成为每个结果行的键,这是不可取的,因为键是唯一的,我认为您不能保证 last names 是唯一的:
$result[$values[0]] = $values;
//or to remove it from the array but use as the key
$result[array_unshift($values)] = $values;
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
。这也可以更好地处理可能包含逗号、双引号甚至换行符的字符串。
我对 PHP 中的 Strtok() 函数非常熟悉,并且在过去让该函数正确处理字符串时我没有遇到任何问题。但是,我目前必须读取一个 .csv 文本文件(我已成功完成),其中每一行由 6 个字段组成,如下所示:姓氏、名字、地址、城市、地区、邮政 code\r\n < --carriage return and linefeed at the end
我必须使用 Strok() 将它们按分隔符拆分并将单词标记为字段(即最后、第一个、地址等)。我计划使用一个以姓氏作为主键的关联数组,这样我就可以将数据插入一个 HTML Table,它已创建并可以正常工作。我现在的问题是正确拆分文件,因为它有大约 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++;
}
显然,table 是在它下面创建的,但是由于我还没有完成数据结构,所以我没有它的字段。我认为我的令牌循环对于这个问题可能不正确,但我从我书中的早期示例和我所做的练习中提取了一些,其中我的令牌过程有效但文件结构不同。感谢您对此的任何指导或帮助。
好吧,我本来打算跳过这个问题的,因为 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);
如果您希望 last name 成为每个结果行的键,这是不可取的,因为键是唯一的,我认为您不能保证 last names 是唯一的:
$result[$values[0]] = $values;
//or to remove it from the array but use as the key
$result[array_unshift($values)] = $values;
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
。这也可以更好地处理可能包含逗号、双引号甚至换行符的字符串。