глобалните променливи в php не работят според очакванията

Имам проблем с глобалните променливи в php. Имам набор от $screen var в един файл, който изисква друг файл, който извиква 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
глобалните са супер полезни за прости скриптове. Esp. ако имате конфигурации и 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

Безполезен е, докато не е във функция или клас. Глобално означава, че можете да използвате променлива във всяка част от програмата. Така че, ако глобалното не се съдържа във функцията или класа, няма полза от използването на Global

person user3651145    schedule 29.05.2014