views:

37

answers:

1

Hello,

I have the following table in PostgreSQL 8.4.5:

snake=> create table gps (
id bytea check(length(id) = 16),
stamp timestamp DEFAULT current_timestamp,
pos point not null);

and I'm able to INSERT record into it from psql prompt:

snake=> insert into gps (id, pos) values (decode(md5('x'), 'hex'), point(0, 0));
INSERT 0 1
snake=> insert into gps (id, pos) values (decode(md5('x'), 'hex'), point(0, 0));
INSERT 0 1

But for some reason INSERT fails in my PHP script listed below and its result is returned as 0. Does anybody please have an idea what is wrong there or how to get more info? I'm surprised that an exception isn't thrown.

<?php

$id  = trim($_REQUEST['id']);
$lat = strtr(trim($_REQUEST['lat']), ',', '.');
$lon = strtr(trim($_REQUEST['lon']), ',', '.');

if (preg_match('/^[a-fA-F0-9]{32}$/', $id) &&
    preg_match('/^[+-]?[0-9.]+$/', $lat) &&
    preg_match('/^[+-]?[0-9.]+$/', $lon)) {

        try {
                $db = new PDO('pgsql:host=/tmp', 'snake', 'snake');
                $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

                $insert = $db->prepare("insert into gps (id, pos) values (decode(?, 'hex'), point(?, ?))");
                $res = $insert->execute($id, $lat, $lon);

                $select = $db->prepare("select encode(id, 'hex') as id, extract('epoch' from stamp) as stamp, pos[0] as lat, pos[1] as lon from gps");
                $select->execute();

                header('Content-Type: text/xml; charset=utf-8');
                print '<?xml version="1.0"?><gps>';
                while ($row = $select->fetch(PDO::FETCH_ASSOC)) {
                        printf('<pos id="%s" stamp="%u" lat="%f" lon="%f" />',
                            $row['id'], $row['stamp'], $row['lat'], $row['lon']);
                }
                printf('<res val="%d" />', $res);

                print '</gps>';
        } catch (Exception $e) {
                print 'Database problem: ' . $e->getMessage();
        }

} else {
        header('Content-Type: text/html; charset=utf-8');
        print '<html>
<body>
<form method="post">
<p>Id: <input type="text" name="id" size=32 maxlength=32 /></p>
<p>Latitude: <input type="text" name="lat" /></p>
<p>Longitude: <input type="text" name="lon" /></p>
<p><input type="submit" value="Save" /></p>
</form>
</body>
</html>
';

}

?>

I get the output which indicates that result is 0:

<gps>
<pos id="0cc175b9c0f1b6a831c399e269772661" stamp="1287306960" lat="51.000000" lon="7.000000"/>
<pos id="0cc175b9c0f1b6a831c399e269772661" stamp="1287323377" lat="51.000000" lon="7.000000"/>
<pos id="92eb5ffee6ae2fec3ad71c777531578f" stamp="1287323381" lat="51.000000" lon="7.000000"/>
<pos id="92eb5ffee6ae2fec3ad71c777531578f" stamp="1287323442" lat="51.300000" lon="7.000000"/>
<pos id="92eb5ffee6ae2fec3ad71c777531578f" stamp="1287325610" lat="51.300000" lon="7.000000"/>
<pos id="92eb5ffee6ae2fec3ad71c777531578f" stamp="1287325612" lat="51.300000" lon="7.000000"/>
<pos id="9dd4e461268c8034f5c8564e155c67a6" stamp="1287325692" lat="0.000000" lon="0.000000"/>
<res val="0"/>
</gps>

Regards, Alex

PS: Here is my current script, seems to work ok -

<?php

$id  = trim($_REQUEST['id']);
$lat = strtr(trim($_REQUEST['lat']), ',', '.');
$lng = strtr(trim($_REQUEST['lng']), ',', '.');

if (preg_match('/^[a-fA-F0-9]{32}$/', $id) &&
    preg_match('/^[+-]?[0-9.]+$/', $lat) &&
    preg_match('/^[+-]?[0-9.]+$/', $lng)) {

        try {
                # enable persistent connections and throw exception on errors
                $options = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                                 PDO::ATTR_PERSISTENT => true);

                $db = new PDO('pgsql:host=/tmp dbname=snake', 'snake', 'snake', $options);

                #$db->exec('create table gps (id bytea check(length(id) = 16), stamp timestamp DEFAULT current_timestamp, pos point not null)');

                $insert = $db->prepare("insert into gps (id, pos) values (decode(?, 'hex'), point(?, ?))");
                $insert->execute(array($id, $lat, $lng));

                $select = $db->prepare("select encode(id, 'hex') as id, extract('epoch' from stamp) as stamp, pos[0] as lat, pos[1] as lng from gps");
                $select->execute();

                header('Content-Type: text/xml; charset=utf-8');
                print '<?xml version="1.0"?><gps>';
                while ($row = $select->fetch(PDO::FETCH_ASSOC)) {
                        printf('<pos id="%s" stamp="%u" lat="%f" lng="%f" />',
                            $row['id'], $row['stamp'], $row['lat'], $row['lng']);
                }
                print '</gps>';
        } catch (Exception $e) {
                print 'Database problem: ' . $e->getMessage();
        }

} else {
        header('Content-Type: text/html; charset=utf-8');
        print '<html>
<body>
<form method="post">
<p>Id: <input type="text" name="id" size=32 maxlength=32 /></p>
<p>Latitude: <input type="text" name="lat" /></p>
<p>Longitude: <input type="text" name="lng" /></p>
<p><input type="submit" value="Save" /></p>
</form>
</body>
</html>
';
}

?>
+2  A: 

I believe you need to do PDOStatement->insert() using an array of parameters, not multiple arguments:

$res = $insert->execute($id, array($lat, $lon));

See the manual.

lonesomeday
That was it, thank you! Strange that an exception wasn't thrown
Alexander Farber
There's a comment on [the manual page](http://www.php.net/manual/en/pdo.setattribute.php#71281): "setting the PDO::ATTR_ERRMODE attribute to PDO::ERRMODE_EXCEPTION worked for me only with Mysql 4.x - I took me some time to figure this out ;-)" Maybe that's the reason?
lonesomeday