Преобразование PostgreSQL HSTORE в массив PHP - PullRequest
1 голос
/ 21 февраля 2012

Я работаю с типом данных PostgreSQL HSTORE и PHP.

Мне требуется возможность преобразовать возвращенную строку PostgreSQL hstore в массив PHP. Я попытался использовать метод fromPg (), определенный здесь , как упомянуто в [этом сообщении] [2], однако, когда я сохраняю значение и пытаюсь получить его, когда я сталкиваюсь со значением, подобным следующему

"myKey" => "my\"Value"

... метод fromPg () разбивает значение на две записи массива, первая из которых имеет ключ «myKey» и значение «my \», а вторая имеет ключ «Value \» «и пустое значение.

Мне интересно, была ли у кого-нибудь еще эта проблема, и не желал бы кто-нибудь предоставить более функциональный метод преобразования строки hstore в ее эквивалентный массив PHP.

Вот пример кода, чтобы повторить мою проблему с существующим «решением»:

<code><?php
function fromPg($data) {
    $split = preg_split('/[,\s]*"([^"]+)"[,\s]*|[,=>\s]+/', $data, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
    $hstore = array();
    for($index = 0; $index < count($split); $index = $index + 2) {
        $hstore[$split[$index]] = $split[$index + 1] != 'NULL' ? $split[$index + 1] : null;
    }
    return $hstore;
}

$hstore_string = '"myKey" => "my\"Value"';
$hstore_array = fromPg($hstore_string);

print '<pre>';
print_r($hstore_array);
print '
';

Я наконец-то сломал и создал собственную библиотеку PHP, специально предназначенную для решения этой проблемы, а также многие другие недостатки драйвера PHP PostgreSQL, такие как автоматическое обнаружение и преобразование PostgreSQL Hstores, Arrays, Dates, Geometric data -типы и т. д. Он доступен на GitHub по адресу: https://github.com/JDBurnZ/PHPG

Ответы [ 3 ]

1 голос
/ 28 февраля 2013

Если вы интерпретируете строку hstore, которая поступает (напрямую или нет) из пользовательского ввода, решение Петра потенциально опасно (так как все пользовательские данные исчезают).Я не могу придумать способ злоупотребить им, но все же я бы предпочел не вычислять неизвестную строку.

Использование:

hstore (, false) преобразует входные данные в действительный строковый литерал hStore и возвращает его:

hstore(array('k1' => 'v1', 'k2' => 'v2')) => "k1"=>"v1","k2"=>"v2"

hstore () преобразует входные данные в действительный hStore, заключенный в одинарные кавычки, за которым следует: hstore

hstore(array('k1' => 'v1', 'k2' => 'v2')) => '"k1"=>"v1","k2"=>"v2"'::hstore

hstore () преобразует из строки hstore (как это происходит из запроса) в массив

hstore('"k1"=>"v1","k2"=>"v2"') => array('k1' => 'v1', 'k2' => 'v2')

Он обрабатывает значения NULL (в обе стороны) и правильно экранирует / удаляет ключи и значения.

<?php

/**
 * mixed hstore(mixed $input[, bool $prepared = false])
 *      Convert from hstore string to array, or from array/object to hstore.
 * Inner arrays/objects are serialized but deserialization is up to you; you
 * are expected to keep track of which fields you sent as non-scalars.
 *
 * @param mixed $input          A string (from hstore) or an array/object
 * @param type $prepared        Array or object to convert to hstore string
 * @return mixed                Depends on the input
 */
function hStore($input, $prepared=true)
{
    if (is_string($input))
    {
        if ($input === 'NULL')
        {
            $output = NULL;
        }
        else
        {
            $re = '_("|^)(.*?[^\\\\"])"=>"(.*?[^\\\\"])("|$)_s';
            preg_match_all($re, $input, $pairs);
            $mid = $pairs ? array_combine($pairs[2], $pairs[3]) : array();

            foreach ($mid as $k => $v)
            {
                $output[trim($k, '"')] = stripslashes($v);
            }
        }
    }
    elseif (is_null($input))
    {
        $output = $prepared  ? 'NULL::hstore' : 'NULL';
    }
    elseif (!is_scalar($input))
    {
        foreach ((array)$input as $k => $v)
        {
            !is_scalar($v) && ($v = serialize($v));
            $entries[] = '"' . addslashes($k) . '"=>' .
                         '"' . addslashes($v) . '"';
        }

        $mid = empty($entries) ? '' : join(', ', $entries);

        $output = $prepared ? "'{$mid}'::hstore" : $mid;
    }

    return $output;
}

?>

Этот вопрос действительно является дубликатом Конвертировать postgresql hstore в массив php .

Я просто публикую здесь свой ответ на этот пост.

1 голос
/ 25 июня 2012

Попробуйте:

function unescape_hstore($hstore)
{        
  $hstore = preg_replace('/([$])/', "\\\\$1", $hstore);
  $unescapedHStore = array();
  eval('$unescapedHStore = array(' . $hstore . ');');
  return $unescapedHStore;
}

И передайте эту функцию выводом из postgresql.

0 голосов
/ 22 августа 2012

Вы можете использовать Система преобразования Pomm . Он поставляется с HSTore конвертером из / в PHP - Postgresql.

Надеюсь, это поможет ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...