PHPで初歩的な質問です。

以下のスクリプトを実行するとtest1()内ではheader.phpの値が代入されません。
test1()のrequire_onceをrequireにするとheader.phpの値が代入されます。
基本的には、require_onceは関数を跨ぐと再度読み込まれると解釈していたのですが、どうも読み込まれないようです。
実用的には多くの関数で構成されるシステムの場合、個々の関数でdefineを読み込むようなケースが多いと思いますが、そのような場合は一般的にrequireを使用するものなのでしょうか?
require_onceを使いたかったのですが、設定で変更することは可能でしょうか?
よろしくご教授お願いいたします。

●動作結果
test0 : A = 1234
test0 : B = 5678
test1 : A =
test1 : B =

●header.php
<?php
$a = '1234';
$b = '5678';
?>

●test.php
<?php
function test1() {
require_once "header.php";
echo "test1 : A = " . $a . "<BR>";
echo "test1 : B = " . $b . "<BR>";
}
require_once "header.php";
echo "test0 : A = " . $a . "<BR>";
echo "test0 : B = " . $b . "<BR>";
test1();
?>

回答の条件
  • URL必須
  • 1人3回まで
  • 登録:2009/10/19 12:50:34
  • 終了:2009/10/20 16:24:04

ベストアンサー

id:horonict No.1

horonict回答回数257ベストアンサー獲得回数512009/10/19 12:55:34

ポイント27pt

require_once関数は一度しか実行されません。

http://jp2.php.net/manual/ja/function.require-once.php


したがって、test.phpの2番目のrequire_once関数は実行されません。

一方、最初のrequire_once関数で読み込まれた$a,$bは、関数test1内のローカル変数になっています。

このため、test1関数の外側で$a,$bを呼び出しても、まだ値が設定されていない状態と見なされます。


もしtest1の外側でも$a,$bの値を表示させたいなら、下記のようにグローバル変数として扱うことです。

<?php
require_once "header.php";
function test1() {
    global $a, $b;
    echo "test1 : A = " . $a . "<BR>";
    echo "test1 : B = " . $b . "<BR>";
}

echo "test0 : A = " . $a . "<BR>";
echo "test0 : B = " . $b . "<BR>";
test1();
?>
id:cochoo

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

なるほど、変数のスコープについて勘違いしていました。

test1()内の変数$a, $bはローカル変数なのはわかるのですが、

たとえば、test1()以外に汎用関数としてtest2()、test3()…とあった場合、

それぞれの関数で同じ固定値(定義値)を参照したい場合、次のような対策が考えられるのですが、どれもデメリットがあるので、他によい方法がないかと思案しておりました。

①それぞれの関数内に同じ固定値を書く … 保守性が下がる

②グローバル変数を利用 … セキュリティが下がる

③関数の引数に渡す … 参照値が多いと問題(配列にしてもいいが、煩雑化する)

④requireで参照 … 毎回読み込むのでリソースが懸念

呼び出し関係などプログラムの構造を見直す必要がありそうです。

もう少し検討してみます。ありがとうございました!

2009/10/19 13:11:07

その他の回答(2件)

id:horonict No.1

horonict回答回数257ベストアンサー獲得回数512009/10/19 12:55:34ここでベストアンサー

ポイント27pt

require_once関数は一度しか実行されません。

http://jp2.php.net/manual/ja/function.require-once.php


したがって、test.phpの2番目のrequire_once関数は実行されません。

一方、最初のrequire_once関数で読み込まれた$a,$bは、関数test1内のローカル変数になっています。

このため、test1関数の外側で$a,$bを呼び出しても、まだ値が設定されていない状態と見なされます。


もしtest1の外側でも$a,$bの値を表示させたいなら、下記のようにグローバル変数として扱うことです。

<?php
require_once "header.php";
function test1() {
    global $a, $b;
    echo "test1 : A = " . $a . "<BR>";
    echo "test1 : B = " . $b . "<BR>";
}

echo "test0 : A = " . $a . "<BR>";
echo "test0 : B = " . $b . "<BR>";
test1();
?>
id:cochoo

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

なるほど、変数のスコープについて勘違いしていました。

test1()内の変数$a, $bはローカル変数なのはわかるのですが、

たとえば、test1()以外に汎用関数としてtest2()、test3()…とあった場合、

それぞれの関数で同じ固定値(定義値)を参照したい場合、次のような対策が考えられるのですが、どれもデメリットがあるので、他によい方法がないかと思案しておりました。

①それぞれの関数内に同じ固定値を書く … 保守性が下がる

②グローバル変数を利用 … セキュリティが下がる

③関数の引数に渡す … 参照値が多いと問題(配列にしてもいいが、煩雑化する)

④requireで参照 … 毎回読み込むのでリソースが懸念

呼び出し関係などプログラムの構造を見直す必要がありそうです。

もう少し検討してみます。ありがとうございました!

2009/10/19 13:11:07
id:b-wind No.2

b-wind回答回数3344ベストアンサー獲得回数4402009/10/19 13:28:57

ポイント27pt

それぞれの関数で同じ固定値(定義値)を参照したい場合

固定値なら定数でいいのでは?

PHP: 絎���� - Manual

id:cochoo

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

それはそうですね^^

たとえば、環境に依存するAuthとかDBの設定を想定していたのですが、

もともと私自身がCやJAVAプログラマだったので、そのようなケースでは定数より変数の方がしっくりくると考えていました。

本来、そのような環境に依存する処理は1箇所にまとめるのが普通なのですが、拡張の拡張を重ねると、どうしても、このような問題に突き当たります。

修正による影響を考え、構造の見直しより、requireかグローバル、もしくは、定数で対応したいと思います。

ありがとうございました。

2009/10/19 13:51:55
id:y-kawaz No.3

y-kawaz回答回数1421ベストアンサー獲得回数2262009/10/19 13:52:42

ポイント26pt

スコープの問題は解決されたようなので固定値の参照方法についてのレスです。


一般的には固定値の定義には define を使うんじゃないでしょうか(英語の意味も「定義する」という単語ですし)。

単純な文字列や数値ではなく、配列で定義するようなモノであればグローバル変数を使うか、クラスを作ってクラス変数にするとか。

あとはMVCフレームワークなんかだと、親クラスがインスタンスにセットしてくれているのでサブクラスはそれを使うだけとか、そもそも設定値が隠蔽されていて直接触る必要が無いようになっているというパターンもありますね。


ところで、

>②グローバル変数を利用 … セキュリティが下がる

これに関してですがグローバル変数にすると何でセキュリティが下がるとお考えでしょうか?

register_globals が有効にでもされていない限りはセキュリティ上の問題は無いと思うのですが。

http://q.hatena.ne.jp/answer

コメントはまだありません

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

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

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

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