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

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

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

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

Q&A

3回答

4199閲覧

bindValueを用いてSQL文に同一の変数を複数埋め込みたい

ebi-ebi587

総合スコア0

PHP

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

0グッド

0クリップ

投稿2021/09/30 04:52

前提・実現したいこと

簡単な検索機能を作成しています。名前検索処理のみ上手く動作しません。

一つのSQL文に同一の変数をプレースホルダを用いて複数代入したいです。

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

Invalid parameter number in ...

(以下のコード内の)$info->execute()で不具合が起きています。

該当のソースコード

php

1$sql = 'concat(lastname, firstname) as name from info'; 2 3~中略(条件分岐)4 5$sql = $sql.' where (lastname like :keyword 6 or firstname like :keyword 7 or firstkana like :keyword 8 or lastkana like :keyword)'; 9 10~中略(条件分岐)11 12$info = $pdo->prepare($sql.';'); 13$info->bindValue(':keyword', '%'.$keyword.'%', PDO::PARAM_STR); 14$info->execute();

試したこと

カラム・プレースホルダの名前確認、テーブルの構造確認、bindParamでの実行
疑問符プレースホルダでは正常に動作しますが、同じ変数を代入しているだけなので、一括にできる方法はないかと考えています。
bindValueの数が間違っているというエラーだと考え、変数分(4つ)bindValueを入れてみたのですが、そうなると「値がありません」というエラーになってしまいます。

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

突然この処理ができなくなり困惑しています(直前までは正常に動いていた)。
動かなくなると前とで変更した箇所はデータベースなのですが、大きく構造を修正したわけではなく、カラム名も間違っていません。

名前以外の検索処理は問題なく動作します。

SQL文内の()は「名前が一致している”かつ”○○」という文法にするためのものです。

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

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

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

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

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

guest

回答3

0

ラベルの使い回しをするためにはprepareのエミュレートモードを有効にしないといけません

PHP

1 $pdo = new PDO($dsn, $user,$password); 2 $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 3 $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES,true);

投稿2021/09/30 05:01

yambejp

総合スコア115010

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

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

yambejp

2021/09/30 05:10

ちなみにエミュレートしない場合、prepareの置換はSQL側でネイティブにおこなわれ エミュレートの場合はPHP側で行う・・・という仕様だった記憶があり エミュレートではインジェクションが危険なような気がしますが 以前徳丸先生の公演で「そんな気にする必要ないよ」と言われたので問題ないと思います
guest

0

sql

1$sql = $sql.' where (lastname like :keyword1 2 or firstname like :keyword2 3 or firstkana like :keyword3 4 or lastkana like :keyword4)'; 5$info->bindValue(':keyword1', '%'.$keyword.'%', PDO::PARAM_STR); 6$info->bindValue(':keyword2', '%'.$keyword.'%', PDO::PARAM_STR); 7$info->bindValue(':keyword3', '%'.$keyword.'%', PDO::PARAM_STR); 8$info->bindValue(':keyword4', '%'.$keyword.'%', PDO::PARAM_STR);

単純にこんなのもあり

投稿2021/09/30 07:02

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

0

多少結果が違うかもしれんけどこれでよくない?

sql

1$sql = $sql.' where lastname+firstname+firstkana+lastkana like :keyword)';

多少が気になるんなら絶対にありえない文字を間に挟むとか

sql

1$sql = $sql.' where lastname+"????"+firstname+"????"+firstkana+"????"+lastkana like :keyword)';

データベースがわからんから書き方違うかもしれんけどやりたいことは
各々にorするんじゃなくて全部繋げた文字列に一回だけlikeすればいいです。

多少結果がちがうっていうのはlastname「山田」firstname「太郎」に対して
文字列を繋げてlikeする都合上、「田太」と検索しても引っかかるようになるということです。
なので間とありえない文字で埋めれば検索対象が「山田????太郎」などとなるため
「田太」と検索しても引っかからないようになります。

投稿2021/09/30 06:28

sousuke

総合スコア3828

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問