Доступ к psql-массиву напрямую в PHP - PullRequest
2 голосов
/ 07 февраля 2012

Я запрашиваю базу данных psql через PHP, чтобы получить массив логических значений, где индексы являются идентификаторами пользователей, например, userconfirm bool[].Когда я делаю что-то вроде:

$query  = "select userconfirm from calendar where id = '%s'";
$result = $this->db->query($query, 2);
var_dump($result['userconfirm']);

, я получаю:

array(1) { [0]=> array(1) { ["userconfirm"]=> string(20) "[256:258]={t,NULL,t}" } } 

То есть я получаю строку, где должен быть массив.Хорошо, разбор этого, вероятно, мог бы быть сделан, если бы я изучал PHP, но это кажется неправильным.Конечно, есть способ получить массив напрямую?

Главный вопрос: как мне напрямую получить этот массив в PHP?

Дополнительный вопрос: подходит ли этот формат для отслеживания посещаемости пользователей?Есть ли лучший способ?

Ответы [ 3 ]

1 голос
/ 05 марта 2013

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)
1 голос
/ 07 февраля 2012

(Повторно опубликовано из комментария по запросу)

Взглянув на документацию , не похоже, что есть способ напрямую интерполировать массив PostgreSQL в массив вPHP.Однако, если позиция вашего вектора представляет идентификатор пользователя, вам может быть лучше перестроить ваши данные в столбцы с user_id и attended (последний из которых должен иметь тип данных boolean).

0 голосов
/ 17 февраля 2012

вот моя pg_parse функция на github

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