質問編集履歴

2 $dbのreturnを削除し、以下を可変長プレースホルダの形に書き換えました。また、HTMLのhtmlspecialchars部分をphp内に記述してみました。

TaraIkura

TaraIkura score 1

2019/11/27 00:32  投稿

MySQL、PHPで複数の項目から部分検索ができる検索システム
### 前提・実現したいこと
以前使っていたMySQL、PHPで複数の項目から検索システムをPDO、bindValueを使って更新しているのですが
実装すると上手くいきません。お力を貸していただけると幸いです。
列の項目には複数の文字が含まれるためLIKEの部分検索を取り入れています。
### 以前のPHP&HTML コード
```
//search.phpのコード
function getUserData( $params ) {
 //DBの接続情報
 include_once( 'database.php' );
 //DBコネクタを生成
 $Mysqli = new mysqli( $dsn, $usr, $passwd );
 $Mysqli->set_charset( 'utf8' );
 $query = "SELECT * FROM TABLE1";
 //接続状況チェック
 if ( $Mysqli->connect_error ) {
   error_log( $Mysqli->connect_error );
   exit;
 }
 //入力された検索条件からSQl文を生成
 $where = [];
 if ( !empty( $params[ 'search_name' ] ) ) {
   $where[] = "search_name like '%{$params['search_name']}%'";
 }
 if ( !empty( $params[ 'color' ] ) ) {
   $where[] = "color like '%{$params['color']}%'";
 }
 if ( !empty( $params[ 'category' ] ) ) {
   $where[] = "category like '%{$params['category']}%'";
 }
 if ( $where ) {
   $whereSql = implode( " AND ", $where );
   $sql = "select * from TABLE1 where " . $whereSql;
 } else {
   $sql = "select * from TABLE1";
 }
 $query .= $where;
 //SQL文を実行する
 $UserDataSet = $Mysqli->query( $sql );
 //扱いやすい形に変える
 $result = [];
 while ( $row = $UserDataSet->fetch_assoc() ) {
   $result[] = $row;
 }
 return $result;
}
//ーーー HTML側 ーーー
<!doctype html>
<?php
include_once( 'search.php' );
$userData = getUserData( $_POST );
?>
<html>
<head>
</head>
<body>
  //キーワード検索、チェックボックス、セレクションの3タイプで検索
  <input name="search_name" value="<?php echo isset($_POST['search_name']) ? htmlspecialchars($_POST['search_name']) : '' ?>">
  <input type="checkbox" name="color" value="白" <?php echo isset($_POST['color']) && $_POST['color'] == '白' ? 'selected' : '' ?>><label for="color">白</label>//他省略
  <select name="category">
  <option value="0" <?php echo empty($_POST['category']) ? 'selected' : '' ?>>分類A</option>//他省略
  </select>
  <button type="submit" name="search">検索</button>
  
//上記項目以外のデータで結果表示
  <?php if(isset($userData)): ?>
  <?php foreach($userData as $row): ?>
    <img src="../<?php echo htmlspecialchars($row['img']); ?>">
    <?php echo htmlspecialchars($row['original_name']) ?>
  <?php endforeach; ?>
  <?php endif; ?>
</body>
</html>
```
### 改定後
```
//search.phpのコード
function getUserData() {
 //DBの接続情報
 include_once( 'database.php' );
 //DBコネクタを生成
 try {
  try {
   $db = new PDO( $dsn, $usr, $passwd );
   $db->exec( 'SET NAMES utf8' );  
   $db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
   $db->setAttribute( PDO::ATTR_EMULATE_PREPARES, false );
 } catch ( PDOException $e ) {  
   die( "接続エラー1: {$e->getMessage()}" );  
 }  
 return $db;  
 //ここまでは接続確認済です。  
   
 //queryのデータ  
 try {  
  $query = "SELECT * FROM TABLE1 WHERE search_name LIKE ? ESCAPE '!' AND color LIKE ? ESCAPE '!' AND category LIKE ? ESCAPE '!' ";  
 $qPart = array_fill( 0, count( $userData ), "(?, ?, ?, ?, ?)" );  
 $query .= implode( ",", $qPart );  
 $search_name = $_POST[ 'search_name' ];
 $color = $_POST[ 'color' ];
 $category = $_POST[ 'category' ];
  $q = ( string )filter_input( INPUT_GET, 'q' );
  $maxKeywords = -1;
  $keywords = preg_split( '/(?:\p{Z}|\p{Cc})++/u', $q, $maxKeywords, PREG_SPLIT_NO_EMPTY );
 //SQL文を実行する
 $UserDataSet = $db->prepare( $query );
 $i = 1;
 foreach ( $userData as $row ) { //bind the values one by one
   $stmt->bindValue( $i++, $row[ '%' . preg_replace( '/(?=[!_%])/', '!', $search_name ) . '%' ], PDO::PARAM_STR );
   $stmt->bindValue( $i++, $row[ '%' . preg_replace( '/(?=[!_%])/', '!', $color ) . '%' ], PDO::PARAM_STR );
   $stmt->bindValue( $i++, $row[ '%' . preg_replace( '/(?=[!_%])/', '!', $category ) . '%' ], PDO::PARAM_STR );
 }
 $UserDataSet->execute();
 //扱いやすい形に変える
 $result = [];
 while ( $row = $UserDataSet->fetch(PDO::FETCH_ASSOC)) {
   $result[] = $row;
 }
 return $result;
   if ( $keywords ) {
     foreach ( $keywords as $keyword ) {
       $holders[] = "((search_name LIKE ? ESCAPE '!') OR (color LIKE ? ESCAPE '!') OR (category LIKE ? ESCAPE '!'))";
       $values[] = $values[] = '%' . preg_replace( '/(?=[!_%])/', '!', $keyword ) . '%';
     }
     $sql = "SELECT * FROM TABLE1 WHERE (' . implode(' AND ', $holders) . ')";
     $UserDataSet = $bd->prepare( $sql );
     $UserDataSet->execute( $values );
     $userData = $UserDataSet->fetchAll( PDO::FETCH_ASSOC );
   }
   print '接続に成功しました';
 } catch ( PDOException $e ) {
   die( "接続エラー2: {$e->getMessage()}" );
   header( 'Content-Type: text/plain; charset=UTF-8', true, 500 );
   exit( '接続できませんでした' . $e->getMessage() );
 }
 function h( $str ) {
   return htmlspecialchars( $str, ENT_QUOTES, 'UTF-8' );
 }
}
//ーーー HTML側 ーーー
<!doctype html>
<?php
include_once( 'search.php' );
$userData = getUserData( $_POST );
$userData = getUserData( $_GET );
?>
<html>
<head>
</head>
<body>
  //キーワード検索、チェックボックス、セレクションの3タイプで検索
  <input name="search_name" value="<?php echo isset($search_name) ? htmlspecialchars($search_name) : '' ?>">
  <input name="search_name" value="<?php echo isset($search_name) ?= h($search_name) : '' ?>">
  <input type="checkbox" name="color" value="白" <?php echo isset($color) && $color == '白' ? 'selected' : '' ?>><label for="color">白</label>//他省略
  <select name="category">
  <option value="0" <?php echo empty($category) ? 'selected' : '' ?>>分類A</option>//他省略
  </select>
  <button type="submit" name="search">検索</button>
  
//上記項目以外のデータで結果表示
  <?php if(isset($userData)): ?>
  <?php foreach($userData as $row): ?>
    <img src="../<?php echo htmlspecialchars($row['img']); ?>">
    <?php echo htmlspecialchars($row['original_name']) ?>
  <?php endforeach; ?>
  <?php endif; ?>
  //$holders[]に指定した列以外のデータで結果表示
  <?php if (isset($err)) : ?>
     <p><?= h($err->getMessage()); ?></p>
   <?php endif; ?>
   <?php if (0 < count($userData)): ?>
     <?php foreach ($userData as $row) : ?>
       <div class="box_warp">
         <div><img class="circular" height="80" src="../<?= h($row['img']); ?>"></div>
         <div class="break-word"><?= h($row['original_name']); ?></div>
     </div>
     <?php endforeach; ?>
   <?php endif; ?>
</body>
</html>
```
  • PHP

    27961 questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • HTML

    14638 questions

    HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

  • MySQL

    8288 questions

    MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

  • PDO

    444 questions

    PDO(PHP Data Objects)はPHPのデータベース抽象化レイヤーです。

  • 検索

    194 questions

    検索は、あるデータの集まりの中から 目的のデータを見つけ出すことです。

1 1. 接続が確認できている部分にコメント追加 2. database.phpに設定した$usertable をテーブル名に変更 3. ->execute();の位置を変更

TaraIkura

TaraIkura score 1

2019/11/25 10:14  投稿

MySQL、PHPで複数の項目から部分検索ができる検索システム
### 前提・実現したいこと
以前使っていたMySQL、PHPで複数の項目から検索システムをPDO、bindValueを使って更新しているのですが
実装すると上手くいきません。お力を貸していただけると幸いです。
列の項目には複数の文字が含まれるためLIKEの部分検索を取り入れています。
### 以前のPHP&HTML コード
```
//search.phpのコード
function getUserData( $params ) {
 //DBの接続情報
 include_once( 'database.php' );
 //DBコネクタを生成
 $Mysqli = new mysqli( $dsn, $usr, $passwd );
 $Mysqli->set_charset( 'utf8' );
 $query = "SELECT * FROM $usertable";
 $query = "SELECT * FROM TABLE1";
 //接続状況チェック
 if ( $Mysqli->connect_error ) {
   error_log( $Mysqli->connect_error );
   exit;
 }
 
 //入力された検索条件からSQl文を生成
 $where = [];
 if ( !empty( $params[ 'search_name' ] ) ) {
   $where[] = "search_name like '%{$params['search_name']}%'";
 }
 if ( !empty( $params[ 'color' ] ) ) {
   $where[] = "color like '%{$params['color']}%'";
 }
 if ( !empty( $params[ 'category' ] ) ) {
   $where[] = "category like '%{$params['category']}%'";
 }
 if ( $where ) {
   $whereSql = implode( " AND ", $where );
   $sql = "select * from $usertable where " . $whereSql;
   $sql = "select * from TABLE1 where " . $whereSql;
 } else {
   $sql = "select * from $usertable";
   $sql = "select * from TABLE1";
 }
 $query .= $where;
 //SQL文を実行する
 $UserDataSet = $Mysqli->query( $sql );
 //扱いやすい形に変える
 $result = [];
 while ( $row = $UserDataSet->fetch_assoc() ) {
   $result[] = $row;
 }
 return $result;
}
//ーーー HTML側 ーーー
<!doctype html>
<?php
include_once( 'search.php' );
$userData = getUserData( $_POST );
?>
<html>
<head>
</head>
<body>
  //キーワード検索、チェックボックス、セレクションの3タイプで検索
  <input name="search_name" value="<?php echo isset($_POST['search_name']) ? htmlspecialchars($_POST['search_name']) : '' ?>">
  <input type="checkbox" name="color" value="白" <?php echo isset($_POST['color']) && $_POST['color'] == '白' ? 'selected' : '' ?>><label for="color">白</label>//他省略
  <select name="category">
  <option value="0" <?php echo empty($_POST['category']) ? 'selected' : '' ?>>分類A</option>//他省略
  </select>
  <button type="submit" name="search">検索</button>
  
//上記項目以外のデータで結果表示
  <?php if(isset($userData)): ?>
  <?php foreach($userData as $row): ?>
    <img src="../<?php echo htmlspecialchars($row['img']); ?>">
    <?php echo htmlspecialchars($row['original_name']) ?>
  <?php endforeach; ?>
  <?php endif; ?>
</body>
</html>
```
### 改定後
```
//search.phpのコード
function getUserData() {
 //DBの接続情報
 include_once( 'database.php' );
 //DBコネクタを生成
 try {
   $db = new PDO( $dsn, $usr, $passwd );
   $db->exec( 'SET NAMES utf8' );
   $db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
   $db->setAttribute( PDO::ATTR_EMULATE_PREPARES, false );
 } catch ( PDOException $e ) {
   die( "接続エラー: {$e->getMessage()}" );
   die( "接続エラー1: {$e->getMessage()}" );
 }
 return $db;
 //ここまでは接続確認済です。
 
 //queryのデータ
 $query = "SELECT * FROM $usertable WHERE search_name LIKE ? AND color LIKE ? AND category LIKE ?";
 try {
  $query = "SELECT * FROM TABLE1 WHERE search_name LIKE ? ESCAPE '!' AND color LIKE ? ESCAPE '!' AND category LIKE ? ESCAPE '!' ";
 $qPart = array_fill( 0, count( $userData ), "(?, ?, ?, ?, ?)" );
 $query .= implode( ",", $qPart );
 $search_name = $_POST[ 'search_name' ];
 $color = $_POST[ 'color' ];
 $category = $_POST[ 'category' ];
 //SQL文を実行する
 $UserDataSet = $db->prepare( $query );
 $i = 1;
 foreach ( $userData as $row ) { //bind the values one by one
   $UserDataSet->bindValue( $i++, $row[ '%' . addcslashes( $search_name, '\_%' ) . '%' ], PDO::PARAM_STR );
   $UserDataSet->bindValue( $i++, $row[ '%' . addcslashes( $color, '\_%' ) . '%' ], PDO::PARAM_STR );
   $UserDataSet->bindValue( $i++, $row[ '%' . addcslashes( $category, '\_%' ) . '%' ], PDO::PARAM_STR );
   $stmt->bindValue( $i++, $row[ '%' . preg_replace( '/(?=[!_%])/', '!', $search_name ) . '%' ], PDO::PARAM_STR );
   $stmt->bindValue( $i++, $row[ '%' . preg_replace( '/(?=[!_%])/', '!', $color ) . '%' ], PDO::PARAM_STR );
   $stmt->bindValue( $i++, $row[ '%' . preg_replace( '/(?=[!_%])/', '!', $category ) . '%' ], PDO::PARAM_STR );
 }
 $UserDataSet->execute();  
 //扱いやすい形に変える
 $result = [];
 while ( $row = $UserDataSet->fetch(PDO::FETCH_ASSOC)) {
   $result[] = $row;
 }
 return $result;
 $UserDataSet->execute();
 } catch ( PDOException $e ) {
   die( "接続エラー2: {$e->getMessage()}" );
 }
}
//ーーー HTML側 ーーー
<!doctype html>
<?php
include_once( 'search.php' );
$userData = getUserData( $_POST );
?>
<html>
<head>
</head>
<body>
  //キーワード検索、チェックボックス、セレクションの3タイプで検索
  <input name="search_name" value="<?php echo isset($search_name) ? htmlspecialchars($search_name) : '' ?>">
  <input type="checkbox" name="color" value="白" <?php echo isset($color) && $color == '白' ? 'selected' : '' ?>><label for="color">白</label>//他省略
  <select name="category">
  <option value="0" <?php echo empty($category) ? 'selected' : '' ?>>分類A</option>//他省略
  </select>
  <button type="submit" name="search">検索</button>
  
//上記項目以外のデータで結果表示
  <?php if(isset($userData)): ?>
  <?php foreach($userData as $row): ?>
    <img src="../<?php echo htmlspecialchars($row['img']); ?>">
    <?php echo htmlspecialchars($row['original_name']) ?>
  <?php endforeach; ?>
  <?php endif; ?>
</body>
</html>
```
  • PHP

    27961 questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • HTML

    14638 questions

    HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

  • MySQL

    8288 questions

    MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

  • PDO

    444 questions

    PDO(PHP Data Objects)はPHPのデータベース抽象化レイヤーです。

  • 検索

    194 questions

    検索は、あるデータの集まりの中から 目的のデータを見つけ出すことです。

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る