PHP's native PostgreSQL driver does not support advanced data-types. In fact, it doesn't even properly support integers, booleans or anything else! (cite: As stated here under "Return Values", all values are returned as strings, NOT their correct data type: http://www.php.net/manual/en/function.pg-fetch-assoc.php)
To help battle this problem, you may want to check out PHPG, a PHP library designed to specifically transform all returned PostgreSQL values to native PHP data-types. Supports arrays for any data-type, Hstores, Geometric data-types, and more:
Numeric / Integers
If you're a numeric[] or integer[] data type which does NOT have the possibility of containing NULL values, then you can simply remove the leading and trailing curly brackets, and explode the string into an array using the comma delimiter: 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
However, the problem becomes much more complex when dealing with string-based data types such as character[], character varying[] or text[] and here is why: If the value of an array contains a space or some other special character, then PostgreSQL returns that particular value encapsulated in double quotes. If the value is a single word with no special characters, then that value is returned with no quotes whatsoever.
Here is an example character varying[] value returned from PostgreSQL:
{val1,"val 2",val3,"val-4","val,4"}
The challenge here is:
- Can't explicitly explode on
"," because not all strings are double-quoted.
- Can't explicitly explode on
, because a value may contain a comma such as val,4
The only method I was able to derive after MONTHS of encountering this problem over and over again was to take the string provided by PostgreSQL, and perform a subsequent query to UNNEST the array into a result set, which is then read and transformed into a native PHP array:
$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
In regards to boolean[] values, you could most likely take the same approach as suggested for integers. However because you also anticipate NULL values, we have the added task of mapping the string value NULL to PHP's native NULL data-type:
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)
user_id,date, andattended(the last being boolean). This form takes up more storage, but is easier to query.