Mysqli使用mysql变量准备语句

时间:2014-08-04 16:30:37

标签: php mysql mysqli prepared-statement

我有一个sql查询,使用latitude&amp ;;返回5个最近的位置经度。

$conn->query("SELECT activityId, ( 3959 * acos( cos( radians(
 -0.0761144) ) * cos( radians(
  activity.latitude ) ) * cos( radians(
  activity.longitude ) - radians(

  51.5080937) ) + sin( radians(
  -0.0761144) ) * sin( radians(
    activity.latitude ) ) ) ) AS distance
from activity order by distance limit 5;");

我需要做一个准备好的声明,但要使用?占位符没有意义,因为它意味着两次绑定相同的参数。哦,它实际上没有用。

$stmt = $conn->prepare("SELECT activityId, ( 3959 * acos( cos( radians(
 ?) ) * cos( radians(
  activity.latitude ) ) * cos( radians(
  activity.longitude ) - radians(

  ?) ) + sin( radians(
  ?) ) * sin( radians(
    activity.latitude ) ) ) ) AS distance
from activity order by distance limit 5;");

$stmt = $conn->prepare("ddd", $lat, $lng, $lat);

所以我做了一些研究,从mysql语句中使用变量收集的内容似乎是最好的方法,但这是我卡住的地方,到目前为止,我有以下内容。

$stmt = $conn->prepare("

set @lat = ?;
set @lng = ?;    

SELECT activityId, ( 3959 * acos( cos( radians(
 @lat) ) * cos( radians(
  activity.latitude ) ) * cos( radians(
  activity.longitude ) - radians(

  @lng) ) + sin( radians(
  @lat) ) * sin( radians(
    activity.latitude ) ) ) ) AS distance
from activity order by distance limit 5;

");

$stmt->bind_param("dd", $lat, $lng");

然而现在params没有绑定,我得到一个错误响应,说明这一点。我已经看过谷歌了,我已经指向的答案包括运行两个查询,字体创建变量只是一个查询()然后然后在第二个准备语句中的SELECT语句。但是当然这些语句没有准备好,并且查询对SQL注入开放了吗?

是否有更好的方法来准备此声明,以便从注入攻击中获得安全保障?

// * EDIT * //

经过一些很好的回答后,似乎使用set @var在$ sql-> prepare()中无效;我想我现在可以改进这个问题;我如何将其作为准备好的声明运行?:

$stmt = $conn->prepare("SELECT activityId, ( 3959 * acos( cos( radians(
?) ) * cos( radians(
activity.latitude ) ) * cos( radians(
activity.longitude ) - radians(

?) ) + sin( radians(
?) ) * sin( radians(
activity.latitude ) ) ) ) AS distance
from activity order by distance limit 5;");

$stmt = $conn->prepare("ddd", $lat, $lng, $lat);

2 个答案:

答案 0 :(得分:1)

这是正确的方法:

$stmt = $conn->prepare("SELECT activityId, ( 3959 * acos( cos( radians(
?) ) * cos( radians(
activity.latitude ) ) * cos( radians(
activity.longitude ) - radians(

?) ) + sin( radians(
?) ) * sin( radians(
activity.latitude ) ) ) ) AS distance
from activity order by distance limit 5;");

$stmt->bind_param("ddd", $lat, $lng, $lat);
$result = $stmt->execute();
if($result){
  echo 'SELECT succesful';
}

答案 1 :(得分:0)

也许您可以尝试将类型设置为加倍?

$stmt->bind_param("dd", $lat, $lng);