глобальные переменные в php не работают должным образом

У меня проблемы с глобальными переменными в php. У меня есть переменная $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" 

Обновление:
Если я снова объявлю $screen глобальным непосредственно перед запросом второй модели, $screen будет корректно обновлен для метода initSession(). Странный.


person Josh Smeaton    schedule 20.09.2008    source источник
comment
global $a; эквивалентно $a =& $GLOBALS['a'];. То есть создает ссылку в локальной области видимости с тем же именем. Вне функции вы всегда находитесь в глобальной области видимости. PHP не предоставляет файловую область.   -  person Matthew    schedule 19.03.2010


Ответы (7)


Global НЕ делает переменную глобальной. Я знаю, что это сложно :-)

Global говорит, что локальная переменная будет использоваться как если бы это была переменная с более высокой областью действия.

E.G :

<?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, если можете.

person e-satis    schedule 20.09.2008
comment
Я полностью согласен с тем, чтобы избегать глобальных «если вы можете». Этот код был частью фреймворка, который мы пытались немного расширить, поэтому мы не могли избежать глобальных переменных, так как не помещали их туда. - person Josh Smeaton; 30.10.2010
comment
это верно для классов? - person Snymax; 28.06.2014
comment
Тем не менее, глобальные переменные очень полезны для простых сценариев. особ. если у вас есть конфигурации и OO не подходит. - person ; 22.01.2015

global $foo не означает "сделать эту переменную глобальной, чтобы каждый мог ее использовать". global $foo означает "в рамках этой функции используйте глобальную переменную $foo".

Из вашего примера я предполагаю, что каждый раз вы имеете в виду $screen из функции. Если это так, вам нужно будет использовать global $screen в каждой функции.

person Athena    schedule 20.09.2008

Вам нужно поместить «global $ screen» в каждую функцию, которая на него ссылается, а не только в начале каждого файла.

person finnw    schedule 20.09.2008

Если у вас есть много переменных, к которым вы хотите получить доступ во время задачи, которая использует много функций, рассмотрите возможность создания объекта «контекст» для хранения материала:

//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 классом, в котором действительно есть соответствующие методы.

person Internet Friend    schedule 20.09.2008

Глобальная область охватывает включенные и обязательные файлы, вам не нужно использовать ключевое слово global, если вы не используете переменную внутри функции. Вместо этого вы можете попробовать использовать массив $GLOBALS.

person zobier    schedule 20.09.2008

Вы должны объявить переменную как глобальную, прежде чем определять для нее значения.

person Brynner Ferreira    schedule 01.07.2012
comment
Что ваш ответ добавляет к ранее принятому и высоко оцененному ответу? Хотите прокомментировать и добавить пример кода? - person Yaroslav; 11.10.2012

Это бесполезно, пока оно не находится в функции или классе. Глобальный означает, что вы можете использовать переменную в любой части программы. Поэтому, если глобальный объект не содержится в функции или классе, нет смысла использовать глобальный.

person user3651145    schedule 29.05.2014