PHP-драйвер PostgreSQL не поддерживает расширенные типы данных.На самом деле, он даже не поддерживает integers
, booleans
или что-то еще!(cite: как указано здесь в разделе «Возвращаемые значения», все значения возвращаются в виде строк , НЕ их правильный тип данных: http://www.php.net/manual/en/function.pg-fetch-assoc.php)
Чтобы помочь в решении этой проблемы, вы можете захотетьпосмотрите PHPG, PHP-библиотеку, разработанную специально для преобразования всех возвращенных значений PostgreSQL в собственные типы данных PHP.Поддерживает массивы для любых типов данных, Hstores, Geometric-типов данных и многого другого:
Числовой/ Целые числа
Если вы используете тип данных numeric[]
или integer[]
, который НЕ имеет возможности содержать значения NULL, то вы можете просто удалить начальные и конечные фигурные скобки и разбитьстрока в массив с использованием разделителя запятых: https://github.com/JDBurnZ/PHPG
<?php
$pg_intarr = '{1,2,3,4,5}';
$vals = substr($pg_intarr, 1, -1); // Remove curly brackets
$vals = explode(',',$vals); // Returns: array(1,2,3,4,5)
Strings
Однако проблема становится гораздо более сложной при работе с данными на основе строктакие типы, как character[]
, character varying[]
или text[]
, и вот почему: если значение массива содержит пробел или какой-либо другой специальный символ, то PostgreSQL возвращает это конкретное значение encapsulв двойных кавычках.Если значение представляет собой одно слово без специальных символов, то это значение возвращается без кавычек.
Вот пример character varying[]
значения, возвращаемого из PostgreSQL:
{val1,"val 2",val3,"val-4","val,4"}
Задача здесь:
- Невозможно явно взорваться на
","
, потому что не все строки заключены в двойные кавычки. - Невозможно явно взорваться на
,
, поскольку значение можетсодержать запятую, такую как val,4
Единственный метод, который я смог получить после МЕСЯЦЕВ повторения этой проблемы снова и снова, это взять строку, предоставленную PostgreSQL, и выполнить последующий запрос кUNNEST массив в результирующий набор, который затем читается и преобразуется в собственный массив PHP:
$grab_vals = pg_query("SELECT UNNEST('" . pg_escape_string('{val1,"val 2",val3,"val-4","val,4"}') . "') AS value");
$grab_vals = pg_fetch_all($grab_vals);
$array_vals = array();
foreach($grab_vals as $val) {
$array_vals[] = $grab_vals['value'];
}
Booleans
В отношении boolean[]
значений,Скорее всего, вы можете использовать тот же подход, что и для целых чисел.Однако, поскольку вы также ожидаете значения NULL
, у нас есть дополнительная задача сопоставления строкового значения NULL
с собственным типом данных NULL в PHP:
function pgBool2Php($string) {
if($string == 't') {
return True;
} else if($string == 'f') {
return False;
} else if($string == 'NULL') {
return Null;
} else {
raise new Exception('Mal-formed PostgreSQL Boolean encountered. Expecting value of "t", "f" or "NULL", encountered "' . $string . '"');
}
}
$pg_intarr = '{t,NULL,t,f}';
$vals = substr($pg_intarr, 1, -1); // Remove curly brackets
$vals = explode(',',$vals); // Returns: array('t','NULL','t','f')
$vals = array_map('pgBool2Php', $vals); // Returns: array(True, Null, True, False)