Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 好主意还是坏主意?使用静态类变量存储全局_Php_Design Patterns_Global Variables - Fatal编程技术网

Php 好主意还是坏主意?使用静态类变量存储全局

Php 好主意还是坏主意?使用静态类变量存储全局,php,design-patterns,global-variables,Php,Design Patterns,Global Variables,我的代码中到处都在使用一个类。它包含设置和其他核心功能。下面是我现在正在做的使用这个类 $settings = new Settings(); $settings->loadSettings(); 然后,当我需要在另一个类中的某个随机函数中编写代码时,我会这样做: function abc() { global $settings; $variable = $settings->a; } Settings::$settings = new Settings();

我的代码中到处都在使用一个类。它包含设置和其他核心功能。下面是我现在正在做的使用这个类

$settings = new Settings();
$settings->loadSettings();
然后,当我需要在另一个类中的某个随机函数中编写代码时,我会这样做:

function abc() {
    global $settings;
    $variable = $settings->a;
}
Settings::$settings = new Settings();
Settings::$settings->loadSettings();
我厌倦了到处随机调用global$settings来拉入设置对象。我不想使用$\u GLOBALS数组(我不知道为什么,我只是不想)

我想我想切换到设置中有一个名为$settings的静态类变量。代码如下所示:

function abc() {
    global $settings;
    $variable = $settings->a;
}
Settings::$settings = new Settings();
Settings::$settings->loadSettings();
然后,无论何时我想使用它,我都不必担心通过全局操作员将其吸入:

function abc() {
    $variable = Settings::$settings->a;
}

好主意还是坏主意?

这可能是对globals的改进,因为它解决了globals导致的所有难看的范围界定问题。摆脱全局操作符通常是一件好事!您所做的与单例模式没有什么不同,尽管它相当简单。(有关该模式的更多信息,请参阅上的“Singleton”部分。)您的解决方案几乎可以满足您的需求

另一方面,可能有更好的方法来实现同样的事情,从而使代码更加解耦。也就是说,每一个类在不需要大量重新编码的情况下,都能够在另一个项目中使用。一种方法是将设置对象“注入”到每个类中:

class ABC {
    private $settings;

    public function __construct($settings) {
        $this->settings = $settings;
    }

    public function someMethod() {
        $variable = $this->settings->a;
    }
}
这将是更多的工作,但可能会提高代码的可重用性。例如,您可以为每个项目编写不同的设置类,但使用相同的ABC类


将对象“注入”到依赖它的另一个对象中的过程称为依赖项注入。还有其他更复杂的方法,包括复杂的容器。有关此主题的一组有趣教程,请参见。它们可能是您当前需要的附带条件,但可能在现在或将来有所帮助。

您似乎正在寻找一个合适的解决方案。基本上,这个想法是让一个类具有一个公共静态方法getInstance(),该方法返回类本身的一个实例。第一次调用该方法时,它将实例存储在私有属性中,之后所有时间都返回存储的实例。这样,无论何时调用Settings::getInstance(),都可以保证拥有同一对象的副本。然后,您可以将设置存储在此对象中。

感谢您的精彩回答,这可能是重复的。但是,通过这种方式,我们必须使用全局实例编写更长的代码,这里是
$setting
,而不是使用
$settings
,对吗?我看不出这有什么好处,为什么人们避免使用
global
关键字?您可以在
\u construct
上全局获取
$settings
,而不是在声明实例时传递对象,在这种情况下使用引用会更好吗<代码>$this->settings=&$settings这有助于减少内存使用吗?-1:在这种情况下,静态类和单例类之间没有区别。是的,有一个,这就是一个(可能是另一个程序员)不能错误地创建设置的另一个实例,而不是使用设置::$settings。singleton模式所做的就是执行这个约定。singleton是反模式的,不应该使用。我同意,单身汉很容易被虐待。但是,如果原始海报实际上希望使用静态类变量来保存实例,那么最好使用单例。当然,人们可能会质疑使用这样一个变量来保存全局设置是否真的是一个好主意,或者更确切地说是使用依赖项注入。但在某些情况下,这可能是合理的,而且对于一个人可以使用或不能使用的东西进行教条式的教条化实际上没有任何好处。