разобрать удаленный csv-файл с PHP на GAE - PullRequest
7 голосов
/ 08 августа 2011

Кажется, я в ловушке с небольшим приложением, которое я разрабатываю на PHP на Google App Engine с использованием Quercus;

  1. У меня есть удаленный CSV-файл, который я могу загрузить и сохранить в строке
  2. Для разбора этой строки я бы в идеале использовал str_getcsv, но у Quercus пока нет этой функции
  3. Quercus, похоже, знает fgetcsv, но эта функция ожидает дескриптор файла, которого у меня нет (и я не могу создать новый, так как GAE не позволяет создавать файлы)

Кто-нибудь получил представление о том, как решить эту проблему без необходимости отмены встроенных функций PHP csv-parser и написания вместо этого собственного парсера?

Ответы [ 5 ]

1 голос
/ 22 сентября 2011

Я думаю, что самое простое решение - написать собственный парсер.В любом случае, это просто пирог, и вы научитесь изучать регулярные выражения - нет смысла в том, что в PHP нет строки csv для синтаксического анализа массива, поэтому совершенно оправданно писать свою собственную.Просто убедитесь, что это не слишком медленно;)

0 голосов
/ 08 ноября 2011

Вы можете использовать fopen с php://temp или php://memory ( php.net ), чтобы заставить его работать.Что бы вы сделали, это откройте либо php://temp или php://memory, напишите в него, затем перемотайте его ( php.net ) и затем передайте его в fgetcsv.Я не проверял это, но это может сработать.

0 голосов
/ 03 ноября 2011

, если он может быть грязным и быстрым. Я бы просто использовал http://php.net/manual/en/function.exec.php передать его и использовать sed и awk (http://shop.oreilly.com/product/9781565922259.do) для его синтаксического анализа. Я знаю, что вы хотели использовать анализатор php. Надеюсь это поможет. Удачи.

0 голосов
/ 21 сентября 2011

это показывает простой ручной анализатор, который я написал с примером ввода с квалифицированной, неквалифицированной, escape-функцией.он может использоваться для строк заголовка и данных и включать функцию связанного массива, чтобы превратить ваши данные в массив стиля 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;
}
0 голосов
/ 18 августа 2011

Вы можете создать новую потоковую оболочку, используя 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);
...