PHP数组到postgres数组
现在php不能直接与Postgresql数组一起工作。例如,php采用postgresql数组 “{foo”,“bar”}” 我需要一个简单的php函数来从php数组创建多维postgresql数组 我认为实验性的pg_convert()不是最优的,因为它需要额外的数据来形成数据库输出的简单数组字符串,也许我误解了这个函数的概念 例如,我需要转换PHP数组到postgres数组,php,arrays,postgresql,plpgsql,Php,Arrays,Postgresql,Plpgsql,现在php不能直接与Postgresql数组一起工作。例如,php采用postgresql数组 “{foo”,“bar”}” 我需要一个简单的php函数来从php数组创建多维postgresql数组 我认为实验性的pg_convert()不是最优的,因为它需要额外的数据来形成数据库输出的简单数组字符串,也许我误解了这个函数的概念 例如,我需要转换 $from=array( array( "par_1_1","par_1_2" ), array( "array_2_1", "array_2_2"
$from=array( array( "par_1_1","par_1_2" ), array( "array_2_1", "array_2_2" ) );
$to='{{"par_1_1","par_1_2"},{"par_2_1","par_2_2"}}';
我可以使用array\u walk\u recursive()转换数组中最深的元素吗?下面是一个简单的函数,用于将PHP数组转换为PG数组
function to_pg_array($set) {
settype($set, 'array'); // can be called with a scalar or array
$result = array();
foreach ($set as $t) {
if (is_array($t)) {
$result[] = to_pg_array($t);
} else {
$t = str_replace('"', '\\"', $t); // escape double quote
if (! is_numeric($t)) // quote only non-numeric values
$t = '"' . $t . '"';
$result[] = $t;
}
}
return '{' . implode(",", $result) . '}'; // format
}
使用pg_escape_字符串引用并支持PHP空值和布尔值的小编辑:
/**
* Converts a php array into a postgres array (also multidimensional)
*
* Each element is escaped using pg_escape_string, only string values
* are enclosed within single quotes, numeric values no; special
* elements as php nulls or booleans are literally converted, so the
* php NULL value is written literally 'NULL' and becomes a postgres
* NULL (the same thing is done with TRUE and FALSE values).
*
* Examples :
* VARCHAR VERY BASTARD ARRAY :
* $input = array('bla bla', 'ehi "hello"', 'abc, def', ' \'VERY\' "BASTARD,\'value"', NULL);
*
* to_pg_array($input) ==>> 'ARRAY['bla bla','ehi "hello"','abc, def',' ''VERY'' "BASTARD,''value"',NULL]'
*
* try to put this value in a query (you will get a valid result):
* select unnest(ARRAY['bla bla','ehi "hello"','abc, def',' ''VERY'' "BASTARD,''value"',NULL]::varchar[])
*
* NUMERIC ARRAY:
* $input = array(1, 2, 3, 8.5, null, 7.32);
* to_pg_array($input) ==>> 'ARRAY[1,2,3,8.5,NULL,7.32]'
* try: select unnest(ARRAY[1,2,3,8.5,NULL,7.32]::numeric[])
*
* BOOLEAN ARRAY:
* $input = array(false, true, true, null);
* to_pg_array($input) ==>> 'ARRAY[FALSE,TRUE,TRUE,NULL]'
* try: select unnest(ARRAY[FALSE,TRUE,TRUE,NULL]::boolean[])
*
* MULTIDIMENSIONAL ARRAY:
* $input = array(array('abc', 'def'), array('ghi', 'jkl'));
* to_pg_array($input) ==>> 'ARRAY[ARRAY['abc','def'],ARRAY['ghi','jkl']]'
* try: select ARRAY[ARRAY['abc','def'],ARRAY['ghi','jkl']]::varchar[][]
*
* EMPTY ARRAY (is different than null!!!):
* $input = array();
* to_pg_array($input) ==>> 'ARRAY[]'
* try: select unnest(ARRAY[]::varchar[])
*
* NULL VALUE :
* $input = NULL;
* to_pg_array($input) ==>> 'NULL'
* the functions returns a string='NULL' (literally 'NULL'), so putting it
* in the query, it becomes a postgres null value.
*
* If you pass a value that is not an array, the function returns a literal 'NULL'.
*
* You should put the result of this functions directly inside a query,
* without quoting or escaping it and you cannot use this result as parameter
* of a prepared statement.
*
* Example:
* $q = 'INSERT INTO foo (field1, field_array) VALUES ($1, ' . to_pg_array($php_array) . '::varchar[])';
* $params = array('scalar_parameter');
*
* It is recommended to write the array type (ex. varchar[], numeric[], ...)
* because if the array is empty or contains only null values, postgres
* can give an error (cannot determine type of an empty array...)
*
* The function returns only a syntactically well-formed array, it does not
* make any logical check, you should consider that postgres gives errors
* if you mix different types (ex. numeric and text) or different dimensions
* in a multidim array.
*
* @param array $set PHP array
*
* @return string Array in postgres syntax
*/
function to_pg_array($set) {
if (is_null($set) || !is_array($set)) {
return 'NULL';
}
// can be called with a scalar or array
settype($set, 'array');
$result = array();
foreach ($set as $t) {
// Element is array : recursion
if (is_array($t)) {
$result[] = to_pg_array($t);
}
else {
// PHP NULL
if (is_null($t)) {
$result[] = 'NULL';
}
// PHP TRUE::boolean
elseif (is_bool($t) && $t == TRUE) {
$result[] = 'TRUE';
}
// PHP FALSE::boolean
elseif (is_bool($t) && $t == FALSE) {
$result[] = 'FALSE';
}
// Other scalar value
else {
// Escape
$t = pg_escape_string($t);
// quote only non-numeric values
if (!is_numeric($t)) {
$t = '\'' . $t . '\'';
}
$result[] = $t;
}
}
}
return 'ARRAY[' . implode(",", $result) . ']'; // format
}
这与以下内容相同,但更具可读性、通用性和现代性(至少对我而言):
你想把array_2_1
改成par_2_1
还是这是一个打字错误??我想用PHP制作postgresql数组的结构。它必须是类似于标准PHP数组中PHP中的“{{”*”、“*”}、“*”、“*”}”的字符串,其中*是数据。Postgresql将这些字符串解析为数组。警告:这不会引用恰好表示数值的字符串。在执行is\u numeric
检查之前执行is\u string
检查更安全,否则包含数字表示的字符串将被解释为数字并导致语法错误。
<?php
class Sql
{
/**
* Convert PHP-array to SQL-array
* https://stackoverflow.com/questions/5631387/php-array-to-postgres-array
*
* @param array $data
* @return string
*/
public static function toArray(array $data, $escape = 'pg_escape_string')
{
$result = [];
foreach ($data as $element) {
if (is_array($element)) {
$result[] = static::toArray($element, $escape);
} elseif ($element === null) {
$result[] = 'NULL';
} elseif ($element === true) {
$result[] = 'TRUE';
} elseif ($element === false) {
$result[] = 'FALSE';
} elseif (is_numeric($element)) {
$result[] = $element;
} elseif (is_string($element)) {
$result[] = "'" . $escape($element) . "'";
} else {
throw new \InvalidArgumentException("Unsupported array item");
}
}
return sprintf('ARRAY[%s]', implode(',', $result));
}
}
<?php
use Sql;
class SqlTest extends \PHPUnit_Framework_TestCase
{
public function testToArray()
{
$this->assertSame("ARRAY['foo','bar']", Sql::toArray(['foo', 'bar']));
$this->assertSame("ARRAY[1,2]", Sql::toArray([1, 2]));
$this->assertSame("ARRAY[1,2]", Sql::toArray(['1', '2']));
$this->assertSame("ARRAY['foo\\\"bar','bar\'foo']", Sql::toArray(['foo"bar', 'bar\'foo'], function($str){
return addslashes($str);
}));
$this->assertSame("ARRAY[ARRAY['foo\\\"bar'],ARRAY['bar\'foo']]", Sql::toArray([['foo"bar'], ['bar\'foo']], function($str){
return addslashes($str);
}));
}
}