SQLの「?」と戦う② 直す編
書いている構文から、「?」に検索条件を置き換えているのは
$this->db->query($sql, $binds)
のqueryで間違いないと思います。
systemフォルダの中をあさってみると
CI_DB_driverというクラスにqueryファンクションが存在しました。
さらに実際の置き換え処理をしているのがcompile_bindsファンクションのようです。
teratailで教えて頂いたサイト様を参考にCI_DB_driverを拡張しようとしたのですが、何度やってもうまくいきません。
わざと?を全部「あ」に置き換える処理にしてみても呼ばれてる気配がない。
これはおかしい・・・。
ということでソースをうんうん眺めていたのですが、気になったのが
abstract class CI_DB_driver {
abstractって…私が作ったクラスにはついてないけどなんだコレ。
抽象クラスというらしいですが、説明を何回読んでもサッパリ意味がわかりません。
わからないけど、要するにこれだけじゃ何もできなくて、継承しないと使えないもの?
その観点から「CI_DB_driver」でファイルを全部検索すると
↓こんなとこが見つかりました。
if ( ! isset($query_builder) OR $query_builder === TRUE) { require_once(BASEPATH.'database/DB_query_builder.php'); if ( ! class_exists('CI_DB', FALSE)) { /** * CI_DB * Acts as an alias for both CI_DB_driver and CI_DB_query_builder. * @see CI_DB_query_builder * @see CI_DB_driver */ class CI_DB extends CI_DB_query_builder { } // ここと } } elseif ( ! class_exists('CI_DB', FALSE)) { /** * @ignore */ class CI_DB extends CI_DB_driver { } // ここ }
おぉ…名前からして$this-dbのdbの本体がこのCI_DBのようだ・・・・。 いくらCI_DB_driverを拡張しても何の意味もないのは実態はCI_DBで、継承してるのは拡張してない本体だからという呼ばれないのかも。
そこでteratailでおしえて頂いたサイト様の以下を参考に a-zumi.net CI_DB_query_builderを継承したMY_DB_query_builder作成。
これで、本題だったcompile_bindsが上書きできるようになりました!!
↓こんな感じ
public function compile_binds($sql, $binds){ $sql = parent::compile_binds($sql, $binds); if (array_values($binds) !== $binds) { foreach($binds as $key => $value){ $escaped_value = $this->escape($value); if (is_array($escaped_value)){ $escaped_value = '('.implode(',', $escaped_value).')'; } $sql = str_replace(':'.$key, $escaped_value, $sql); } } return $sql; }
最初にparentのファンクションを呼び出したので、?も置き換えてもらえました。 置き換え処理は親クラスを真似したのでたぶん大丈夫。 $escaped_valueをが配列かどうか判定している部分が何になるのか、さっぱりわかりません。 親クラスがやってたので真似しました。
これで目標は達成できましたが、abstractクラスというのが一体何のために使われるのかわかりません。 興味がわいて調べてみたら、ちょっと面白そうだったので、次はそれに挑戦してみます。