我很难将SQL查询从mysql转换为PDO预处理语句。它是以下内容,它用于计算会话中存储的坐标(用户位置)与数据库中的坐标之间的距离,以及它是否在用户确定的半径范围内:
$query = "
SELECT
*
FROM
first_page_data
WHERE
((((acos(sin((".$_SESSION['alat']."*pi()/180)) *
sin(('geo_lat1'*pi()/180))+cos((".$_SESSION['alat']."*pi()/180)) *
cos(('geo_lat1'*pi()/180)) * cos(((".$_SESSION['alon']."- 'geo_lon1') *
pi()/180))))*180/pi())*60*1.1515) * (1.609344/1000)) < ".$_SESSION['aradius'];
我想将会话变量以及geo_lat和geo_lon变量更改为占位符,这样我就可以将值绑定到它们,但我不能让它的生命让它工作!
我甚至不知道怎样才能看到我如何上场,因为一旦我用占位符替换了上面的变量(我一直在使用未命名的问号占位符)然后将值绑定到它们,我不知道如何从中检索已编译的查询$ stmt我执行它之前:
$stmt = db->prepare($query);
$stmt->bindValue(1, $_SESSION['alat'], PDO::PARAM_STR);
**more bindings**
$stmt->execute();
答案 0 :(得分:2)
这些变化非常简单。我放置了占位符名称,删除了字符串连接,并删除了错误的引号。它可以使用格式化帮助,也可以使用UDF。
# Change string-concat for placeholders
$query = "
SELECT
*
FROM
first_page_data
WHERE
((((acos(sin(( :lat1 *pi()/180)) *
sin((geo_lat1*pi()/180))+cos(( :lat2 *pi()/180)) *
cos((geo_lat1*pi()/180)) * cos((( :lon - geo_lon1) *
pi()/180))))*180/pi())*60*1.1515) * (1.609344/1000)) < :rad";
# Bind values (PARAM_STR is default)
# While PDO does support using a named parameter multiple times
# when emulating placeholders, this is not guaranteed. To be safe,
# here the code is binding the same value to two "different" params.
$stmt = db->prepare($query);
$stmt->bindValue(":lat1", $_SESSION['alat']);
$stmt->bindValue(":lat2", $_SESSION['alat']);
$stmt->bindValue(":lon", $_SESSION['along']);
$stmt->bindValue(":rad", $_SESSION['aradius']);
# Execute! I recommend enabling PDO Exceptions to avoid so much
# manual error-checking of result values.
$stmt->execute();
现在,没有直接的方式来查看带有数据的语句,因为这不是占位符的工作原理 - 即使PDO在内部模拟占位符&#39 ; s仅仅是一个实现细节,你无法看到它。
然而,对于调试语句&#34;更常见的任务有各种解决方案。在How to debug PDO database queries?中讨论过(我建议使用 development 的数据库日志记录,因为您的代码可能不应该直接记录或打印查询。)