PDO⑯ INを使用したサンプル
INを使用したサンプルシステムをご紹介します。
データは別の記事で使用しているものを使用します。
以下リンクの下部にある「動作環境について」の項目から環境を作成してください。
SQL練習問題 – 一覧まとめ
■要件
- サッカー選手の一覧が表示される
- チェックを入れて検索すると、選択したポジションの選手が表示される
- チェックを入れずに検索した場合はヒットしない
- チェックは検索ボタンを押下後もチェックが状態が維持される
■プログラム
※デザインにBootstrap5を使用しています。
pdo_in.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 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | <?php try { // 接続処理 $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.position IN (%s) EOM; // チェックされたポジションを配列で取得。取得できない場合は、空の要素を1つ持つ(SQLの構文エラー対策) $positions = isset( $_GET [ 'positions' ]) ? $_GET [ 'positions' ] : array ( '' ); // 配列の要素の数だけIN内の?をカンマ区切りで生成し%s部分をprintf関数で置換 $sql = sprintf( $sql , substr ( str_repeat ( ',?' , count ( $positions )), 1)); $stmt = $dbh ->prepare( $sql ); // ?マークをバインド for ( $i = 0; $i < count ( $positions ); $i ++){ $stmt ->bindParam( $i + 1, $positions [ $i ]); } $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>INを使用したサンプルシステム</title> </head> <body> <div class = "container" > <div class = "h1 mb-3" >INを使用したサンプルシステム</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" > <label class = "form-check-label" for = "" >ポジション</label> <div class = "col-12" > <div class = "form-check form-check-inline" > <input class = "form-check-input" type= "checkbox" name= "positions[]" value= "GK" id= "GK" <?php print (in_array( 'GK' , $positions ) ? 'checked' : '' ) ?>> <label class = "form-check-label" for = "GK" >ゴールキーパー(GK)</label> </div> <div class = "form-check form-check-inline" > <input class = "form-check-input" type= "checkbox" name= "positions[]" value= "DF" id= "DF" <?php print (in_array( 'DF' , $positions ) ? 'checked' : '' ) ?>> <label class = "form-check-label" for = "DF" >ディフェンス(DF)</label> </div> <div class = "form-check form-check-inline" > <input class = "form-check-input" type= "checkbox" name= "positions[]" value= "MF" id= "MF" <?php print (in_array( 'MF' , $positions ) ? 'checked' : '' ) ?>> <label class = "form-check-label" for = "MF" >ミッドフィルダー(MF)</label> </div> <div class = "form-check form-check-inline" > <input class = "form-check-input" type= "checkbox" name= "positions[]" value= "FW" id= "FW" <?php print (in_array( 'FW' , $positions ) ? 'checked' : '' ) ?>> <label class = "form-check-label" for = "FW" >フォワード(FW)</label> </div> </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> |
■解説
30行目
チェックなしの場合はarray('');となり、空文字の要素が1つ追加されます。
これがないと、発行されるSQLのINが
1 | IN () |
となってSQLの構文エラーとなってしまいます。
空文字を追加することにより、発行されるSQLが
1 | IN ( '' ) |
となり、エラーにならなくなります。