phpのMDB2について質問です。

下記のようなコードを書いてみたのですが、ブラウザ経由だと問題ないのに、php sample.php という形でコマンドラインから実行をすると"Fatal error: MDB2 Error: not found in ***"というエラーが出てしまいます。
<?php
set_include_path(get_include_path().PATH_SEPARATOR."../lib");
require_once("MDB2.php");
$db =& MDB2::connect('mysql://root:namaco@localhost/azisaii');
if (PEAR::isError($db)) {
trigger_error($db->getMessage(), E_USER_ERROR);
}
?>
ネットで調べると、MDB2_Driver_sqliteが入っていない場合によく出るエラーだということは分かっているのですが、MDB2_Driver_sqliteもインストール済みです。ブラウザ経由でアクセスする際には問題ない(DBにクエリを投げて結果を取得できることも確認済み)のも確認しています。
apache経由の実行ではないので、何かしらのパスが通ってないとかなのかな・・と思ったのですが、何を試していいものやら途方にくれてしまっています。

お手数ですが何かわかるかたはお教えいただけますと幸いです。

以下、環境です。
・apache 2.2.14
・php 5.3.1
・MDB2 2.4.1

回答の条件
  • 1人5回まで
  • 13歳以上
  • 登録:2010/08/26 00:28:57
  • 終了:2010/08/28 12:27:57

ベストアンサー

id:windofjuly No.1

うぃんど回答回数2625ベストアンサー獲得回数11492010/08/26 08:17:14

ポイント83pt

【1】MDB2_Driver_sqliteは無関係

データベースはMySQLですよね

ブラウザ経由で動いているので MDB2_Driver_mysql が正しくインストールされてます

 

【2】ブラウザ経由(apache経由)とコマンドラインの大きな違い

  apache経由 コマンドライン
phpの挙動 apacheモジュールあるいはCGI CLI
ユーザー(アクセス権限) apacheを動かしているユーザー OSにログインしているユーザー
カレントディレクトリ 仮想パス 実パス

その他、細々とした違いがあるのですが関係なさそうなので今回は割愛します

 

【3】NOT FOUND

仮想パスと実パスの違いにより位置関係が崩れてしまい MDB2.php が見つからないというエラーが出ているようですから、

get_include_path() の結果と MDB2.phpのパスを調べて set_include_path() を書き直せばよいでしょう

 

apache経由とコマンドラインは基本的に別物となりますので知識は知識として持っておいて、

改造などせず素直にapache経由でテストを行うのが良いと思います(改造点が増えればミスする可能性も増えますし)

id:n_maco2

詳しいご説明ありがとうございます。

でもMDB2.php自体へのパスは通っているように思います。というのは"Fatal error: MDB2 Error: not found in ***"は、$db->getMessage()が返しているエラー文章のためです。MDB2.phpが見つけられない場合は(わざとパスを間違えてやってみたのですが)"Warning: require_once(MDB2.php): failed to open stream: No such file or directory in ***"になるはずです。

MDB2.phpを見つけているにも関わらずMDB2がNot foundと言っているものがなんなのかがわからない・・といった状況です。


※追記

できればapache経由にしたいところなのですが、管理用のスクリプトでDBを使う必要があり、apache経由にしにくい状態なのです。perl等の他言語でライブラリを書き直すのも面倒ですし・・なんとかphpのMDB2をスクリプト経由で動かすことができれば、一番楽なのですが・・・

※追記2

コマンドラインから実行する際にsudoで実行してみたのですが、それでも変わりませんね・・

2010/08/26 15:17:15

その他の回答(3件)

id:windofjuly No.1

うぃんど回答回数2625ベストアンサー獲得回数11492010/08/26 08:17:14ここでベストアンサー

ポイント83pt

【1】MDB2_Driver_sqliteは無関係

データベースはMySQLですよね

ブラウザ経由で動いているので MDB2_Driver_mysql が正しくインストールされてます

 

【2】ブラウザ経由(apache経由)とコマンドラインの大きな違い

  apache経由 コマンドライン
phpの挙動 apacheモジュールあるいはCGI CLI
ユーザー(アクセス権限) apacheを動かしているユーザー OSにログインしているユーザー
カレントディレクトリ 仮想パス 実パス

その他、細々とした違いがあるのですが関係なさそうなので今回は割愛します

 

【3】NOT FOUND

仮想パスと実パスの違いにより位置関係が崩れてしまい MDB2.php が見つからないというエラーが出ているようですから、

get_include_path() の結果と MDB2.phpのパスを調べて set_include_path() を書き直せばよいでしょう

 

apache経由とコマンドラインは基本的に別物となりますので知識は知識として持っておいて、

改造などせず素直にapache経由でテストを行うのが良いと思います(改造点が増えればミスする可能性も増えますし)

id:n_maco2

詳しいご説明ありがとうございます。

でもMDB2.php自体へのパスは通っているように思います。というのは"Fatal error: MDB2 Error: not found in ***"は、$db->getMessage()が返しているエラー文章のためです。MDB2.phpが見つけられない場合は(わざとパスを間違えてやってみたのですが)"Warning: require_once(MDB2.php): failed to open stream: No such file or directory in ***"になるはずです。

MDB2.phpを見つけているにも関わらずMDB2がNot foundと言っているものがなんなのかがわからない・・といった状況です。


※追記

できればapache経由にしたいところなのですが、管理用のスクリプトでDBを使う必要があり、apache経由にしにくい状態なのです。perl等の他言語でライブラリを書き直すのも面倒ですし・・なんとかphpのMDB2をスクリプト経由で動かすことができれば、一番楽なのですが・・・

※追記2

コマンドラインから実行する際にsudoで実行してみたのですが、それでも変わりませんね・・

2010/08/26 15:17:15
id:yamaneroom No.2

yamaneroom回答回数1040ベストアンサー獲得回数612010/08/26 08:54:13

ポイント3pt

コマンドラインから実行するときのカレントパスに "MDB2.php" がない。

対策としては、

require_once("MDB2.php");

の部分を絶対パス指定してやること。

id:n_maco2

ご回答ありがとうございます。

絶対パス指定はしていませんでした。ただ、set_include_pathを使って正しいディレクトリがinclude_pathに含まれるようになっていたので、その当たりの問題ではないのかなと感じています。念のため絶対パスに描き直してやってみたのですが、特に症状に変化はありませんでした。

2010/08/26 09:56:56
id:kaijikaiji No.3

kaijikaiji回答回数40ベストアンサー獲得回数02010/08/26 11:45:50

ポイント3pt

Apache 経由とコマンドラインでは、使用される php.ini が異なっている可能性があります。異なっている場合は、get_include_path() で返される値も異なっている可能性があります。一度確認されてはどうでしょうか。

id:n_maco2

ご指摘ありがとうございます。

get_include_pathで確認したのですが、PEARのパスが違うくらいでした。

そこでset_include_pathを使って完全にapacheでもスクリプトでも同じパスで実行されるように変えてみたのですが、完全に同じにも関わらずやはりapache経由だと実行できて、コマンドラインだと実行できません。

※追記

使っているphp.iniを揃えるために、ブラウザでphpinfoを取得してそこに表示されているphp.iniのパスを取得しました。その後下記のようなコマンドで実行して、php.iniをブラウザと同じものに変えて実行してみたのですが・・

php -f sample_MDB2.php -c /private/etc/php.ini

やはり症状は変わりませんでした。php.iniまで同じなのに・・(-iオプションでphp.iniのパスが同一になっていることを確認)

2010/08/26 15:40:26
id:la-la-land No.4

la-la-land回答回数58ベストアンサー獲得回数62010/08/26 17:46:14

ポイント3pt

php.iniのたとえばextension_dirなどのディレクトリのパスを絶対パスにするとかはどうですか。

同じphp.iniで参照先が違うというのは見てるユーザーの違いでどこかの相対パスの参照先が変わってるからだと思います。

id:n_maco2

上記ありがとうございます。

確認してみたのですが元々extension_dirは絶対パスで書いてあったようです・・

またその他パス類で相対パスで設定されているものはないか一通り見てみたのですが、全て絶対パスで書かれているようです

2010/08/26 19:53:11
  • id:n_maco2
    windofjulyさんからメッセージにて下記アドバイスをいただいたので、
    取り急ぎ転載させていただきます。
    ご協力ありがとうございます!!!!

    --以下転載-------------------------------------------


    環境にもよるのですがrequire_onceで失敗していれば、WarningとFatalが順に返されてくるので、
    最後のエラーとしてNOT FOUNDが出ていると思い込んでしまいましたが
    phpではなくPEARがエラーを返しているということで、ちょっと違ったようですね。ごめんなさい

    帰宅しましたので、
    MDB2とMDB2_Driver_mysqlをPEAR INSTALL コマンドで自宅サーバにインストールしてみましたが、
    apache経由でも実行しても、コマンドラインでどのユーザーから実行しても、
    PEARのパスはまったく変わりなく、動作も変わりなく正常に結果を返してくれてますので、手は止まっています

    (1)テスト環境
    Vine Linux 5
    Apache 2.2.14
    MySQL 5.1.41
    PHP 5.3.1 (cli)
    PEAR 1.9.0
    MDB2 2.4.1
    MDB2_Driver_mysql 1.4.1

    (2)テストコード
    <?php
    set_include_path( get_include_path() . PATH_SEPARATOR . "../lib" );
    echo get_include_path() . "
    \n";
    require_once("MDB2.php");
    $db =& MDB2::connect('mysql://root:@localhost/test');
    if (PEAR::isError($db)) {
    trigger_error($db->getMessage(), E_USER_ERROR);
    }
    $res =& $db->query('SHOW TABLES');
    if (PEAR::isError($res)) {
    die($res->getMessage());
    }
    while ($row =& $res->fetchRow(DB_FETCHMODE_ASSOC)) {
    print($row[0] . "
    \n");
    }
    $db->disconnect();

    (3)実行結果はapache経由、コマンドライン(rootでログイン、sudo、いくつかのユーザー)とも同じ結果
    .:/usr/share/php5-pear:../lib

    テーブル1

    テーブル2


    【4】次に疑うとすれば文字コード、接続文字列と、MySQLのアクセス制限
    ・テストコードはutf-8、改行はLFのみで作成しています
    ・接続文字列は上記のとおりで他のオプションはありません
    ・コマンド実行は端末からのリモートではなくサーバ上で行いました
    ・apacheとMySQLは同一サーバ上に存在します
    ・testデータベースのアクセス制限は特に行っていません

    また、何か浮かべばメッセージ送信させていただくかもしれませんが、
    回答受付中もコメントを受け付ける設定にしておいてもらえると楽になります

    以上、回答とするには不足が多すぎのため、取り急ぎメッセージ送信とさせていただいてます
  • id:n_maco2
    上記のソースコードで実行してみましたが、症状は同じでした。
    apache経由だと問題ないのですが、コマンドラインからは同じエラーです。

    一点だけ気になっているのが、DB_FETCHMODE_ASSOCがMDB2ではMDB2_FETCHMODE_ASSOCでないと動かなかったことです。
    おそらくwindofjulyさんの環境だとPEAR::DBが入っていたが私の環境でははいっていないので問題がでたんでしょうか。

    MDB2のトラブルでPEAR::DBの有無が影響してくるとも考えにくいので、
    これも直接的な原因にはなっていないように感じます。

    難しい・・
  • id:windofjuly
    うぃんど 2010/08/26 20:02:51
    PEAR-DBはインストールしてませんよ
    PEAR LISTの実行結果を貼り付けておきますが、自宅環境にセットアップしたのは「自宅サーバではPEAR環境を使っていなかったのでphpインストール時に同時にインストールされる最低限だけしか存在しないから」なのです
     
    INSTALLED PACKAGES, CHANNEL PEAR.PHP.NET:
    =========================================
    PACKAGE VERSION STATE
    Archive_Tar 1.3.3 stable
    Console_Getopt 1.2.3 stable
    MDB2 2.4.1 stable
    MDB2_Driver_mysql 1.4.1 stable
    PEAR 1.9.0 stable
    Structures_Graph 1.0.2 stable
    XML_Util 1.2.1 stable
     
    この違いから導き出されるものとしては「MDB2をPEAR INSTALLではなく手動で展開したものを設置した」のではないかという点です
    PEAR INSTALLであれば関係箇所へのリンクなども自動的に行われますので、テストコード程度では問題なく動いていることが考えられますが、手動で展開したものを置いただけではPEAR本体との連携がうまくとれず、実際に実行しようとした段階でエラーが出ると考えると自然でしょう
     
    PEARの内部解析でも行って関連付け出来ればよいのですが、この場合の対処方法は「PEAR INSTALLでインストールしてください」に落ち着くと思います
    レンタルサーバなどの場合は、PEAR INSTALLが使えない場合などもあると思いますが、その場合は、また別途考えないといけないですね
  • id:n_maco2
    ご回答ありがとうございます。
    おっしゃるとおり私の環境ではPEARコマンドを使ってインストールをしていませんでした。

    そのため
    ・PEARコマンドでMDB2とMDB2_Driver_mysqlをインストール
    ・set_include_path("/usr/share/pear/PEAR");で読み込み先のパスをPEAR本来のものだけに固定
    という形で再度実行してみました。

    が、症状に代わりはありませんでした・・
    /usr/share/pear/PEARに各パッケージが配置されているのは確認したのですが・・
  • id:n_maco2
    とりあえず、windofjulyさんのおかげでこの問題は環境依存の問題だと確信を持てましたので、いったん原因追求をストップしたいと思います。本当に実行させたい環境の準備ができましたら、そちらで再度試してみて問題なければそれでよし、といった感じで進めようと思います。

    ご協力いただき本当にありがとうございました。
    助かりました!!!

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

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

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

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