PDO で SELECT の結果数を取得する

SELECT 文で取得した結果の数が取れなかったので調べてみたら、次のような注意書きがあった。

PDOStatement::rowCount() は 相当する PDOStatement オブジェクトによって実行された 直近の DELETE, INSERT, UPDATE 文によって作用した行数を返します。
関連する PDOStatement によって実行された直近の SQL ステートメントSELECT 文の場合、いくつかのデータベースは文によって返された 行数を返すかも知れません。しかしながら、 この振る舞いは全てのデータベースで保証されていません。さまざまな場所で使用するアプリケーションでは、 これに頼ってはいけません。

http://php.net/manual/ja/pdostatement.rowcount.php

そして、「SELECT 文によって返された行をカウントする」ということで、

ほとんどのデータベースでは、PDOStatement::rowCount() は SELECT 文によって作用した行数を返しません。代わりに、 PDO::query() を使って 意図する SELECT 文として同様の述部を持つ SELECT COUNT(*) 文を発行し、PDOStatement::fetchColumn() を使って返される行数を取得することができます。 そうすることで、アプリケーションは正しい動作をすることができます。

http://php.net/manual/ja/pdostatement.rowcount.php
<?php
$sql = "SELECT COUNT(*) FROM fruit WHERE calories > 100";
if ($res = $conn->query($sql)) {

    /* SELECT 文にマッチする行数をチェックする */
  if ($res->fetchColumn() > 0) {

        /* 実際の SELECT 文を発行し、結果を処理する */
         $sql = "SELECT name FROM fruit WHERE calories > 100";

         foreach ($conn->query($sql) as $row) {
           print "Name: " .  $row['NAME'] . "\n";
         }
    }
    /* 行がマッチしなかった場合 -- 他に何かをする */
  else {
      print "No rows matched the query.";
    }
}

$res = null;
$conn = null;
?>

他に方法はないのか

SELECT文で rowCount() が使えるか?」で下記のコードをサンプルが提示されている。

<?php
// DB_CONNECT_STR 定数には、それぞれのDBで必要な接続情報が定義されているとして読んで下さい。
try {
    $db = new PDO(DB_CONNECT_STR);
    $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true); //←この行追加
    $stmt = $db->query('SELECT * FROM hoge_table ');
    var_dump($stmt->rowCount());
 } catch (PDOException $e){
    die($e->getMessage());
 }
?>

上記のコードでは、PDO::prepare を利用しているが、PDO::prepare でも取得結果数を取得できる。
ただし、

PDO::MYSQL_ATTR_USE_BUFFERED_QUERY (integer)
PDOStatement でこの属性を TRUE に設定すると、 MySQL ドライバはバッファ版の MySQL API を使用します。 移植性の高いコードを書くには、代わりに PDOStatement::fetchAll() を使用すべきです。

http://php.net/manual/ja/ref.pdo-mysql.php

とあるので、こう書くべきだろう。

<?php
$id = 1;
try {
    $db = new PDO(DB_CONNECT_STR);
    $sth->prepare('SELECT `id` FROM `hoge_table` WHERE `id` = :id');
    $sth->bindParam(':id', $id, PDO::PARAM_INT);
    $sth->execute();
 } catch (PDOException $e){
    die($e->getMessage());
 }

$resultSet = $sth->fetchAll();
$resultNum = count($resultSet);

if (0 < $resultNum) {
    do_something();
} else {
    ...
}
?>