【问题标题】:"bindParam" with multi-parameters after "Limit" couldn't work in php?“Limit”之后的多参数“bindParam”不能在php中工作?
【发布时间】:2020-08-19 01:55:26
【问题描述】:

我遇到了这个问题,找不到解决办法, 有专家可以帮我吗?

public  function getComments($postId,$pageCmt){
        $db = $this->dbConnect();
        $cmtNb=3;
        $r=($pageCmt-1)*3;

        $req = $db->prepare('SELECT id, comments FROM comments WHERE post_id = ? ORDER BY ind_date DESC,date_comments DESC LIMIT ? OFFSET ?' );

        $req->bindParam(1,$postId,\PDO::PARAM_INT);         
        $req->bindParam(2,$cmtNb,\PDO::PARAM_INT );                 
        $req->bindParam(3,$r,\PDO::PARAM_INT);

         $req->execute(array($postId,$cmtNb,$r));

         return $req;
      }

似乎问题来自LIMIT之后的参数, 因为如果我起飞“限制?偏移?”代码可以与第一个参数 $postId 一起使用,将获取 cmets,

但如果我添加带有“LIMIT ? OFFSET?”的代码在页面上将不会获取任何 cmets,但也不会显示任何错误,

有什么想法吗?

谢谢。

【问题讨论】:

  • 我的建议是从execute 中删除参数,因为前面的bindParam 调用已经完成了占位符绑定。 (我们将假设启用了 PHP 错误报告,并且 PDO 连接配置为在发生错误时抛出异常,即 setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION) 我个人的偏好是使用 bindValue 代替 bindParam 的值在绑定时已知,我个人的偏好是使用LIMIT ? , ? 形式而不是OFFSET
  • 首先感谢您的建议,好吧,PDO 连接似乎没问题,因为如果我删除 2e 和 3e “?”,此代码可以工作,但如果我添加 2e 和 3e 变量,即使使用bindValue,它也不能工作......!。
  • 对于 debubbing,当我们离开 OFFSET ? 时,只剩下 LIMIT 会发生什么?如果我们硬编码 LIMIT 子句,没有任何绑定占位符(作为测试),例如LIMIT 3,还是LIMIT 0,3?如果可行,那么$r 的值是多少(我们可以将其转储以进行调试。
  • 是的,去掉execute中的array($postId,$cmtNb,$r)
  • @spencer7593 你好,我今天用你的方法又试了一次,但仍然使用“LIMIT ?OFFSET ?”有用!谢谢,“vardump”真的很有用。顺便说一句,当我使用“限制?,?”它不起作用,仍然不知道为什么。

标签: php mysql sqlbindparameter


【解决方案1】:

在这种情况下,您可以尝试将值直接连接到查询中,因为该值不能被用户欺骗,值是在服务器端设置的。

另外,您不需要使用 bindParam() 并将值传递给 execute()

你的代码可以修改为

$req = $db->prepare('SELECT id, comments FROM comments WHERE post_id = ? ORDER BY ind_date DESC,date_comments DESC LIMIT {$cmtNb} OFFSET {$r}' );
$req->execute(array($postId));

如果您需要使用用户为LIMITOFFSET 指定的值,则需要在运行查询之前在服务器端验证该值是否应该被接受。

【讨论】:

  • MySQL 参考手册不同意这个答案的第一句话。 MySQL 允许吗? LIMIT 子句中的占位符,至少从 5.6 版开始。 (如果在 SQL 文本中引入单引号,我认为这取决于绑定中的数据类型;PDO 不会对其他数据库执行此操作,可能取决于是否使用服务器端准备?)我个人的偏好会是使用bindValue 代替bindParam(假设绑定值在绑定时已知)
  • @spencer7593 谢谢。我删除了第一句话。从个人经验来看,这种方法对我有用。至于实际传递值,我更喜欢将值传递给execute(),因为它对我来说看起来更干净。不过,我使用自己制作的类包装器,所以我根本不必这样做。
  • 当我们想要将所有值绑定为字符串 PDO::PARAM_STR 时,将值传递给执行中的绑定占位符。
  • 谢谢你们,但我尝试了 { $variable} 的方法,但仍然无法正常工作......数据类型有什么问题:因为我绑定 int 并在 2e 和3e参数对我来说是int,所以我不知道是什么问题。
  • @spencer7593 无论绑定方式如何,MySQL 都不能很好地处理这些类型吗?我总是使用execute() 方法传递值,我从来没有遇到过任何问题。
【解决方案2】:

我今天得到了解决方案:

仍然使用“LIMIT ? OFFSET ?”然后:

      $req->bindValue(1,$postId,\PDO::PARAM_INT);          
      $req->bindValue(2,$cmtNb,\PDO::PARAM_INT );               
      $req->bindValue(3,$r,\PDO::PARAM_INT);
      var_dump($r);

      $req->execute(); 

今天完美运行!谢谢你们。

【讨论】:

    猜你喜欢
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多