Intereting Posts
Первый postLink () не создает форму Есть ли способ обмениваться объектами между php-страницами? Включение CSS в файл .php Проблема. Объявление XML разрешено только в начале документа. Отправка электронной почты с PHP с помощью SMTP и электронной почты идет на спам. Какой будет самый простой способ отправить электронную почту во входящие? Mysql codeigniter php asc desc order по результату подсчета с использованием php php – отправлять и получать xml-документы Как показать индикатор выполнения в загрузке файла ajax Как предотвратить множественные экземпляры скрипта? OneNote API не может получать заметки из общего ноутбука для обмена пользователями Laravel … Автоматически выполнять скрипт через несколько часов Ошибка при попытке получить данные из 2 таблиц codeigniter подтверждение сообщения перед отправкой в ​​php Удалить ключ индекса из массива для доступа к объекту? комментарии «//» с регулярным выражением, но не внутри цитаты

Преобразование массива PostgreSQL в массив PHP

У меня проблемы с чтением массивов Postgresql в PHP. Я попробовал explode (), но это разбивает массивы, содержащие запятые в строках, и str_getcsv (), но это также не хорошо, поскольку PostgreSQL не цитирует японские строки.

Не работает:

explode(',', trim($pgArray['key'], '{}')); str_getcsv( trim($pgArray['key'], '{}') ); 

Пример:

 // print_r() on PostgreSQL returned data: Array ( [strings] => {または, "some string without a comma", "a string, with a comma"} ) // Output: Array ( [0] => または [1] => "some string without a comma" [2] => "a string [3] => with a comma" ) explode(',', trim($pgArray['strings'], '{}')); // Output: Array ( [0] => [1] => some string without a comma [2] => a string, with a comma ) print_r(str_getcsv( trim($pgArray['strings'], '{}') )); 

Если у вас есть PostgreSQL 9.2, вы можете сделать что-то вроде этого:

 SELECT array_to_json(pg_array_result) AS new_name FROM tbl1; 

Результат вернет массив как JSON

Затем на стороне php вопрос:

 $array = json_decode($returned_field); 

Вы также можете конвертировать обратно. Вот страница функций JSON

Поскольку ни одно из этих решений не работает с многомерными массивами , поэтому я предлагаю здесь свое рекурсивное решение, которое работает с массивами любой сложности :

 function pg_array_parse($s, $start = 0, &$end = null) { if (empty($s) || $s[0] != '{') return null; $return = array(); $string = false; $quote=''; $len = strlen($s); $v = ''; for ($i = $start + 1; $i < $len; $i++) { $ch = $s[$i]; if (!$string && $ch == '}') { if ($v !== '' || !empty($return)) { $return[] = $v; } $end = $i; break; } elseif (!$string && $ch == '{') { $v = pg_array_parse($s, $i, $i); } elseif (!$string && $ch == ','){ $return[] = $v; $v = ''; } elseif (!$string && ($ch == '"' || $ch == "'")) { $string = true; $quote = $ch; } elseif ($string && $ch == $quote && $s[$i - 1] == "\\") { $v = substr($v, 0, -1) . $ch; } elseif ($string && $ch == $quote && $s[$i - 1] != "\\") { $string = false; } else { $v .= $ch; } } return $return; } 

Я не слишком много тестировал, но похоже, что это работает. Здесь у вас есть мои тесты с результатами:

 var_export(pg_array_parse('{1,2,3,4,5}'));echo "\n"; /* array ( 0 => '1', 1 => '2', 2 => '3', 3 => '4', 4 => '5', ) */ var_export(pg_array_parse('{{1,2},{3,4},{5}}'));echo "\n"; /* array ( 0 => array ( 0 => '1', 1 => '2', ), 1 => array ( 0 => '3', 1 => '4', ), 2 => array ( 0 => '5', ), ) */ var_export(pg_array_parse('{dfasdf,"qw,,e{q\"we",\'qrer\'}'));echo "\n"; /* array ( 0 => 'dfasdf', 1 => 'qw,,e{q"we', 2 => 'qrer', ) */ var_export(pg_array_parse('{,}'));echo "\n"; /* array ( 0 => '', 1 => '', ) */ var_export(pg_array_parse('{}'));echo "\n"; /* array ( ) */ var_export(pg_array_parse(null));echo "\n"; // NULL var_export(pg_array_parse(''));echo "\n"; // NULL 

PS: Я знаю, что это очень старый пост, но я не смог найти решение для postgresql pre 9.2

Надежная функция для синтаксического анализа литерала массива PostgreSQL (одномерного) в массив PHP с использованием регулярных выражений:

 function pg_array_parse($literal) { if ($literal == '') return; preg_match_all('/(?<=^\{|,)(([^,"{]*)|\s*"((?:[^"\\\\]|\\\\(?:.|[0-9]+|x[0-9a-f]+))*)"\s*)(,|(?<!^\{)(?=\}$))/i', $literal, $matches, PREG_SET_ORDER); $values = []; foreach ($matches as $match) { $values[] = $match[3] != '' ? stripcslashes($match[3]) : (strtolower($match[2]) == 'null' ? null : $match[2]); } return $values; } print_r(pg_array_parse('{blah,blah blah,123,,"blah \\"\\\\ ,{\100\x40\t\daő\ő",NULL}')); // Array // ( // [0] => blah // [1] => blah blah // [2] => 123 // [3] => // [4] => blah "\ ,{@@ daőő // [5] => // ) var_dump(pg_array_parse('{,}')); // array(2) { // [0] => // string(0) "" // [1] => // string(0) "" // } print_r(pg_array_parse('{}')); var_dump(pg_array_parse(null)); var_dump(pg_array_parse('')); // Array // ( // ) // NULL // NULL print_r(pg_array_parse('{または, "some string without a comma", "a string, with a comma"}')); // Array // ( // [0] => または// [1] => some string without a comma // [2] => a string, with a comma // ) 

Если вы можете предвидеть, какие текстовые данные вы можете ожидать в этом поле, вы можете использовать функцию array_to_string . Он доступен в 9.1

Например, я точно знаю, что в моих полевых labes массива никогда не будет символа '\n' . Поэтому я преобразовываю массивы в строку с помощью функции array_to_string

 SELECT ... array_to_string( labels, chr(10) ) as labes FROM ... 

Теперь я могу разбить эту строку, используя функцию PHP explode :

 $phpLabels = explode( $pgLabes, "\n" ); 

Вы можете использовать любую последовательность символов для разделения элементов массива.

SQL:

 SELECT array_to_string( labels, '<--###DELIMITER###-->' ) as labes 

PHP:

 $phpLabels = explode( $pgLabes, '<--###DELIMITER###-->' ); 

Я попробовал ответить array_to_json, но, к сожалению, это приводит к неизвестной ошибке функции. Используя конструктор dbal query в базе данных postgres 9.2 с чем-то вроде ->addSelect('array_agg(a.name) as account_name') , я получил в результате строку типа { "name 1", "name 2", "name 3" }

Есть только кавычки вокруг частей массива, если они содержат специальные символы, такие как пробелы или знаки препинания.

Поэтому, если есть кавычки, я делаю строку допустимой json-строкой, а затем использую встроенную функцию parse json. В противном случае я использую взрыв.

 $data = str_replace(array("\r\n", "\r", "\n"), "", trim($postgresArray,'{}')); if (strpos($data, '"') === 0) { $data = '[' . $data . ']'; $result = json_decode($data); } else { $result = explode(',', $data); 

}

Я вижу, что вы используете explode(',', trim($pgArray, '{}'));

Но взорваться используется для разделения строки по строке (и вы поставляете ей массив!). что-то вроде ..

 $string = "A string, with, commas"; $arr = explode(',', $string); 

Что вы пытаетесь сделать с массивом? если вы хотите конкатенатировать, посмотрите на implode

ИЛИ не уверены, что вы можете указать разделитель, отличный от запятой? array_to_string (anyarray, текст)

Если у вас есть контроль над запросом, который попадает в базу данных, почему бы вам просто не использовать unnest() для получения результатов в виде строк вместо массивов Postgres? Оттуда вы можете изначально получить PHP-массив.

 $result = pg_query('SELECT unnest(myArrayColumn) FROM someTable;'); if ( $result === false ) { throw new Exception("Something went wrong."); } $array = pg_fetch_all($result); 

Это оборачивает проблемы с накладными расходами и обслуживанием, которые вы понесли, пытаясь преобразовать строковое представление массива самостоятельно.