将PostgreSQL HSTORE转换为PHP数组

时间:2012-02-21 16:51:42

标签: php postgresql

我正在使用PostgreSQL的HSTORE数据类型和PHP。

我需要能够将PostgreSQL返回的hstore字符串转换为PHP数组。我已经尝试使用[this post] [2]中提到的定义here的fromPg()方法,但是当我保存值并尝试检索它时,遇到类似于以下的值: / p>

"myKey" => "my\"Value"

... fromPg()方法将值分成两个数组条目,第一个具有“myKey”键,值为“my”,第二个键具有“Value”的键和空白值。

我想知道是否有其他人遇到过此问题,是否有人愿意提供更有效的方法将hstore字符串转换为等效的PHP数组。

这是一个代码示例,用于复制我现有的“解决方案”所遇到的问题:

<?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 '</pre>';

我终于打破并创建了一个我自己的PHP库,专门用于解决这个问题,以及PHP的PostgreSQL驱动程序的许多其他缺点,如PostgreSQL Hstores的自动检测和转换,数组,日期,几何数据-types等。它可以在GitHub上找到:https://github.com/JDBurnZ/PHPG

3 个答案:

答案 0 :(得分:1)

试试这个:

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

并使用postgresql的输出提供此函数。

答案 1 :(得分:1)

如果您正在解释来自(直接或不是)来自用户输入的hstore字符串,则Piotr的解决方案具有潜在的危险性(因为所有用户输入的证据都是如此)。我无法想出一种方法来滥用它,但我仍然宁愿避免使用未知的字符串。

用法:

hstore(&lt; some_array_or_object&gt;,false)将输入转换为有效的hStore字符串文字并返回它:

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

hstore(&lt; some_array_or_object&gt;)将输入转换为有效的hStore,单引号,然后是:: hstore

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

hstore(&lt; some_string&gt;)从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;
}

?>

这个问题确实是Convert postgresql hstore to php array的重复。

我只是在这里重新发布我对该帖子的回答。

答案 2 :(得分:0)

您可以使用Pomm's converter system。它带有一个来自/到PHP的HSTore转换器 - Postgresql。

希望它有所帮助...