在GAE上用PHP解析远程csv文件


parse remote csv-file with PHP on GAE

我似乎在一个catch-22与一个小的应用程序,我正在开发在谷歌应用程序引擎上使用Quercus PHP;

  1. 我有一个远程csv文件,我可以下载&存储在字符串
  2. 解析字符串时,我理想地使用str_getcsv,但Quercus还没有这个函数
  3. Quercus似乎知道fgetcsv,但该函数期望一个文件句柄,我没有(我不能做一个新的,因为GAE不允许创建文件)

有人知道如何解决这个问题,而不必放弃内置的PHP csv解析器函数,而是编写自己的解析器?

我认为最简单的解决方案是编写自己的解析器。无论如何,它都是小菜一碟,并且会让你学习更多的正则表达式- PHP中没有csv字符串到数组的解析器是没有意义的,所以完全有理由自己编写。只要确保它不会太慢;)

您可以使用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);

这显示了我编写的一个简单的手动解析器,它使用带有限定、非限定和转义特性的示例输入。它可以用于标题和数据行,并包含一个关联数组函数,使您的数据成为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;
}

如果可以又脏又快的话。我就用http://php.net/manual/en/function.exec.php传入并使用sed和awk (http://shop.oreilly.com/product/9781565922259.do)对其进行解析。我知道您想使用php解析器。我以前尝试过,但失败了,只是因为它没有直言不讳地说出它的错误。希望这对你有所帮助。祝你好运。

您可以将fopenphp://tempphp://memory (php.net)一起使用以使其工作。您要做的是打开php://tempphp://memory,写入它,然后倒带(php.net),然后将其传递给fgetcsv。我没有测试这个,但它可能工作。