mysql_connectでnew_linkをtrueにしても、既に開かれたリンクIDが返ってくる。

セッション管理用のリンクと普段使うリンクを分けるために、mysql_connectのnew_linkをtrueにして開きました。
しかし、片方をmysql_closeするとセッション管理用に開いておいたリンクが閉じられてしまいます。
別々にリンクを開く場合は、どのようにすれば良いのでしょうか?
よろしくお願いいたします。

PHPのセーフモードはoffになっています。
PHP 5.3.3 + Suhosin-Patch + eAccelerator

サンプル
http://pastebin.com/yPLV7sq8

回答の条件
  • 1人10回まで
  • 登録:2012/03/04 20:54:40
  • 終了:2012/03/11 20:55:16

回答(0件)

回答はまだありません

  • id:tdoi
    サンプルのコード見ましたが、挙げられている部分に関しては問題がない気がします。
    手元の環境が5.2なので、名前空間をはずして試してみましたが、$DB->Close()をコールした後でも、$_sess_dbのハンドルでDBにアクセスできることを確認しました。
    ちなみに、何をもって$_sess_dbのハンドルが閉じられたと判断していますか?

    恐らく、掲載された箇所以外に問題があるのではないかと思いますが、可能性としては、知らないうちにsession_closeやsession_destroyが呼ばれているとか、mysql_close()が引数null、あるいは、引数なしで呼ばれている箇所があるとか、そういったことなんじゃないかなと。セッションもオブジェクトで管理するなら、ハンドルもDBと同じようにフィールドで管理してしまえばいいと思うのですが、そうしていないことから類推すると、どこかで$_sess_dbが使われているのではないかなと。もしそうであれば、そういった可能性もあるのかと。

    何かの参考になれば。
  • id:smokedcheese
    >ちなみに、何をもって$_sess_dbのハンドルが閉じられたと判断していますか?
    mysql_connectとmysql_closeの周りにprintfを置いて呼び出される順番を確認し、
    エラーと照らし合わせることで判断しました。

    @パターン1($_sess_dbが$dbよりも後に閉じられる場合)
    session_start()
    OpenDB(Session)
    OpenDB(DB)
    CloseDB(DB)
    [以降、$_sess_dbのアクセスは拒否される。添付1]
    CloseDB(Session)

    @パターン2($dbが$_sess_dbよりも後に閉じられる場合)
    session_start()
    OpenDB(Session)
    OpenDB(DB)
    session_write_close();
    CloseDB(Session)
    [$dbのアクセスは可能]
    CloseDB(DB)
    ※こちらは正常に動作する。

    <添付1>
    Warning: mysql_real_escape_string(): Access denied for user 'www-data'@'localhost' (using password: NO) fileB.php
    Warning: mysql_real_escape_string(): A link to the server could not be established fileB.php
    Warning: mysql_real_escape_string(): Access denied for user 'www-data'@'localhost' (using password: NO) fileB.php
    Warning: mysql_real_escape_string(): A link to the server could not be established in fileB.php
    Warning: mysql_real_escape_string(): Access denied for user 'www-data'@'localhost' (using password: NO) in fileB.php
    Warning: mysql_real_escape_string(): A link to the server could not be established in fileB.php
    $dbが既に閉じられているために実行ユーザー名で再接続している?

    掲載していない部分と問題を切り分けるために必要最小限のコードを書き直しましたが、どうも同じエラーが出てしまいます。
    pastbinの方に書き忘れた部分がありますが、mysql_close()を呼び出しているのはDatabaseとSessionHandlerの二箇所だけです。

    早めにセッションを終了しておけば問題ないと言えなくもないですが、どのような実装がベストなのでしょうか。
  • id:tdoi
    OpenDBとCloseDBが何か分かりませんが、もし、コメントで頂いたwarningが出ることで接続が2つとも切れていると判断されているのであれば、そこが間違いです。

    mysql_real_escape_stringは第2引数にコネクションのハンドルをとりますが、恐らくこれを指定していないですよね?
    以下マニュアルより引用
    http://php.net/manual/ja/function.mysql-real-escape-string.php

    link_identifier
    MySQL 接続。 指定されない場合、mysql_connect() により直近にオープンされたリンクが 指定されたと仮定されます。そのようなリンクがない場合、引数を指定せずに mysql_connect() がコールした時と同様にリンクを確立します。 リンクが見付からない、または、確立できない場合、 E_WARNING レベルのエラーが生成されます。

    で、

    session_start() // Session用のDBコネクション確立
    OpenDB(Session)
    OpenDB(DB) // DBオブジェクト用のDBコネクション確立
    CloseDB(DB) // DBオブジェクト用のDBコネクション破棄

    [$dbのアクセスは可能]
    この時点では、session用のコネクションは存在しているものの、mysql_real_escape_stringの第2引数を指定しなければ、直近にオープンした、つまり、DBオブジェクト用のコネクションを確認しに行きます。
    その結果、該当のWarningが出ているのではないかと。

    CloseDB(Session) // セッション用のDBコネクション破棄?

  • id:smokedcheese
    まさか、そのような引数があるとは。
    見逃していました。お恥ずかしい限りです。
    この度は本当にありがとうございました。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません