94

ほとんどのプログラミング言語のスコープ ルールによれば、内部の関数の外部で定義された変数にアクセスできますが、このコードが機能しないのはなぜですか?

<?php
    $data = 'My data';

    function menugen() {
        echo "[" . $data . "]";
    }

    menugen();
?>

出力は[]です。

4

8 に答える 8

178

アクセスするグローバル変数を宣言する必要あるため、機能していません。

$data = 'My data';

function menugen() {
    global $data; // <-- Add this line

    echo "[" . $data . "]";
}

menugen();

それ以外の場合は、としてアクセスできます$GLOBALS['data']変数のスコープを参照してください。

少し話題から外れていても、グローバルをまったく使用せず、パラメーターとして渡すことをお勧めします。

于 2013-03-28T16:38:58.500 に答える
22

次のいずれかを実行できます。

<?php
    $data = 'My data';

    function menugen() {
        global $data;
        echo "[" . $data . "]";
    }

    menugen();

または

<?php
    $data = 'My data';

    function menugen() {
        echo "[" . $GLOBALS['data'] . "]";
    }

    menugen();

そうは言っても、グローバルを使いすぎると、コードが貧弱になる可能性があります。通常は、必要なものを渡すことをお勧めします。たとえば、グローバル データベース オブジェクトを参照する代わりに、ハンドルをデータベースに渡し、それに基づいて操作する必要があります。これは依存性注入と呼ばれます。自動化されたテストを実装すると、作業がずっと楽になります (そうするべきです)。

于 2013-03-28T16:42:03.640 に答える
16

それを行う別の方法:

<?php

$data = 'My data';

$menugen = function() use ($data) {

    echo "[".$data."]";
};

$menugen();

UPDATE 2020-01-13:ピーター・モーテンセンのリクエスト

PHP 5.3.0 では、クロージャを作成できる無名関数がサポートされています。クロージャーは、そのスコープ外で作成された変数にアクセスできます。

例では、句$dataで宣言されているため、クロージャーはアクセスできます。use

于 2016-02-05T20:32:47.357 に答える
12

それは範囲の問題です。要するに、グローバル変数は避けるべきです:

パラメータとして渡す必要があります。

$data = 'My data';

function menugen($data)
{
    echo $data;
}

または、クラスに入れてアクセスします

class MyClass
{
    private $data = "";

    function menugen()
    {
        echo this->data;
    }

}

@MatteoTassinariの回答も参照してください。グローバルとしてマークしてアクセスできますが、グローバル変数は通常必要ないため、コーディングを再考することをお勧めします。

于 2013-03-28T16:40:20.683 に答える
-2

変数を関数に渡す必要があります。

$data = 'My data';

function menugen($data)
{
    echo $data;
}
于 2013-03-28T16:38:29.800 に答える