web-dev-qa-db-ja.com

PHPのグローバル変数が期待どおりに機能しない

PHPのグローバル変数に問題があります。 1つのファイルに_$screen_変数セットがあり、さらに別のファイルで定義されたinitSession()を呼び出す別のファイルが必要です。 initSession()は_global $screen_を宣言し、最初のスクリプトで設定された値を使用して$ screenをさらに下に処理します。

これはどのようにして可能ですか?

混乱を招くため、$ screenを再度設定してからinitSession()を呼び出すと、最初に使用した値が再度使用されます。次のコードはプロセスを説明します。誰かがこれを説明することに挑戦できますか?

_$screen = "list1.inc";            // From model.php
require "controller.php";         // From model.php
initSession();                    // From controller.php
global $screen;                   // From Include.Session.inc  
echo $screen; // prints "list1.inc" // From anywhere
$screen = "delete1.inc";          // From model2.php
require "controller2.php"         
initSession();
global $screen;
echo $screen; // prints "list1.inc" 
_

更新:
2番目のモデルが必要になる直前に_$screen_グローバルを宣言すると、$ screenはinitSession()メソッド用に正しく更新されます。奇妙な。

25
Josh Smeaton

Global変数をグローバルにしません。私はそれがトリッキーであることを知っています:-)

Globalは、ローカル変数が使用されることを示していますより高いスコープを持つ変数のように

例:

<?php

$var = "test"; // this is accessible in all the rest of the code, even an included one

function foo2()
{
    global $var;
    echo $var; // this print "test"
    $var = 'test2';
}

global $var; // this is totally useless, unless this file is included inside a class or function

function foo()
{
    echo $var; // this print nothing, you are using a local var
    $var = 'test3';
}

foo();
foo2();
echo $var;  // this will print 'test2'
?>

グローバル変数はめったに良いアイデアではないことに注意してください。コードなしで99.99999%の時間をコーディングでき、ファジースコープがない場合、コードの保守がはるかに容易になります。可能であればglobalを避けてください。

61
e-satis

global $fooは、「この変数をグローバルにして、誰もが使用できるようにする」という意味ではありません。 global $fooは、「この関数のスコープ内、グローバル変数$fooを使用する」を意味します。

私はあなたの例から、毎回関数内から$ screenを参照していると想定しています。その場合は、各関数でglobal $screenを使用する必要があります。

15
Athena

多くの関数を使用するタスク中にアクセスしたい変数がたくさんある場合は、「コンテキスト」オブジェクトを作成して内容を保持することを検討してください:

//We're doing "foo", and we need importantString and relevantObject to do it
$fooContext = new StdClass(); //StdClass is an empty class
$fooContext->importantString = "a very important string";
$fooContext->relevantObject = new RelevantObject();

doFoo($fooContext);

次に、このオブジェクトをパラメーターとしてすべての関数に渡します。グローバル変数は必要なく、関数のシグネチャはクリーンなままです。空のStdClassを、関連するメソッドが実際に含まれるクラスに置き換えるのも簡単です。

4
Internet Friend

「グローバル$ screen」は、各ファイルの先頭だけでなく、それを参照するすべての関数に配置する必要があります。

4
finnw

グローバルスコープは、含まれるファイルと必要なファイルにまたがります。関数内から変数を使用しない限り、グローバルキーワードを使用する必要はありません。代わりに$ GLOBALS配列を使用してみてください。

1
zobier

変数の値を定義する前に、変数をグローバルとして宣言する必要があります。

0

関数やクラスに入るまで役に立ちません。グローバルとは、プログラムのどの部分でも変数を使用できることを意味します。したがって、グローバルが関数またはクラスに含まれていない場合、グローバルを使用することはできません

0
user3651145