PDO⑭ LIKEを使用したサンプル
LIKEを使用したサンプルシステムをご紹介します。
データは別の記事で使用しているものを流用します。
以下リンクの下部にある「動作環境について」の項目から環境を作成してください。
SQL練習問題 – 一覧まとめ
■要件
- サッカー選手の一覧が表示される
- 検索欄に名前を入力し検索すると、選手名の部分一致で検索ができる
- 検索ボタンを押下後も入力した名前が入力欄に維持される
■プログラム
※デザインにBootstrap5を使用しています。
pdo_like.php
<?php
try {
// 入力された検索したい名前を取得
$playerName = isset($_GET['playerName']) ? $_GET['playerName'] : '';
// 接続処理
$dsn = 'mysql:host=localhost;dbname=worldcup2014';
$user = 'root';
$password = '';
$dbh = new PDO($dsn, $user, $password);
// SELECT文を発行
$sql = <<<EOM
SELECT
p.id AS playerId
, p.name AS playerName
, c.name AS countryName
, p.club
, p.position
, p.uniform_num AS uniformNum
, p.birth
, p.height
, p.weight
FROM
players p JOIN countries c
ON p.country_id = c.id
WHERE
p.name LIKE :playerName
EOM;
$stmt = $dbh->prepare($sql);
$bindPlayerName = '%'.$playerName.'%'; // 検索したい名前の前後に%を付与
$stmt->bindParam(':playerName', $bindPlayerName, PDO::PARAM_STR);
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_OBJ); // レコードを取得
// 接続切断
$dbh = null;
} catch (PDOException $e) {
print $e->getMessage() . "<br/>";
die();
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
<title>LIKEを使用したサンプルシステム</title>
</head>
<body>
<div class="container">
<div class="h1 mb-3">LIKEを使用したサンプルシステム</div>
<div class="card mb-3">
<div class="card-header bg-primary text-white">
検索
</div>
<div class="card-body">
<form action="">
<div class="row mb-3">
<div class="col-6">
<label for="playerName" class="form-label">選手の名前</label>
<input type="playerName" class="form-control" id="playerName" name="playerName" placeholder="" value="<?php print($playerName); ?>">
</div>
</div>
<button type="submit" class="btn btn-primary">検 索</button>
</form>
</div>
</div>
<table class="table table-striped">
<tr>
<th>ID</th>
<th>名前</th>
<th>国名</th>
<th>所属クラブ</th>
<th>ポジション</th>
<th>背番号</th>
<th>生年月日</th>
<th>身長</th>
<th>体重</th>
</tr>
<?php
if($rows) {
foreach($rows as $row){
?>
<tr>
<td><?php print($row->playerId) ?></td>
<td><?php print($row->playerName) ?></td>
<td><?php print($row->countryName) ?></td>
<td><?php print($row->club) ?></td>
<td><?php print($row->position) ?></td>
<td><?php print($row->uniformNum) ?></td>
<td><?php print($row->birth) ?></td>
<td><?php print($row->height) ?>cm</td>
<td><?php print($row->weight) ?>kg</td>
</tr>
<?php
}
}
?>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" crossorigin="anonymous"></script>
</body>
</html>
■解説
ポイントは33行目。
入力された値の前後に%を文字列結合しています。
これにより
WHERE p.name LIKE '%入力値%'
とバインドされます。
バインドする際、前後に自動でシングルクォートが付与されるため、入力値に%を結合しなければいけません。
間違い例
// 中略
WHERE
p.name LIKE %:playerName%
EOM;
// 中略
$stmt->bindParam(':playerName', $bindPlayerName, PDO::PARAM_STR);
// 中略
この場合、発行されるSQLは
WHERE p.name LIKE %'入力値'%
となり、構文エラーとなってしまいます。
