我在使用Quercus开发PHP小应用时遇到了一个棘手的问题:
- 我有一个远程csv文件,可以下载并存储在字符串中
- 为了解析该字符串,我最好使用str_getcsv函数,但是Quercus还没有这个函数
- Quercus似乎知道fgetcsv函数,但是该函数需要一个文件句柄,而我没有(由于GAE不允许创建文件)也无法创建一个新的文件句柄
有没有人有什么办法可以解决这个问题,而不必放弃内置的PHP csv-parser函数并编写自己的解析器呢?
我在使用Quercus开发PHP小应用时遇到了一个棘手的问题:
有没有人有什么办法可以解决这个问题,而不必放弃内置的PHP csv-parser函数并编写自己的解析器呢?
我认为最简单的解决方案是编写自己的解析器。这很容易,而且可以让你学习更多的正则表达式。在PHP中没有将CSV字符串转换为数组的解析器是没有意义的,因此编写自己的解析器是完全合理的。只要确保它不会太慢就可以了 ;)
这是我写的一个简单手动解析器,带有合格、非合格和转义功能的示例输入。它可以用于标题和数据行,并包含一个关联数组函数,将您的数据转换为kvp样式的数组。
//example data
$fields = strparser('"first","second","third","fourth","fifth","sixth","seventh"');
print_r(makeAssocArray($fields, strparser('"asdf","bla\"1","bl,ah2","bl,ah\"3",123,34.234,"k;jsdfj ;alsjf;"')));
//do something like this
$fields = strparser(<csvfirstline>);
foreach ($lines as $line)
$data = makeAssocArray($fields, strparser($line));
function strparser($string, $div = ",", $qual = "\"", $esc = "\\") {
$buff = "";
$data = array();
$isQual = false; //the result will be a qualifier
$inQual = false; //currently parseing inside qualifier
//itereate through string each byte
for ($i = 0; $i < strlen($string); $i++) {
switch ($string[$i]) {
case $esc:
//add next byte to buffer and skip it
$buff .= $string[$i+1];
$i++;
break;
case $qual:
//see if this is escaped qualifier
if (!$inQual) {
$isQual = true;
$inQual = true;
break;
} else {
$inQual = false; //done parseing qualifier
break;
}
case $div:
if (!$inQual) {
$data[] = $buff; //add value to data
$buff = ""; //reset buffer
break;
}
default:
$buff .= $string[$i];
}
}
//get last item as it doesnt have a divider
$data[] = $buff;
return $data;
}
function makeAssocArray($fields, $data) {
foreach ($fields as $key => $field)
$array[$field] = $data[$key];
return $array;
}
你可以使用stream_wrapper_register创建一个新的流包装器。
这里有一个手册中读取全局变量的示例:http://www.php.net/manual/en/stream.streamwrapper.example-1.php
然后你可以像使用普通文件句柄一样使用它:
$csvStr = '...';
$fp = fopen('var://csvStr', 'r+');
while ($row = fgetcsv($fp)) {
// ...
}
fclose($fp);
如果可以粗暴并快速地处理,我会只使用http://php.net/manual/en/function.exec.php来传递并使用sed和awk(http://shop.oreilly.com/product/9781565922259.do)进行解析。我知道您想使用PHP解析器。我以前尝试过但失败了,因为它对错误不够明确。希望这可以帮到您。祝您好运。