mysql_select_dbの挙動が気に入らない
何だかいろいろ試していたらあれ?ということにぶつかってしまったので、覚え書き。
解決策は考え中です。解決しました!
※追記 10/12/22 19:50
Twitterでアドバイスを頂き、解決の方向性が見えてきました。
※追記 10/12/23 14:00
Twitterで完全な解決策を頂きました!こしあんさんに感謝!
まず、簡単に状況説明から。
僕はphpからmysqlを使うために、DB用のクラスを作っています。
まぁ多くの方は持ってると思いますが。。
僕の場合はこんな感じ。
class DB{ var $db_encoding="UTF-8"; var $script_encoding="UTF-8"; #--------------------------- # constructer #--------------------------- function DB($host=HOST,$user=USER,$pass=PASS,$db=DBNAME){ # CONNECT MySQL if (!($mysql=mysql_connect($host,$user,$pass,TRUE))) { die("ERROR: HOST CONNECT FAILED"); } # CONNECT DB if (!(mysql_select_db($db,$mysql))) { die("ERROR: DB CONNECT FAILED"); } } #--------------------------- # class method #--------------------------- function exe($stmt){ # Execute SQL if (!($data = mysql_query($stmt))) { echo mysql_error()."\n"; var_dump($stmt); return false; } $result = Array(); while($tmp = @mysql_fetch_assoc($data)){ array_push($result,$tmp); } if( !empty ( $result ) ){ return $result; }else{ return TRUE; } } }
オブジェクト生成時にコンストラクタでmysql_connectを使って接続、そのあとメソッドでSQLを実行します。
いつも定数でDBへの接続情報を持っているのですが、引数で渡せば別のDBにも接続できるようになってます。
しかし、2つのDBに接続しようとして、以下のコードを書いたときに失敗しました。
$db = new DB();# DB Object $db2 = new DB('localhost','user','password','hogedb');# DB Object $db->exe("select * from db1table"); $db2->exe("select * from db2table");
「 Table ‘db1.db1table’ doesn’t exist 」となって、最初のクエリが失敗。
今までは大概1つのDBに接続していたので気付かなかったのですが、2つのハンドラを生成した場合に後から生成されたDBハンドラに上書きされてしまったのです。
もっと正確に言うと、コンストラクタで使用していたmysql_select_db関数が情報を上書きしてしまい、DBを変更してしまうのです。
mysql_select_db関数は第二引数にmysql接続を渡すことで指定できるのに、後からの接続に情報を上書きされてしまいます。
どうにも納得いかないんですが、どう回避したらいいのか思案中です。。。(´・ω・)
※追記 10/12/22 19:40
Twitterにも書いたんですが、実は今回のコードの回避策はあるにはあるのです。
mysql_select_dbをメソッドexe()の最初に持ってくることで、実行前に毎回DBを選択すれば解決します。
でもものっすごく気に入らないので別の回避策がないかなーと思っております。
もし何か良い案があれば是非教えてください。。><;
※追記 10/12/22 19:50
Twitterでdebiru氏にこんな助言を頂きました。
@yakumo27 クラス作ってオブジェクト思考型で処理したいなら、そもそも手続き型の関数を使うべきではないのではないでしょうか。PHP4前提だと少し難しいですね。私は PHP5.x での開発が主なので mysqli をよく用います。 http://bit.ly/gQyFvH
元発言はこちら
恥ずかしながら、mysqliは利用したことがなかったので未知の領域でした。
環境がPHP5.xなのであれば有効なのかも。
この問題はアドバイス頂いた方向で解決してみたいと思います。
※追記 10/12/23 14:00
Twitterでこしあんさんにこんなメッセージを頂きました!
@yakumo27 ちょっと書きなおしてみました、こんな感じでどうでしょ。 https://gist.github.com/752467
元発言はこちら
@yakumo27 多分、コネクション($mysql)を省略していたので、最初に作ったコネクションを自動的に使ってしまってるのではないかなぁと思います。件のソースでは問題なく動きましたー@自分の環境
元発言はこちら
全くもってそのとおりでした!
こしあんさんが解決してくださったソースを見るとわかるのですが、コネクションをメンバ変数に割り当てて、mysql_queryの引数に明示的にコネクションを渡しています。
元の僕のソースではこれを省略してしまってたんですね。
いやはやこんなことに気付いてくださってソースまで書いてくださって、こしあんさんに感謝です!
こしあんさんの技術ブログはこちら。