PDO⑭ LIKEを使用したサンプル
LIKEを使用したサンプルシステムをご紹介します。
データは別の記事で使用しているものを流用します。
以下リンクの下部にある「動作環境について」の項目から環境を作成してください。
SQL練習問題 – 一覧まとめ
■要件
- サッカー選手の一覧が表示される
- 検索欄に名前を入力し検索すると、選手名の部分一致で検索ができる
- 検索ボタンを押下後も入力した名前が入力欄に維持される
■プログラム
※デザインにBootstrap5を使用しています。
pdo_like.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | <?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行目。
入力された値の前後に%を文字列結合しています。
これにより
1 | WHERE p. name LIKE '%入力値%' |
とバインドされます。
バインドする際、前後に自動でシングルクォートが付与されるため、入力値に%を結合しなければいけません。
間違い例
1 2 3 4 5 6 7 | // 中略 WHERE p.name LIKE %:playerName% EOM; // 中略 $stmt ->bindParam( ':playerName' , $bindPlayerName , PDO::PARAM_STR); // 中略 |
この場合、発行されるSQLは
1 | WHERE p. name LIKE % '入力値' % |
となり、構文エラーとなってしまいます。