2011-12-05 21 views
3

私の関数は、外部変数(親関数からの変数)にアクセスする必要があります。ただし、globalキーワードを使用すると、範囲が広すぎます。私はそれを制限する必要があります。このコードを「レベル1」の代わりに「レベル2」を吐き出すにはどうすればよいですか?私はクラスを作る必要がありますか?親関数のスコープから変数にアクセスする方法は?

<?php 
$a = "Level 1"; 

function first() { 
    $a = "Level 2"; 

    function second() { 
     global $a; 
     echo $a.'<br />'; 
    } 

    second(); 
} 

first(); 
//outputs 'Level 1' 
?> 

答えて

9

PHPにはネストされた関数やスコープの概念がなく、関数をネストするのはひどい習慣です。何が起こるかというと、PHPは単に関数宣言に遭遇し、通常の関数secondを作成します。 firstを再度呼び出すと、secondがすでに宣言されているので、PHPは再びsecondの関数宣言を受け取り、クラッシュします。したがって、関数内で関数を宣言しないでください。

値を渡す場合は、関数のパラメータとして明示的に渡すか、あるいは、あなたが言うように、の場合は、クラスを作成します。私はあなたが何をしようとして理解すれば

+0

Aha!教育的な答えに感謝します。それは多くの意味があります、あなたはそれをうまく説明しました。私は関数のパラメータのルートを試してみましょう。 –

+0

でも防御的に 'if(function_exists( 'second')){{'} – WraithKenny

25

ちょうど例のため、あなたはuseで「クロージャも親スコープから変数を継承することができる」とclosure(PHPを5.3+)、使用することができますキーワード。

$a = "Level 1"; 

function first() { 
    $a = "Level 2"; 

    $func = function() use ($a) { 
     echo $a.'<br />'; 
    }; 

    $func(); 
} 

first(); 
// prints 'Level 2<br />' 

コールバック関数で最も一般的に使用されます。ただし、これを使用するのは最善のシナリオではないかもしれません。他人が示唆しているように、あなたが何かできることがあったとしても、それが最良のアイデアだとは限りません。

+0

あなたが高速です。私はその提案を将来の参照のために残しておきます。ありがとう! –

+0

コールバック関数のデータを渡す必要があったため、参照渡しに 'use(&$ a)'と書かなければなりませんでした。 (preg_replace_callbackのシナリオからの一致が記憶されています) – ygoe

関連する問題