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

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

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

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

CodeIgniter

CodeIgniterは、PHP向けオープンソースのWebアプリケーションフレームワークです。CodeIgniterは覚える構文が少なく、自由度も高いため、PHPを理解していれば構築が簡単です。

Q&A

解決済

1回答

3107閲覧

PHP(CodeIgniter3)SQLの検索条件置き換えを「?」以外にしたい

SystemAjisai

総合スコア171

PHP

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

CodeIgniter

CodeIgniterは、PHP向けオープンソースのWebアプリケーションフレームワークです。CodeIgniterは覚える構文が少なく、自由度も高いため、PHPを理解していれば構築が簡単です。

0グッド

0クリップ

投稿2017/02/14 07:28

###前提・実現したいこと
PHP7(CodeIgniter3)で検索画面を作っています。

テーブルの結合が複雑で検索条件も多いため、
↓こういう書き方ではなく

$this->db->from('table1'); $this->db->where('id', 'user123');

↓こういう風に書こうとしています。

$_sql = "select * from table1 where id = ? "; $_binds = array('user123'); $this->db->query($_sql, $_binds)

ネットで調べると、SQL内の「?」で置き換えている箇所が、
JavaやRubyという言語では

select * from table1 where id = :id

のように、「:」+任意の名前でマーキングできるようでした。

PHP(CodeIgniter)では同じことはできないのでしょうか。
こうすればできるよ 等があれば教えてください!

###発生している問題・エラーメッセージ
検索条件が多いため「?」が大量になってしまい、
どこがなんの値で置き換えられているのか、非常に読みづらい。

###試したこと
$this->db->query()の本体と思しき、DB_driver.phpのqueryファンクションを読んでみました。
同じファイルの内のcompile_bindsファンクションが「?」の置き換え処理で、
マーカーとして「?」しか定義されてなかったので、queryファンクションではやりたいことは実現できないのではないかと思っています。
そこでMY_DB_driver.phpを作ってオリジナルのcompile_bindsファンクションを書いてみました。
$this->db->query()でオリジナルのcompile_bindsが呼び出されると思ったのですが、誰からも呼んでもらえませんでした。

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

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

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

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

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

kunai

2017/02/14 08:08

MY_DB_driver.phpをDB_driver.phpとして上書きしてしまえば呼んでくれるのでは。勿論元のファイルはバックアップを取って、ですが。
SystemAjisai

2017/02/14 08:45

ありがとうございます。compile_bindsがpublicファンクションだったので他から呼ばれているのを調べて影響がないか調整しながら上書きするのは怖いなぁと思ったのです。MY~にすれば自分(DB_driver)にしか影響がないと思ったんですが、この辺の解釈に自信がありません・・・。
SystemAjisai

2017/02/14 08:58

書いててバカなことを言ってる気がしてきました。継承クラス作ったら親クラスの挙動だけ入れ替わるとか神秘現象ですよね。MYはDB_driverじゃなくてそのアプリケーションという解釈の方が正しい気がしてきたので、どっちにしろ他に影響しそうなことしてました…。
kunai

2017/02/14 09:09

勿論、影響があって困る本番環境などではやらない方が良いと思いますが。まずは自分だけが扱う開発専用環境等を作って、そこで上書きでやってみたらどうでしょう。
SystemAjisai

2017/02/14 23:12

ありがとうございます。今回の件で自分のパソコンで試せないって不便だなと感じたので、開発環境に挑戦して試してみます!
guest

回答1

0

ベストアンサー

普通に sql 文作って、配列なりオブジェクトで値を渡してあげれば出来たはずです。
ただ、普通のPHPとは違い

$_sql = "select * from table1 where id = :id "; $array = [ 'id' => $id, ];

のように:を取った形で、作ってやる必要があったと思います。
*手元で確認してません^^;間違ってたらすみません。

また、CodeIgniter は制約が緩いので、ナマの PHP が使えます。
クエリビルダを使うのがしんどければ、PDO とかでやるとイイです。

PDO::prepare
やりたいことは普通に実現可能です。

拡張に関しては、こちらが参考になるかと
あずみ.net

投稿2017/02/14 14:11

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

SystemAjisai

2017/02/14 23:58

回答ありがとうございます。 私のやり方が悪いのか、:idの置き換えが行われずそのままSQL実行され、「You have an error in your SQL syntax」という構文エラーになってしまいました。 PDOに関して自分なりに調べてみたのですが、config/database.phpのDB接続設定のdbdriverを現在のmysqliからpdoに変えないといけないようで、ほかに影響が出たら怖いので自分の開発環境ができてから試してみたいと思います。 ↓参照したところ https://forum.codeigniter.com/thread-62163.html 拡張の情報も参考になりました! MY_ControllerやMY_Modelが作れたので同じように考えていましたが これらは継承するから動くわけで、呼び出してるだけのドライバークラスはロードする対象を拡張クラスにしないと呼び出されないんですね。 なんで考え付かなかったんだろう…お恥ずかしい限りです。 ただこちらも私の壮大な勘違いで、他への影響が出る可能性がある修正だったので、自分の環境を作れてから試したいと思います。 取り急ぎ上司から早くしろとせっつかれているので、 「試したこと」で作ってみた自前の置き換えファンクションをモデルにコピーして、 query()に渡すSQLを自前ファンクションで置き換え後のものにする方法で一時しのぎすることにしました。 (普段から俺スキル自慢するくせに、開発経験5日の私に押し付けるな言いたいッ!…という愚痴) なんかカッコ悪い気がするので、自分の環境が作れたら拡張とPDOも試してコッソリ置き換えてみます! ありがとうございました!!
退会済みユーザー

退会済みユーザー

2017/02/15 00:23

すみません。手元のコード見ると、全て $this->db->where('id', 'user123'); みたいにして使ってました。 ちょっと、insert とかとゴッチャになって間違った情報を書いてしまったようです。 *やはりちゃんと検証してからかけばよかった。。。急ぎの時にお手数をおかけしました。 業務で使用するなら、生 PHP は使用しないほうが良いですね^^; メンテが面倒くさくなるので。 なんか全然役に立たない回答してしまいすみませんでした。
SystemAjisai

2017/02/15 03:05

とんでもないです! エラーでも出ればそれを元に調べられるんですが、今回のはなんてキーワードで調べればいいかもわからず途方くれていたので、本当に助かりました。 先ほど自分のパソコンに環境ができたので試しに拡張版で書いてみました。 私が調べていたCI_DB_driverを拡張したのでは、$this->db->~で呼び出す一部の機能が使えなくなってしまいました。 もともと開発中の環境ではDB_query_builder というのが使われていたようでDB_query_builder はDB_driverを継承していました。 長くなりましたが、結論は DB_query_builderを継承したMY_DB_query_builder を作ってcompile_bindsの処理に「:」形式の置換処理を足し、Load処理を拡張してMY_DB_query_builderを読み込んだらOK! でした。 この辺も教えて頂いたサイト様を参考にさせて頂きました。 色々勉強になり、また理想通りにもなって幸せです。 ありがとうございました!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問