PHP中的全局变量被认为是错误的做法吗?若然,原因为何?

PHP中的全局变量被认为是错误的做法吗?若然,原因为何?,php,global-variables,global,Php,Global Variables,Global,在我的小PHP项目中,我通常采用过程化的方式。我通常有一个包含系统配置的变量,当我需要在函数中访问这个变量时,我会global$var 这是一种糟糕的做法吗?当人们在其他语言中谈论全局变量时,它的含义与在PHP中所做的不同。这是因为变量在PHP中并不是真正的全局变量。典型PHP程序的作用域是一个HTTP请求。会话变量实际上比PHP“全局”变量的范围更广,因为它们通常包含许多HTTP请求 通常(总是?)您可以在preg\u replace\u callback()等方法中调用成员函数,如下所示:

在我的小PHP项目中,我通常采用过程化的方式。我通常有一个包含系统配置的变量,当我需要在函数中访问这个变量时,我会
global$var


这是一种糟糕的做法吗?

当人们在其他语言中谈论全局变量时,它的含义与在PHP中所做的不同。这是因为变量在PHP中并不是真正的全局变量。典型PHP程序的作用域是一个HTTP请求。会话变量实际上比PHP“全局”变量的范围更广,因为它们通常包含许多HTTP请求

通常(总是?)您可以在
preg\u replace\u callback()
等方法中调用成员函数,如下所示:

function foo () {
    global $var;
    // rest of code
}
更多信息,请参阅

关键是对象已经被固定到PHP上,并且在某些方面导致了一些尴尬

不要过分关注将不同语言的标准或结构应用于PHP。另一个常见的陷阱是试图将PHP转变为纯OOP语言,方法是将对象模型粘贴在所有对象之上


像其他任何东西一样,使用“全局”变量、过程代码、特定框架和OOP,因为它有意义,解决了问题,减少了需要编写的代码量,或者使其更易于维护和理解,而不是因为你认为应该这样做。

我同意克莱特斯的观点。我想补充两点:

  • 使用前缀,以便您可以立即将其标识为全局(例如$g_)
  • 在一个地方声明它们,不要把它们散布在代码周围
  • 致以最良好的祝愿,
    don

    如果不小心使用全局变量,可能会使问题更难发现。假设您请求了一个php脚本,并收到一条警告,表示您试图访问某个函数中不存在的数组索引

    如果您试图访问的数组是函数的本地数组,请检查函数以查看是否有错误。函数的输入可能有问题,因此请检查调用函数的位置

    但如果该数组是全局的,则需要检查使用该全局变量的所有位置,不仅如此,还必须确定访问这些全局变量的引用的顺序


    如果在一段代码中有一个全局变量,则很难隔离该代码的功能。为什么要隔离功能?因此,您可以测试它并在其他地方重用它。如果您有一些代码不需要测试,也不需要重用,那么使用全局变量就可以了。

    谁能反对经验、大学学位和软件工程?不是我。我只想说,在开发面向对象的单页PHP应用程序时,当我知道我可以从头开始构建整个程序而不必担心名称空间冲突时,我会有更多的乐趣。许多人不再做白手起家的建筑了。他们需要关心的是工作、期限、奖金或声誉。这些类型倾向于使用大量高风险的预构建代码,因此根本无法冒险使用全局变量

    使用全局变量可能不好,即使它们只用于程序的全局区域,但我们不要忘记那些只想玩得开心、让某些东西工作的人

    如果这意味着在全局名称空间中使用一些变量(<10),那么这些变量只能在程序的全局区域中使用,就这样吧。是的,是的,MVC,依赖注入,外部代码,诸如此类。但是,如果您已经将99.99%的代码包含在名称空间和类中,并且外部代码是沙盒的,那么如果您使用全局变量,世界不会结束(我重复,世界不会结束)

    一般来说,我不会说使用全局变量是不好的做法。我想说的是,在程序的全局区域之外使用全局变量(标志等)是自找麻烦,而且(从长远来看)是不明智的,因为您很容易失去对其状态的跟踪。另外,我想说的是,您学习的越多,您对全局变量的依赖性就越低,因为您将体验到跟踪与其使用相关的bug的“乐趣”。这本身就会激励你找到另一种方法来解决同样的问题。巧合的是,这会促使PHP人员学习如何使用名称空间和类(静态成员等)

    计算机科学的领域是广阔的。如果我们因为给某件事贴上坏标签而吓跑了所有人,那么他们就失去了真正理解标签背后道理的乐趣

    如果必须使用全局变量,请使用全局变量,然后查看是否可以在没有全局变量的情况下解决问题。当您深入了解问题的真实本质,而不仅仅是对问题的描述时,冲突、测试和调试意味着更多

    从截止SO测试版文档重新发布

    我们可以用下面的伪代码来说明这个问题

    preg_replace_callback('!pattern!', array($obj, 'method'), $str);
    
    你的第一个问题很明显

    $bob
    来自哪里

    你糊涂了吗?好。您刚刚了解了为什么globals令人困惑,并被认为是一种糟糕的做法。如果这是一个真正的程序,那么下一个有趣的事情就是跟踪
    $bob
    的所有实例,并希望找到正确的实例(如果到处都使用
    $bob
    ,情况会变得更糟)。更糟糕的是,如果其他人去定义
    $bob
    (或者您忘记并重用了该变量),您的代码可能会中断(在上面的代码示例中,使用错误的对象,或者根本没有对象,将导致致命错误)。因为几乎所有的PHP程序都使用像
    include('file.PHP')这样的代码添加的文件越多,维护这样的代码的工作就会变得越来越困难

    我们如何避免全球化?

    避免全球化的最好方法是一种叫做的哲学。这是我们传递工具w的地方
    function foo() {
         global $bob;
         $bob->doSomething();
    }
    
    function foo(\Bar $bob) {
        $bob->doSomething();
    }
    
    global $my_global; 
    $my_global = 'Transport me between functions';
    Equals $GLOBALS['my_global']
    
    $my-global = 'Transport me between functions';
    
    $GLOBALS['my-global'] = 'Transport me between functions';
    
    $GLOBALS['PREFIX-MY-GLOBAL'] = 'Transport me ... ';
    
    $GLOBALS['PREFIX-MY-GLOBAL']['context-something'] = 'Transport me ... ';
    $GLOBALS['PREFIX-MY-GLOBAL']['context-something-else']['numbers'][] = 'Transport me ... ';