【发布时间】:2010-10-17 15:31:57
【问题描述】:
我在 PostgreSQL 8.4.5 中有下表:
snake=> create table gps (
id bytea check(length(id) = 16),
stamp timestamp DEFAULT current_timestamp,
pos point not null);
我可以从 psql 提示符中插入记录:
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
但由于某种原因,在下面列出的我的 PHP 脚本中 INSERT 失败,其结果返回为 0。请问有人知道那里出了什么问题或如何获取更多信息吗?我很惊讶没有抛出异常。
<?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>
';
}
?>
我得到表明结果为 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>
问候, 亚历克斯
PS:这是我当前的脚本,似乎可以正常工作 -
<?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>
';
}
?>
【问题讨论】:
-
您是否收到任何错误消息?您是否使用相同的用户名表单命令行和脚本?
-
这不是你的问题,但我想注意这个错误。在您有 [0-9.] 的数字匹配中,点 (.) 表示“任何字符”。您需要将其转义为 [0-9\.] 以便它匹配一个句点。
-
@Conspicuous Metacharacters 除了
]\^-是字符类中的常规字符,所以这不是问题。 -
@lonesomeday:嗯,好吧,过去阅读手册对我的建议与过去相反。 perldoc.perl.org/perlre.html 请注意,在“版本 8 正则表达式”下,它谈到了在字符类附近进行转义,并没有指出这样的例外。但是这一行表明我错了: perl -e '$foo = "0a9"; print "Dots are magic\n" if $foo =~ /^[0-9.]+$/;' ——没有输出。谢谢你让我直截了当!
-
是的,我是 Perl 的长期用户,我很确定,您可以在正则表达式 char 类中使用类似 [-+0-9^.] 的东西。例如: perl -e 'print ("^" =~ /[-+0-9^.]/)' 不过还是感谢您查看我的代码!
标签: php postgresql insert