Глобальные переменные в php не работают как ожидалось
У меня возникают проблемы с глобальными переменными в php. У меня есть параметр $screen
var в одном файле, для которого требуется другой файл, который вызывает initSession()
, определенный в еще одном файле. initSession()
объявляет global $screen
, а затем обрабатывает $screen дальше вниз, используя значение, установленное в самом первом script.
Как это возможно?
Чтобы сделать вещи более запутанными, если вы попытаетесь снова установить $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
global снова перед тем, как требовать вторую модель, $screen правильно обновляется для метода initSession()
. Странно.
Ответы
Ответ 1
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
, если можете.
Ответ 2
global $foo
не означает "сделать эту переменную глобальной, чтобы каждый мог ее использовать". global $foo
означает "в рамках этой функции используйте глобальную переменную $foo
".
Я предполагаю из вашего примера, что каждый раз вы ссылаетесь на $screen изнутри функции. Если это так, вам нужно будет использовать global $screen
в каждой функции.
Ответ 3
Если у вас есть много переменных, которые вы хотите получить во время задачи, которая использует множество функций, подумайте о создании объекта "context" для хранения этого материала:
//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
Вам нужно поместить "глобальный $screen" в каждую функцию, которая ссылается на него, а не только на верхнюю часть каждого файла.
Ответ 5
В глобальные области охвата включены и требуемые файлы, вам не нужно использовать ключевое слово global, если не использовать переменную из функции. Вместо этого вы можете попробовать использовать массив $GLOBALS.
Ответ 6
Вы должны объявить переменную как глобальную, прежде чем определять значения для нее.
Ответ 7
Это бесполезно, пока оно не находится в функции или классе. Global означает, что вы можете использовать переменную в любой части программы. Поэтому, если глобальное не содержится в функции или классе, использование Global