Pg_query结果包含字符串而不是整数、数字


pg_query result contains strings instead of integer, numeric

当我使用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
]

甚至可以创建自定义转换器并声明如何转换复合(行)类型。这里有一篇更详细的文章。