めのん@ひとりプログラミング同好会

このブログはすべてフィクションであり、実在の人物、団体とは一切関係ありません

includeとスコープ 第2回

おはようございます、めのんです!

今回は昨夜の続きで、PHPのincludeのスコープについての話題です。 おさらいになりますが、公式ドキュメントからそれに関する記述を引用します。

ファイルが読み込まれるとそのファイルに含まれるコードは、 includeもしくはrequireが実行された 行の変数スコープを継承します。 呼び出し側の行で利用可能である全ての変数は、読み込まれたファイル内で利用可能です。 しかし、読み込まれたファイル内で定義されている関数やクラスはすべて グローバルスコープとなります。

PHPのバージョンによって事情が異なるかもしれませんので、私が使っているPHPのバージョンが7.4.7であることをお伝えしておきます。

ソースコードをそのまま取り込むだけであれば、関数にincludeを記述すれば、取り込んだ内容がすべてその関数内スコープになるはずです。 ところが公式ドキュメントでは、関数やクラスはグローバルスコープになるそうです。

私はちょっと疑り深いので、実際に試してみました。

f:id:elddiry:20200630233520p:plain

こういうごく単純なコードを試してみました。 公式ドキュメントの通りだとすれば、b.phpで定義しているAクラスもg関数もグローバルスコープになるはずです。

ところが、このコードを実行すると、次のようなエラーが発生しました。

f:id:elddiry:20200630233735p:plain

Aクラスが見つからないそうです。 おかしいですよね。

しかたがないのでa.phpの8行目をコメントアウトすると、エラー無く実行することができました。

今度はf関数の中で呼び出していたg関数を、直接グローバルスコープから呼び出してみようと思いました。 a.phpの9行目ではもともとf関数を呼び出していましたが、ここをg関数を呼び出すように修正すると、次のようなエラーが発生しました。

f:id:elddiry:20200630234152p:plain

なんか納得いかない結果になってしまいました。

先入観無しに素直に事実を受け止めれば、公式ドキュメントが間違っている気がします。 実際のところどうなんでしょうか?

念のため、PHPでは関数の中でクラスや関数を定義できるのかも試してみました。 すると、問題なく関数内でクラスや関数を定義することができ、そのクラスや関数は関数内スコープになっていました。

普通に考えて、関数からincludeで取り込んだソースファイルに記述したクラスや関数は関数内スコープになっていると思うのですが、実際のところはどうなんでしょうか? どうか詳しい方、ご教示いただけると幸いです。

それでは!!