PHPとSmartyとMySQLでWebアプリを作っていますが、

理解できないエラーが発生し、もう1週間ほど悩んでいます。
PDOを使用してデータベースに接続しているのですが、
接続部分のコードを、関数やクラスとして外部ファイルに切り出すと、
execute()でSQLクエリを発行する時に
"No Database Selected"というエラーが出てしまいます。
そこで、外部ファイルにすることに問題があるのかと思い、
試しに同じファイル内で関数として定義しても、
同じエラーが出てしまいました。
関数にしないでそのまま書き込むとエラーは生じません。
どなたか、ご教授頂けますと大変嬉しいです。
よろしくお願い致します。

以下、データベース接続部のコードです。

try {
$dsn = "mysql:dbname=$DBNM; host=$HOST";
$db = new PDO($dsn, $USER, $PASS);
} catch (PDOException $e) {
die ("接続エラー: {$e->getMessage()}");
}

関数にする場合は、getDb()という名前で
PDOオブジェクトを返すようにしていました。

function getDb() {
try {
$dsn = "mysql:dbname=$DBNM; host=$HOST";
$db = new PDO($dsn, $USER, $PASS);
} catch (PDOException $e) {
die ("接続エラー: {$e->getMessage()}");
}
return $db;
}
$db = getDb();

回答の条件
  • 1人5回まで
  • 13歳以上
  • 登録:2011/01/29 17:33:21
  • 終了:2011/02/01 23:20:36

ベストアンサー

id:okaki1 No.1

okaki回答回数2ベストアンサー獲得回数12011/01/29 19:34:01

ポイント33pt

データベースを指定してないのが原因ではないかと思います。

▼参考ページ

http://sb.xrea.com/archive/index.php/t-3206.html


実際のSQLの記載がないので分かりませんが、

select * from データベース名.テーブル名といった具合に書くとエラーが出ないのではないでしょうか?


ちなみに記載されている関数から下記のテストファイルを作成しましたが、再現しませんでした。


function getDb() {

//環境に合わせた設定

$DBNM="test";

$HOST="localhost";

$USER="test";

$PASS="test";

try {

$dsn = "mysql:dbname=$DBNM; host=$HOST";

$db = new PDO($dsn, $USER, $PASS);

echo "db connect";

} catch (PDOException $e) {

die ("error : {$e->getMessage()}");

}

return $db;

}

$db = getDb();

//環境に合わせたSQL 簡易テスト版として、execute()でなくquery()を使ってます。

//testはカラムidを持ったテーブルです。

$sql = 'SELECT id FROM test';

foreach ($db->query($sql) as $row) {

echo $row[id];

}


?>


この回答で解決しない場合は、公開できる範囲で結構ですので下記の情報を頂けると新たな回答がでやすいと思います。


・関数版(エラー)と、非関数版(非エラー)とで条件は同じか?

 参照テーブル

 DB

 テーブル

 ユーザー

・関数版のソース(SQL周りのところ)

・上記ソースをpmvctさんの環境(DB、テーブル、ユーザー、パスワード、SQL(テーブル))に修正して実行した結果

id:pmvct

お返事有り難うございました。

エラーが出ていた原因は、関数内で$DBNMなどの変数を参照していたせいでした。

globalキーワードを使用する事で、問題を解決する事が出来ました。

単純なミスで恐縮です…。

細かなアドバイス、大変感謝致しております。

2011/01/29 23:29:00

その他の回答(2件)

id:okaki1 No.1

okaki回答回数2ベストアンサー獲得回数12011/01/29 19:34:01ここでベストアンサー

ポイント33pt

データベースを指定してないのが原因ではないかと思います。

▼参考ページ

http://sb.xrea.com/archive/index.php/t-3206.html


実際のSQLの記載がないので分かりませんが、

select * from データベース名.テーブル名といった具合に書くとエラーが出ないのではないでしょうか?


ちなみに記載されている関数から下記のテストファイルを作成しましたが、再現しませんでした。


function getDb() {

//環境に合わせた設定

$DBNM="test";

$HOST="localhost";

$USER="test";

$PASS="test";

try {

$dsn = "mysql:dbname=$DBNM; host=$HOST";

$db = new PDO($dsn, $USER, $PASS);

echo "db connect";

} catch (PDOException $e) {

die ("error : {$e->getMessage()}");

}

return $db;

}

$db = getDb();

//環境に合わせたSQL 簡易テスト版として、execute()でなくquery()を使ってます。

//testはカラムidを持ったテーブルです。

$sql = 'SELECT id FROM test';

foreach ($db->query($sql) as $row) {

echo $row[id];

}


?>


この回答で解決しない場合は、公開できる範囲で結構ですので下記の情報を頂けると新たな回答がでやすいと思います。


・関数版(エラー)と、非関数版(非エラー)とで条件は同じか?

 参照テーブル

 DB

 テーブル

 ユーザー

・関数版のソース(SQL周りのところ)

・上記ソースをpmvctさんの環境(DB、テーブル、ユーザー、パスワード、SQL(テーブル))に修正して実行した結果

id:pmvct

お返事有り難うございました。

エラーが出ていた原因は、関数内で$DBNMなどの変数を参照していたせいでした。

globalキーワードを使用する事で、問題を解決する事が出来ました。

単純なミスで恐縮です…。

細かなアドバイス、大変感謝致しております。

2011/01/29 23:29:00
id:deflation No.2

deflation回答回数1036ベストアンサー獲得回数1262011/01/29 19:55:37

ポイント27pt

以下の、いずれかの設定間違いと思われます。

  1. 変数 $HOST の実体は "localhost" になっていますか?
  2. データベース名 $DBNM は間違っていませんか?

ご確認下さい。

id:pmvct

お返事有り難うございます。

私からの返信が送れてしまい、大変申し訳ございません。

エラーが出ていた原因は、関数内で$DBNMなどを参照していたせいでした。

globalキーワードを使用する事で、問題を解決する事が出来ました。

2011/02/01 23:14:53
id:taroe No.3

taroe回答回数1099ベストアンサー獲得回数1322011/01/29 21:42:23

ポイント26pt

関数にした場合にうまく行かないのでしたら、

returnの戻り値がちゃんと受け渡されて思います。

関数にして、returnに戻すのを一時的にやめて、

グローバル変数に代入して,それを使うことで動作するのなら

ちゃんと値が受け渡されてないです。

あとは、変数をvar_dampして、オブジェクトがちゃんと入ってるかどうかを

確認するしかないです。

id:pmvct

お返事とアドバイス、有り難うございます。

私からの返信が送れてしまい、大変申し訳ございません。

エラーが出ていた原因は、関数内で$DBNMなどを参照していたせいでした。

globalキーワードを使用する事で、問題を解決する事が出来ました。

2011/02/01 23:16:45
  • id:taknt
    $USER, $PASSって 関数内で使えるのかなぁ?
    値が ちゃんと入ってるのか確認してみたら?
  • id:tobeoscontinue
    関数内でグローバル変数を参照する場合はglobalキーワードでその変数がグローバルであることを知らせる必要があります。
    http://www.php.net/manual/ja/language.variables.scope.php

    function getDb() {
    global $DBNM, $HOST, $USER, $PASS;

    或はスーパーグローバルの$GLOBALSを使う方法もあります。
    $DBNM = $GLOBALS['DBNM'];
    ...

    或は単純に引数で渡す方法です。
    function getDb($DBNM, $HOST, $USER, $PASS) {

    或はdefineで定数にしてしまえばスコープの影響を受けません
  • id:pmvct
    >takntさん

    コメント有り難うございます。
    takntさんのおっしゃる通りでした。
    関数内ではglobalを付けるべきでした。

    >tobeoscontinueさん

    細かなアドバイス、大変有り難うございます。
    tobeoscontinueさんのおっしゃった通りに
    globalをつけることでエラーが出なくなりました。
    グローバル変数の参照については理解していたつもりだったのですが、
    コーディング時の意識が足らず、全く思いつきませんでした。
    他にも色々な方法を教えて頂き、大変勉強になりました。

    お二人とも、ポイントを差し上げたいのに、差し上げ方が分かりません・・・・。
    いずれにしろ、大変感謝しております。
  • id:taknt
    http://www.hatena.ne.jp/help/point

    ポイントを送信する というヘルプを参照してもらえればポイントをあげることができます。

    関数にしたら動かなくなったということは たぶん変数のスコープあたりが原因じゃないのかなと思ったのですが、PHPは そんなに詳しくないので、とりあえずコメントにしておきました。

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

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

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

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