【PHP】PDOで、複合検索+ページネーション

お目汚し失礼いたします。
ど素人の勉強ノートです。今回は、複合検索にページネーションを付けてみました。
長いです……絶対、もっと短くなると思います。
何か問題などございましたら、ご指摘いただけると大変うれしいです。
よろしくお願いします！

## 複合検索+ページネーション

```php:sample.php
<?php
// ページネーション　
const PER_PAGE = 10;// 1ページに表示するデータ数
$page = "";
if(empty($page)){
    $page = 1;
}
if(!empty($_GET['page'])){
    if(preg_match('/^[1-9][0-9]*$/', $_GET['page'])){
        $page = (int)$_GET['page'];
    } else {
    $page = "";
    }
}
$offset = PER_PAGE * ($page - 1);
echo $offset;
echo "/".PER_PAGE;


// 複合検索ワードの処理開始
$q = filter_input(INPUT_GET, 'q');
if(!empty($q)){
    $words = explode(" ", str_replace("　", " ", trim($q)));
} else {
$words = array();
}
//
$tmp = array();
$arr = array();
foreach($words as $key=>$word){
    if($word === ''){ continue;}
    $tmp[$key] = sprintf('(keyword like :word%d)', $key);
    $arr[$key] ='%' . addcslashes($word, '\_%') . '%';
}
if (count($tmp) > 0){
    $pdo = getDb();
    $stmt = $pdo->prepare('SELECT * FROM tables WHERE '.implode('and', $tmp).' ORDER BY id desc LIMIT '.$offset.','.PER_PAGE);
    foreach($arr as $key=>$word){
        $stmt->bindValue(sprintf(':word%d', $key), $arr[$key], PDO::PARAM_STR);
    }// ここをbindParamにすると失敗します。
    $stmt->execute();
    $pdo = NULL;

// 検索された全データの数を求める
    $db = getDb();
    $stt = $db->prepare('SELECT * FROM tables WHERE '.implode('and', $tmp).' ORDER BY id desc');
    foreach ($arr as $key => $word) {
    $stt->bindParam(sprintf(':word%d', $key), $arr[$key], PDO::PARAM_STR);
}
    $stt->execute();
    $pdo = NULL;
    $resultSet = $stt->fetchAll();
    $total = count($resultSet);
    $totalPages = ceil($total / PER_PAGE);
    echo "totalpage:".$totalPages;


} else {// 検索ワードが挿入されなかった場合、すべてのデータをページ送りで出力する
$pdo = getDb();
$stmt = $pdo->prepare('SELECT * FROM tables ORDER BY id desc LIMIT '.$offset.','.PER_PAGE);
$stmt->execute();
    $pdo = NULL;
// 総数を出す
    $db = getDb();
    $stt = $db->prepare('SELECT * FROM tables ORDER BY id desc');
    $stt->execute();
    $pdo = NULL;
    $resultSet = $stt->fetchAll();
    $total = count($resultSet);
    $totalPages = ceil($total / PER_PAGE);
}
?>
<html>
<body>
// 検索窓を設置
        <form action="" method="GET">
        <input type="text" name="q" size="20"  value="<?php e($q); ?>">
        <input type="submit" value="search">
        </form>
// 結果をtableで出力
        <table>
            <tr>
                <th>セリフ</th>
                <th>作品タイトル</th>
                <th>キーワード</th>
                <th>編集</th>
            </tr>
                <?php while($row = $stmt->fetch(PDO::FETCH_ASSOC)): ?>
                <?php printf('<tr><td>%s</td><td>%s</td><td>%s</td>', htmlspecialchars($row['title']), htmlspecialchars($row['author']), htmlspecialchars($row['keyword'])); ?>
                <td><a href="edit.php?id=<?php print(htmlspecialchars($row['id'])); ?>">◆</a></td></tr>
                <?php endwhile; ?>
            </tr>
        </table>
        <div>// ページリンク設定
            <?php if($page > 1): ?>
            <a href="?q=<?php if(!empty($q)){ echo $q; } ?>&page=<?php echo $page-1; ?>">前へ</a>
            <?php endif; ?>
            <?php for ($i = 1; $i <= $totalPages; $i++): ?>
                <?php if ($page == $i): ?>
                    <?php printf('%d', htmlspecialchars($i)); ?>
                <?php else: ?>
                    <?php printf('<a href="?q=%s&page=%d">%d</a>',htmlspecialchars($q), htmlspecialchars($i), htmlspecialchars($i)); ?>
                <?php endif; ?>
            <?php endfor; ?>
            <?php if($page < $totalPages): ?>
                <a href="?q=<?php if(!empty($q)){ echo $q; } ?>&page=<?php echo $page+1; ?>">次へ</a>
            <?php endif; ?>

```

## 参考
・[俺的ＰＨＰメモ](http://rasukaru55.sitemix.jp/or_kensaku.php)
・[PHPでPDOを使ってAND検索(OR検索)を実装する](http://qiita.com/petitviolet/items/a3e96a44898bebcb07ce)
・[PHPで作るページング機能](http://dotinstall.com/lessons/paging_php_v2)

## 課題
長いこと……重複が見られるので、もっと短くできる、はず。
あとはPDO周りが不安なこと。prepareに変数を入れてはダメだという記事を読んでから、直で入れるようにしましたが、検索ワードをこのように突っ込んでも平気なのか、と。