【问题标题】:Check PDO query for result and then reuse the data检查 PDO 查询的结果,然后重用数据
【发布时间】:2019-02-14 14:55:15
【问题描述】:

我是 PDO 新手,正在将应用程序从 mysql_query 升级到 PDO。这肯定是一个愚蠢的问题 - 但我希望有人能帮我解决这个问题。

我需要查看 PDO 查询是否有任何数据: - 如果没有,则抛出错误 - 如果是,则检索该数据

我可以使用 mysql_num_rows 轻松做到这一点,但众所周知,这已被弃用。

问题是,一旦我检查了是否有任何数据,我就无法再检索它了。

检查运行良好,但是当尝试检索实际结果时,它是空的。我当然可以在检查后再次执行查询 - 但我宁愿避免必须运行两次查询。

try
{
    $result = $pdo2->prepare("SELECT first_name FROM users WHERE email = :email;");
    $result->bindValue(':email', $email);
    $result->execute();
    $data = $result->fetchAll();
}
catch (PDOException $e)
{
        $error = 'Error fetching user: ' . $e->getMessage();
        echo $error;
        exit();
}

if (!$data) {
    echo "No data!";
} else {
    echo "Data found!";
}           

$row = $result->fetch();
    echo "First name: " . $row['first_name'];

我该如何解决这个问题? 我尝试将 $result 分配给另一个变量($test = $result),然后改为对 $test 变量运行数据检查 - 但即便如此,$result 变量在运行检查后仍然没有返回任何数据(见注释行):

try
{
    $result = $pdo2->prepare("SELECT first_name FROM users WHERE email = :email;");
    $result->bindValue(':email', $email);
    $result->execute();
    $test = $result; // Duplicating the variable
    $data = $test->fetchAll(); // Running the check on the duplicated variable
}
catch (PDOException $e)
{
        $error = 'Error fetching user: ' . $e->getMessage();
        echo $error;
        exit();
}

if (!$data) {
    echo "No data!";
} else {
    echo "Data found!";
}           

$row = $result->fetch(); // Still doesn't return the result!
    echo "First name: " . $row['first_name'];

这真的让我很头疼...我认为某处有一个简单的解决方案,我只是看不到它。请帮忙!

【问题讨论】:

  • 您在使用fetchAll 时已经检索了所有数据,因此当您尝试使用fetch 时,没有什么可检索的了。 fetchAll 将是一个数组,其中可能包含一行或多行数据(因为您的查询没有将结果限制为 1 行)。
  • 您可能还想使用$data = $test->fetchAll(PDO::FETCH_ASSOC):。为了只返回一个带有列名的关联数组。请参阅here 了解更多信息
  • 仅供参考,您可以直接在执行调用中传递变量,避免单独调用绑定。 $result->execute([':email'=>$email]);
  • mysql_num_rows() 的 PDO 等效项是 $result->rowCount()
  • 将对象分配给不同的变量不会产生副本,因此您对一个变量所做的任何事情都会影响另一个变量。只有数组被复制,而不是对象。

标签: php mysql pdo


【解决方案1】:

$result->fetch() 仅获取尚未获取的行。由于您使用 $result->fetchAll() 获取了所有内容,因此什么都没有了。

如果你想要第一行,你可以使用:

$row = data[0];

如果要处理所有行,请使用:

foreach ($data as $row)

您可以使用rowCount() 方法,而不是获取所有内容。

if (!$result->rowCount()) {
    echo "No data";
} else {
    echo "Data found!";
}

在 PDO 中使用 rowCount()SELECT 查询有一些注意事项,但我认为它通常适用于 MySQL。

【讨论】:

    【解决方案2】:

    当您使用 try/catch 块时,您可以引发自己的异常并捕获 PDO 抛出的异常 - 因此您可以执行以下操作:

    try{
    
        $sql='SELECT first_name FROM users WHERE email = :email;';
        $stmt = $pdo2->prepare( $sql );
    
        if( !$stmt )throw new Exception('Failed to prepare sql statement');
        $result=$stmt->execute( array( ':email' => $email ) );
    
        if( !$result )throw new Exception('Failed to get any results');
        $rows = $stmt->rowCount();
    
        if( $rows == 0 )throw new Exception('Empty recordset');
    
        while( $rs=$stmt->fetch( PDO::FETCH_OBJ ) ){
            echo $rs->firstname;
        }
    
    }catch ( PDOException $e ){
        exit( 'Error fetching user: ' . $e->getMessage() );
    }
    

    【讨论】:

      【解决方案3】:

      您始终可以获取单独的行,对于第一行,检查数据是否返回,如果没有则处理。然后进入do...while()循环,处理数据,然后在循环结束时读取下一行...

      try
      {
          $result = $pdo2->prepare("SELECT first_name FROM users WHERE email = :email;");
          $result->bindValue(':email', $email);
          $result->execute();
          $row = $result->fetch();  // Fetch first row of data
      
          if (!$row) {
              echo "No data!";
          } else {
              echo "Data found!";
      
              do { 
                  echo "First name: " . $row['first_name'];
              }
              while ($row = $result->fetch());
          }           
      }
      catch (PDOException $e)
      {
              $error = 'Error fetching user: ' . $e->getMessage();
              echo $error;
              exit();
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-04-10
        • 2021-09-09
        • 2016-09-03
        • 1970-01-01
        • 2010-11-25
        • 1970-01-01
        • 1970-01-01
        • 2020-10-11
        相关资源
        最近更新 更多