当我使用pg_query,pg_fetch_assoc从postgresql数据库获取数据时,所有数字字段都作为字符串返回。是否有一种方法可以解决这个问题,或者我是否必须按我需要的方式对每个字段进行类型转换?
这就是PHP的功能。从手册:
数组中的每个值都用字符串表示。
可能有点跑题了——让我知道,我会放弃我的答案——但是,这仍然是Pomm项目失败的原因之一:因为默认情况下,布尔值返回为字符串't'和'f'(真和假)。
这是非常不方便的,它使开发人员无法使用复杂而有用的结构,如数组,范围,几何类型等。
Pomm的Foundation包使用pg_field_type函数来触发结果和参数的转换:
select
array[1, 2, 3]::int4[] as some_ints,
now() as a_date,
point(1,2) as a_point,
true as a_bool
;
使用PDO或本地PHP的Postgres库执行此查询将返回一个字符串数组,如下所示:
some_ints │ a_date │ a_point │ a_bool
{1,2,3} │ 2015-07-31 07:35:36.143182+00 │ (1,2) │ t
使用Pomm's Foundation执行此查询将返回一个具有单个数组结果的迭代器:
[
"some_ints" => [
1,
2,
3
],
"a_date" => <DateTime> {
date: "2015-07-31 07:45:21.438447",
timezone_type: 1,
timezone: "+00:00"
},
"a_point" => <PommProject'Foundation'Converter'Type'Point> {
x: 1.0,
y: 2.0
},
"a_bool" => true
]
转换系统也适用于查询参数:
$sql = <<<SQL
select
2 = ANY($*::int4[]) as contain_two,
now() > $*::timestamptz as is_past,
circle(point(0,0), 5) @> $*::point as is_in_circle
;
SQL;
$res = $pomm
->getDefaultSession()
->getQueryManager()
->query($sql, [
[1,2,3],
new 'DateTime('yesterday'),
new 'PommProject'Foundation'Converter'Type'Point('(3,3)')
])
->current()
;
这回报:
[
"contain_two" => true,
"is_past" => true,
"is_in_circle" => true
]
甚至可以创建自定义转换器并声明如何转换复合(行)类型。这里有一篇更详细的文章。