在 oop 中设置全局变量的最佳方法


Best way to setup global variables in oop?

我很难找到答案,我确信它就在我面前,但我无法把它放在一起。

    //Global Variables
    global $GLOBAL;
    $GLOBAL['myPluginPath'] = dirname( __FILE__ );

    //Main Object   
    class My_Class {
            public function __construct() {
                    // Initialize Settings
                    require_once $GLOBAL['myPluginPath'] . '/settings.php';
                    $My_Settings = new My_Settings();
            } 
     }

我想使用一个变量,这样我的代码感觉更有条理,我觉得当以这种方式定义路径时,我可以更好地阅读我的代码,并且可以更轻松地更改变量,以便在需要时将其应用于整个代码。

我可以通过在方法中编写它来使变量工作。

    public function WhatEverFunc() {
        global $GLOBAL
        require_once $GLOBAL['myPluginPath'] . '/settings.php'; 
   }

这里的主要问题是,我想知道这是否是不好的做法,如果不是,是否有更好的方法,那么必须在每种方法中定义global $GLOBAL。但是,如果这是不好的做法,你能给我看好的做法吗?

还有一件事我真的很好奇。在主__construct中,你看到我不使用 global $GLOBAL,因为它在没有它的情况下工作,但在那个require_once文件中是另一个类,它有必须在其中使用的方法global $GLOBAL。希望有人能解释一下。

我认为,有人说这是不好的做法。我读到有一个单例模式(不好的做法)和一个全局模式。不确定我上面做了什么构成,我只是有点迷茫,不知道我应该在这里做什么,我正在努力实现什么。

一个对象实际上应该拥有执行它所设计的任何功能所需的一切。如果没有,则应通过参数将数据传递给它。

对象

与过程代码的部分意义在于,对象可以在许多地方一遍又一遍地重用。

让我们使用这个例子来说明为什么使用 Globals 和 OOP 是一个坏主意:

假设你有一个很棒的前端代码,并且你通过对象编写它。在某个时候,您需要针对网站中的数据创建其他报告。您开始编码并意识到您可以从前端重用您的类来实现几乎所有您需要的东西 - 但可惜您的代码包含大量对全局变量的引用,这些全局变量仅在从某个脚本调用时才在前端可见。

这基本上只是使您的对象相当不可重用。

虽然这可能不是最好的做法,但我经常写一个快速类来抓住各种$GET$_POST和其他可能被认为是"全局"的变量,如 URL 参数等,然后在我的代码中,我要么根据需要将这些信息直接传递给对象/函数,要么确实传递整个对象(很少)。

使用这种方法,我总是完全准备好重用对象,确切地知道它们需要什么来运行,因为它们在参数中都是必需的。

你为什么不使用$GLOBALS?您甚至不需要使用global关键字。

这里的主要问题,我想知道这是否是不好的做法

好吧,我相信大多数人会说拥有全局状态是不好的实践,因为它更难管理或进行单元测试。大多数人会建议你使用"依赖注入",而不是依赖于全局状态,你需要直接注入类需要的东西。

从您的代码来看,您似乎只是在寻找一种将类名解析为文件名的方法。为此,最好使用自动加载程序。它使类如何映射到文件名的形式远离大部分代码,以便您可以专注于实际开发。

可以使用命名空间来组织插件。

其次,在大多数情况下,你不想在构造函数中实例化类,因为它会导致耦合,而过多的耦合可能会扼杀你的项目;相反,注入依赖项:

class My_Class 
{
    private $settings;
    public function __construct(My_Settings $settings) {
        $this->settings = $settings;
    } 
}

要调用它:

$c = new My_Class(new My_Settings());

使用此示例来解决您的问题

全局关键字并不像您认为的那样工作。它不会使变量具有全局范围。它所做的只是指定要在其中调用它的函数,以便在外部作用域中使用变量。

例如:

$a="test";
function something() {
    global $a;
    echo $a;  //Outputs: test
}

如果要使变量全局化,以便可以从类中访问它,则需要使用超全局变量$GLOBALS。