开发者

parse remote csv-file with PHP on GAE

I seem to be in a catch-22 with a small app I'm developing in PHP on Google App Engine using Quercus;

  1. I have a remote csv-file which I can download & store in a string
  2. To parse that string I'd ideally use str_getcsv, but Quercus doesn't have that function yet
  3. Quercus does seem to know fgetcsv, but that function expects a file handle which I don't have (and I can't make a new one as GAE doesn't allow files to be created)

Anyone got an idea of how to solve this without having to dismiss the built-in PHP csv-parser functions and write my 开发者_Go百科own parser instead?


I think the simplest solution really is to write your own parser . it's a piece of cake anyway and will get you to learn more regex- it makes no sense that there is no csv string to array parser in PHP so it's totally justified to write your own. Just make sure it's not too slow ;)


You might be able to create a new stream wrapper using stream_wrapper_register.

Here's an example from the manual which reads global variables: http://www.php.net/manual/en/stream.streamwrapper.example-1.php

You could then use it like a normal file handle:

$csvStr = '...';
$fp = fopen('var://csvStr', 'r+');
while ($row = fgetcsv($fp)) {
    // ...
}
fclose($fp);


this shows a simple manual parser i wrote with example input with qualifed, non-qualified, escape feature. it can be used for the header and data rows and included an assoc array function to make your data into a kvp style array.

//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;
}


if it can be dirty and quick. I would just use the http://php.net/manual/en/function.exec.php to pass it in and use sed and awk (http://shop.oreilly.com/product/9781565922259.do) to parse it. I know you wanted to use the php parser. I've tried before and failed simply because its not vocal about its errors. Hope this helps. Good luck.


You might be able to use fopen with php://temp or php://memory (php.net) to get it to work. What you would do is open either php://temp or php://memory, write to it, then rewind it (php.net), and then pass it to fgetcsv. I didn't test this, but it might work.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜