ほとんどのプログラミング言語のスコープ ルールによれば、内部の関数の外部で定義された変数にアクセスできますが、このコードが機能しないのはなぜですか?
<?php
$data = 'My data';
function menugen() {
echo "[" . $data . "]";
}
menugen();
?>
出力は[]
です。
アクセスするグローバル変数を宣言する必要があるため、機能していません。
$data = 'My data';
function menugen() {
global $data; // <-- Add this line
echo "[" . $data . "]";
}
menugen();
それ以外の場合は、としてアクセスできます$GLOBALS['data']
。変数のスコープを参照してください。
少し話題から外れていても、グローバルをまったく使用せず、パラメーターとして渡すことをお勧めします。
次のいずれかを実行できます。
<?php
$data = 'My data';
function menugen() {
global $data;
echo "[" . $data . "]";
}
menugen();
または
<?php
$data = 'My data';
function menugen() {
echo "[" . $GLOBALS['data'] . "]";
}
menugen();
そうは言っても、グローバルを使いすぎると、コードが貧弱になる可能性があります。通常は、必要なものを渡すことをお勧めします。たとえば、グローバル データベース オブジェクトを参照する代わりに、ハンドルをデータベースに渡し、それに基づいて操作する必要があります。これは依存性注入と呼ばれます。自動化されたテストを実装すると、作業がずっと楽になります (そうするべきです)。
それを行う別の方法:
<?php
$data = 'My data';
$menugen = function() use ($data) {
echo "[".$data."]";
};
$menugen();
UPDATE 2020-01-13:ピーター・モーテンセンのリクエスト
PHP 5.3.0 では、クロージャを作成できる無名関数がサポートされています。クロージャーは、そのスコープ外で作成された変数にアクセスできます。
例では、句$data
で宣言されているため、クロージャーはアクセスできます。use
それは範囲の問題です。要するに、グローバル変数は避けるべきです:
パラメータとして渡す必要があります。
$data = 'My data';
function menugen($data)
{
echo $data;
}
または、クラスに入れてアクセスします
class MyClass
{
private $data = "";
function menugen()
{
echo this->data;
}
}
@MatteoTassinariの回答も参照してください。グローバルとしてマークしてアクセスできますが、グローバル変数は通常必要ないため、コーディングを再考することをお勧めします。
変数を関数に渡す必要があります。
$data = 'My data';
function menugen($data)
{
echo $data;
}