ほとんどのプログラミング言語のスコープルールに従って、関数内の関数の外部で定義されている変数にアクセスできますが、このコードが機能しないのはなぜですか?
<?php
$data = 'My data';
function menugen() {
echo "[" . $data . "]";
}
menugen();
?>
出力は[]
です。
ほとんどのプログラミング言語のスコープルールに従って、関数内の関数の外部で定義されている変数にアクセスできますが、このコードが機能しないのはなぜですか?
<?php
$data = 'My data';
function menugen() {
echo "[" . $data . "]";
}
menugen();
?>
出力は[]
です。
回答:
アクセスするグローバル変数を宣言する必要があるため、機能していません。
$data = 'My data';
function menugen() {
global $data; // <-- Add this line
echo "[" . $data . "]";
}
menugen();
それ以外の場合は、としてアクセスできます$GLOBALS['data']
。可変スコープを参照してください。
少し話題から外れたとしても、グローバルをまったく使用せず、パラメーターとして渡すことをお勧めします。
This script will not produce any output because the echo statement refers to a local version of the $a variable, and it has not been assigned a value within this scope.
次のいずれかを実行できます。
<?php
$data = 'My data';
function menugen() {
global $data;
echo "[" . $data . "]";
}
menugen();
または
<?php
$data = 'My data';
function menugen() {
echo "[" . $GLOBALS['data'] . "]";
}
menugen();
そうは言っても、グローバルを使いすぎると、コードが貧弱になる可能性があります。通常、必要なものを渡す方がよいでしょう。たとえば、グローバルデータベースオブジェクトを参照する代わりに、データベースにハンドルを渡して、それに基づいて動作する必要があります。これは依存性注入と呼ばれます。自動テストを実装すると、作業がずっと楽になります(そうすべきです)。
それは範囲の問題です。要するに、グローバル変数は避けるべきなので:
パラメータとして渡す必要があります。
$data = 'My data';
function menugen($data)
{
echo $data;
}
または、クラスに入れてアクセスします
class MyClass
{
private $data = "";
function menugen()
{
echo this->data;
}
}
@MatteoTassinariの回答も参照してください。アクセスするにはグローバルとしてマークできますが、グローバル変数は通常必要ないため、コーディングを再考することをお勧めします。
menugen()
単にメニューを生成するだけではなく、さらに多くのことが行われることを意味します。たとえば、そのメニューを拡張して別のソースからアイテムを追加する場合や、メニューにある現在選択されているページを選択する場合はどうでしょうか。ランダムなグローバル変数とロジックがいたるところにあると、OOP設計が叫ばれます。PHP / JSを構造化する必要がないという事実は、厄介な不格好なコードがたくさんある最大の理由の1つです。それは非常にうまく行うことができますが、人々は将来の保守性について考えることができません。
それを行う別の方法:
<?php
$data = 'My data';
$menugen = function() use ($data) {
echo "[".$data."]";
};
$menugen();
更新2020-01-13:PeterMortensenからのリクエスト
PHP 5.3.0以降、クロージャを作成できる無名関数がサポートされています。クロージャは、そのスコープ外で作成された変数にアクセスできます。
この例では、クロージャは句で$data
宣言されているため、アクセスできますuse
。
何年もの間、私は常にこのフォーマットを使用してきました:
<?php
$data = "Hello";
function sayHello(){
echo $GLOBALS["data"];
}
sayHello();
?>
私はそれが簡単でわかりやすいと思います。$ GLOBALSは、PHPでグローバル変数を参照する方法です。$ _SERVER、$ _ POSTなどを使用したことがある場合は、それを知らなくてもグローバル変数を参照しています。
変数を関数に渡す必要があります。
$data = 'My data';
function menugen($data)
{
echo $data;
}
<?php
$data = 'My data';
$menugen = function() use ($data) {
echo "[ $data ]";
};
$menugen();
?>
簡略化することもできます
echo "[" . $data . "]"
に
echo "[$data]"
echo "[" . $data . "]"
とecho "[ $data ]"
は同じではありません(後者の出力には2つの余分なスペースがあります)。
このため、PHPはイライラする可能性があります。上記の使用法の答えglobal
は私にはうまくいきませんでした、そして私はの適切な使用法を理解するのにしばらく時間がかかりましたuse
。
これは正しいです:
$functionName = function($stuff) use ($globalVar) {
//do stuff
}
$output = $functionName($stuff);
$otherOutput = $functionName($otherStuff);
これは正しくありません:
function functionName($stuff) use ($globalVar) {
//do stuff
}
$output = functionName($stuff);
$otherOutput = functionName($otherStuff);
特定の例を使用して:
$data = 'My data';
$menugen = function() use ($data) {
echo "[" . $data . "]";
}
$menugen();
必要に応じて、「define」関数を使用できますが、この関数は、一度定義すると変更できない定数を作成します。
<?php
define("GREETING", "Welcome to W3Schools.com!");
function myTest() {
echo GREETING;
}
myTest();
?>