質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

PHP

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

XAMPP

XAMPP(ザンプ)は、ウェブアプリケーションの実行に必要なフリーソフトウェアをパッケージングしたApacheディストリビューションです。 XAMPPひとつインストールするだけで、Apache、MySQL、PHP、Perlなどのソフトウェアと、 phpMyAdminなどの管理ツール、SQLiteなどのソフトウェアやライブラリモジュールなどを利用することが可能です。

Q&A

解決済

5回答

7840閲覧

変数を用いたLIKE検索ができない

koguchi

総合スコア21

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

PHP

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

XAMPP

XAMPP(ザンプ)は、ウェブアプリケーションの実行に必要なフリーソフトウェアをパッケージングしたApacheディストリビューションです。 XAMPPひとつインストールするだけで、Apache、MySQL、PHP、Perlなどのソフトウェアと、 phpMyAdminなどの管理ツール、SQLiteなどのソフトウェアやライブラリモジュールなどを利用することが可能です。

0グッド

2クリップ

投稿2020/02/08 17:18

###実現したいこと
PHPでのLIKE検索でinput type="text"に入力された文字列を使い、SQLでデータベースからデータを引っ張ってきたい。
万が一不足している情報がありましたら、教えていただけますと幸いです。

PHP

1 $sql='SELECT * FROM anketo WHERE nickname LIKE "/*ここに変数*/" ';

発生している問題・エラーメッセージ

Parse error: syntax error, unexpected '"' in C:\xampp\htdocs\phpkiso\kensaku.php on line 19

該当のソースコード

HTML

1<!DOCTYPE html> 2<html lang="jp"> 3 4<head> 5 <meta charset="UTF-8"> 6 <title>php基礎</title> 7</head> 8 9<body> 10 <form method="post" action="kensaku.php"> 11 <p>ご意見コードを入力してください</p> 12 <input name="nickname" type="text" style="width: 100px"> 13 <input type="submit" value="送信"> 14 </form> 15</body> 16 17</html>

PHP

1<!DOCTYPE html> 2<html lang="jp"> 3 4<head> 5 <meta charset="UTF-8"> 6 <title>php基礎</title> 7</head> 8 9<body> 10 <?php 11 $nickname=$_POST['nickname']; 12 13 $dsn='mysql:dbname=phpkiso;host=localhost'; 14 $user='root'; 15 $password=''; 16 $dbh=new PDO($dsn,$user,$password); 17 $dbh->query('SET NAMES utf8'); 18 19 $sql='SELECT * FROM anketo WHERE nickname LIKE '".$nickname"' '; 20 $stmt=$dbh->prepare($sql); 21 $stmt->execute(); 22 23 while(1){ 24 $rec=$stmt->fetch(PDO::FETCH_ASSOC); 25 if($rec==false){ 26 break; 27 } 28 print $rec['code'].$rec['nickname'].$rec['email'].$rec['goiken'].'<br>'; 29 } 30 31 $dbh=null; 32 ?> 33</body> 34 35</html> 36

試したこと

データベースのテーブルには'nickname'と命名したフィールドが存在します

PHP

1 $sql='SELECT * FROM anketo WHERE nickname LIKE "やっくん" '; //成功

上記の文ではsubmitクリックで、フィールドnickname’やっくん’のレコードの取得に成功しました。
このことから構文ミスやスペルミスのではなく、変数がうまく取得されていないと判断できます。

おそらく見当違いな方法を試している気がします。
以下試したこと一覧です。

PHP

1$sql='SELECT * FROM anketo WHERE nickname LIKE '".$nickname"' '; 2$sql='SELECT * FROM anketo WHERE nickname LIKE "'.$nickname'" '; 3$sql='SELECT * FROM anketo WHERE nickname LIKE "'.($nickname)'" '; 4//()で閉じてみたり 5$sql='SELECT * FROM anketo WHERE nickname LIKE '".$nickname"; 6//外に出して連結してみたり

補足情報(FW/ツールのバージョンなど)

OS=Windows10 / ブラウザ=chrome / エディタ=Brackets Ver.1.14 / 開発環境=XAMPP Ver3.2.4 /
データベースエンジン=MySQL

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答5

0

ベストアンサー

変数がうまく取得されていないと判断できます。

その判断は状況証拠からの推察でなく、確実にデバッグで判断すべきです。

  1. PHPからではなくSQLを直に実行する(phpMyAdminとかツールからでも良いです)
  2. $_POSTをvar_dump()する
  3. 構文エラーを確認する
  4. $sqlをechoする

「変数がうまく取得されていない」は2番目で判断できます。
あとは、1番目で想定通りの結果が出たSQLと4番目で出力された文字列が同じであれば「SQL文は問題ない」と判断して良いわけです。
違えば「SQL文が正しく構築できてない」ですね。
合っててデータが出てないなら「どこからエラーが出ている」となりますので次の検証になります。

最初のコード

php

1$sql='SELECT * FROM anketo WHERE nickname LIKE '".$nickname"' ';

これそもそもSyntaxエラーですから。

引用符・二重引用符・文字列連結についてはPHPマニュアルの文字列の項文字列演算子の項を確認してください。

あと、XAMPPであるということ・ダブルクォーテーションで文字列囲ってるところからおそらくMySQLかと思いますが、ダブルクォーテーション使えないDBもある(と言うかそっちの方が多いのでは)ので「文字列はシングルクォーテーションで囲う」と覚えた方が良いです。

というのを加味して変更するなら下記。

php

1 2$sql='SELECT * FROM anketo WHERE nickname LIKE \''.$nickname.'\'';

でも、明らかに2点ダメな点があります。

  1. LIKE使ってるけどそれなら=と同じ
  2. SQLインジェクションの脆弱性がある

1個ずつ見ていきます。

1.LIKE使ってるけどそれなら=と同じ

LIKEパターンマッチングをするために用いられるのが通常です。
あいまい検索。 前方一致や部分一致、後方一致といった場面ですね。

「山なんとかさんだけど忘れた」という場合に「山」だけ入れて「山から始まる名前の人」を探したりだとか、「確かどこかに”岡”って入ってたような」で「岡」だけ入れて「岡を含む名前の人」を探したりだとか、「最後が”子”だったような」場合に「子」だけ入れて「名前の最後が子の人」を探したりだとか、そういうときに使います。

MySQL 5.6 リファレンスマニュアル#パターンマッチング

現在だと「山」と入れたら
SELECT * FROM anketo WHERE nickname LIKE '山'
となるので「nickname が"山"の人」しか探せません。それでいいのならLIKEでなく=とすべきです。

ご検討ください。

2.SQLインジェクションの脆弱性がある

実際に試したわけではないですが、おそらく下記の文字列を送ると、全件取得できます。
' or '1'= '1

対応方法は既に出ている2つの回答通りですが、思考停止でとりあえず指摘通りの対応するのではなく、
「SQLインジェクションとはなんぞや」というところをきちんと調べて理解してから対応してください。

投稿2020/02/08 20:46

編集2020/02/08 20:48
m.ts10806

総合スコア80842

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

koguchi

2020/02/25 15:34

返信が遅くなり申し訳ございません。 ””変数がうまく取得されていないと判断できます。 →その判断は状況証拠からの推察でなく、確実にデバッグで判断すべきです。”” 確かにその通りでした。予想ではなく、エラーメッセージ等で確実な原因を探るべきでした。 ご指摘いただいた通りにしたところ完璧に動作しました。 '='と'LIKE'の使い方も理解が足りませんでした。 SQLインジェクションに関しましてもかなり検索し、おおよその理解はできたかと思います。 詳細な回答、アドバイスをいただき本当にありがとうございました。
guest

0

色々まずいので、以下を読んでください。
PHP で MySQL 接続時に必要な知識(最小限版)

投稿2020/02/08 17:31

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

「nickname LIKE "やっくん"」をするなら「nickname = "やっくん"」
で検索してください。
LIKEはワイルドカードと合わせて使うところに意味があります。

投稿2020/02/10 00:21

yambejp

総合スコア114736

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yambejp

2020/02/10 00:23

そして「nickname LIKE "%やっくん%"」のように部分一致を かけるとインデックスが効きません そうするくらないなら「nickname regexp "やっくん"」の方が すっきり書けるでしょう
guest

0

一般的なアドバイスとして、まずただしく動くSQLを書いて動作確認しましょう。

どんな環境を使っていても(例えばコマンドラインのmysqlクライアント、phpMyAdmin、MySQLWorkbench、クラウドサービスなど)、必ずSQLを実行することができる場所があるはずです。
そこでまず正しく動くSQLを書きましょう。

SQLの問題としては、LIKE検索する場合、マッチしなくて良い部分はワイルドカードを指定する必要があり、
例としてnicknameにhogeを含む行を検索したい場合は以下のようになります。

SQL

1SELECT * FROM anketo WHERE nickname LIKE '%hoge%'

投稿2020/02/09 20:32

rysh

総合スコア874

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

php

1<?php 2/* 値の配列を渡してプリペアドステートメントを実行する */ 3$sql = "SELECT * FROM anketo WHERE nickname LIKE %:nickname%"; 4$sth = $dbh->prepare($sql, [PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY]); 5$sth->execute([":nickname" => $nickname]); 6$res = $sth->fetchAll()

参考:PHP: PDO::prepare - Manual

投稿2020/02/08 17:36

sola-msr

総合スコア876

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2020/02/08 20:50

>LIKE %:nickname% これだとダメな気がします。バインドすると結果は LIKE %'やっくん'% になるはず。
sola-msr

2020/02/09 03:57

あーたしかにそんな気がします
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問