お目汚し失礼いたします。
ど素人の勉強ノートです。今回は、複合検索にページネーションを付けてみました。
長いです……絶対、もっと短くなると思います。
何か問題などございましたら、ご指摘いただけると大変うれしいです。
よろしくお願いします!
複合検索+ページネーション
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; ?>
参考
・俺的PHPメモ
・PHPでPDOを使ってAND検索(OR検索)を実装する
・PHPで作るページング機能
課題
長いこと……重複が見られるので、もっと短くできる、はず。
あとはPDO周りが不安なこと。prepareに変数を入れてはダメだという記事を読んでから、直で入れるようにしましたが、検索ワードをこのように突っ込んでも平気なのか、と。