使用 LIKE 进行 PDO 分页

Posted

技术标签:

【中文标题】使用 LIKE 进行 PDO 分页【英文标题】:PDO pagination with LIKE 【发布时间】:2020-08-18 08:05:17 【问题描述】:

以下 php SQL 代码显示错误 可恢复的致命错误:无法将 PDOStatement 类的对象转换为第 28 行 /home/customer/xxxx/fetch_data.php 中的字符串 我试图从表中显示产品信息filter 有两个$statement->execute();,一个是统计总搜索结果,另一个是显示当前页面的产品。 我是 PDO 方法的新手,不是整体编码方面的专家。

$filter_query = $stmt . 'LIMIT '.$start.', '.$limit.''; 引起了问题。 使用该功能和相关功能,代码可以工作并显示数据。但是如果我启用它,就会出现错误。

    $limit = '5';
$page = 1;
if($_POST['page'] > 1)

  $start = (($_POST['page'] - 1) * $limit);
  $page = $_POST['page'];

else

  $start = 0;

$search = "%samsung%";
    
    $stmt = $connect->prepare("SELECT * FROM filter WHERE product_name LIKE :needle");
    $stmt->bindParam(':needle', $search, PDO::PARAM_STR);
    ##
    
    ##
    
    
    $filter_query = $stmt . 'LIMIT '.$start.', '.$limit.'';
    
    $statement->execute();
    $total_data = $stmt->rowCount();
    
    $stmt = $connect->prepare($filter_query);
    $stmt->execute();
    $result = $stmt->fetchAll();
    $total_filter_data = $stmt->rowCount();
    
    $output = '
     <h3> '.$total_data.' results found </h3>  
    and display each product

我按照Your Common Sense 的建议尝试了以下代码,分页和总搜索结果计数工作正常,但没有显示任何产品。

    $limit = '5';
    $page = 1;
    if($_POST['page'] > 1)
    
      $start = (($_POST['page'] - 1) * $limit);
      $page = $_POST['page'];
    
    else
    
      $start = 0;
    
    $name=str_replace(' ', '%', $_POST['query']);
    $search = "%$name%";
    $base_sql = "SELECT %s FROM filter WHERE product_name LIKE ?";
    ##
    
    ##
    ####
    $count_sql = sprintf($base_sql, "count(*)");
    $stmt = $connect->prepare($count_sql);
    $stmt->execute([$search]);
    $total_data = $stmt->fetchColumn();
    ####
    $data_sql = $count_sql = sprintf($base_sql, "*")." LIMIT ?,?";
    $stmt = $connect->prepare($data_sql);
    $stmt->execute([$search, $start, $limit]);
    $result = $stmt->fetchAll();
    ##
    
    $output = '
   <h3> '.$total_data.' results found </h3>  ';
if($total_data > 0)

  foreach($result as $row)
  
            and display each product

使用下面这行代码会显示一些数据,但是分页不起作用。

$data_sql = sprintf($base_sql, "*");
    $stmt = $connect->prepare($data_sql);
    $stmt->execute([$search]);
    $result = $stmt->fetchAll();

【问题讨论】:

不要连接语句对象上的限制偏移量,在查询语句中(就在like子句之后)这样做,在这种情况下它应该有自己的占位符 @Kevin,如果你有时间,请举个例子。我试过 $stmt = $connect->prepare("SELECT * FROM filter WHERE product_name LIKE :needle LIMIT '.$start.', '.$limit.'");它显示零产品 你检查过执行查询是否会在数据库中抛出错误吗? @Nico Haase,不,实际上在我尝试添加“准备好的语句”功能之前,这段代码运行良好。它也正确计算页面数。 @NicoHaase 仅供参考,PDO 可以抛出异常,因此无需使用 $stmt->errorInfo(); 【参考方案1】:

这不是一项简单的任务,因为我们需要两次运行相同的查询,但差异很小。第一个查询将使用count(*) SQL 函数来获取匹配搜索条件的记录总数。第二个查询将选择带有 LIMIT 子句的实际字段来获取单页的数据。

$base_sql = "SELECT %s FROM filter WHERE product_name LIKE ?";

$count_sql = sprintf($base_sql, "count(*)");
$stmt = $connect->prepare($count_sql);
$stmt->execute([$search]);
$total = $stmt->fetchColumn();

$data_sql = $count_sql = sprintf($base_sql, "*")." LIMIT ?,?";
$stmt = $connect->prepare($data_sql);
$stmt->execute([$search, $start, $limit]);
$data = $stmt->fetchAll();

重要提示:为了使此代码正常工作,请确保您是connecting to mysql properly。正确的连接将允许 LIMIT 子句接受占位符,并且还会在出现任何问题时向您发出警告。

【讨论】:

我试过了,结果部分显示“找到 100 个结果”。数据库中只有 7 个条目,并且只有分页部分显示了这些数据。产品部分没有显示任何内容 更改 "count(*)");" 显示正确的页码,但仍然没有产品显示 关于产品部分,您的开始和限制变量应该具有合理的值 是的,start 和 limit 有值。编辑了我的问题。 @YourCommonSense, 为什么 $data_sql = $count_sql = sprintf($base_sql, "*")." LIMIT ?,?"; ... $count_sql 有必要吗?

以上是关于使用 LIKE 进行 PDO 分页的主要内容,如果未能解决你的问题,请参考以下文章

以多页分页打印所有数据

react-slick 自定义分页分页道具使用

单页分页问题中的多个角度材料表

一个视图中的 CI 多页分页,

当我在基于类的视图中应用过滤器时,如何在 django 中使用分页分页。网址总是不断变化我如何跟踪网址

梦内容页分页标题提取