PHP:为什么使用global不是一个好的实践,以及可以使用什么来替换它


PHP: Why is not a good practice using global and what can be used to replace it?

我读到的关于这件事的答案让我感到困惑。例如:如果变量的名称发生了更改,则必须将变量的每次比较更改为函数内部的全局比较。但是,如果我将变量作为参数传递,我仍然需要更改每个比较。

var $myVar = 5;                         //this var was before $myVariable
function myFunc(){
    global $myVariable;                //it needs to be changed
}     
function myFunc($myPar){
}
var $something = myFunc($myVariable);   //it needs to be changed too

重命名不是主要好处,但这通常更容易,因为函数和函数调用通常位于不同的文件中。如果您有一个使用不同文件中的变量集的全局,它可能会很快变得混乱。如果只在单个文件中使用,那么更好的方法是将函数放在类中,并使用类属性来存储变量。

class Example {
    private $variable;
    public function exampleMethod()
    {
        $this->variable; // instead of global
    }
}

一般来说,试着将每个函数/方法视为一个独立的组件,它接受一些东西(其参数)并返回一些东西(即使它返回void)。函数在内部做什么并不重要,传递什么(假设它的类型正确)可以稍后确定。这种分离的好处是,你可以改变单个部分,而不必担心整体。一旦你开始测试全局就成了问题。

还有一个注意事项。如果您使用全局变量进行配置,请尝试将您的配置放入一个类中,如Steini所建议的,或者您可以使用JSON文件或返回数组的简单PHP文件。例如:

return [
    'setting1' => 'value'
];

在编辑代码时,总有一些事情需要更改。

在最好的情况下,重命名东西是由带有重构工具的专业IDE执行的。那么你就不必同时使用这两种方法了。

但是,您关心避免冗余代码并寻找更好的方法是非常好的,这始终是一个好方法!

然而,我个人更喜欢使用singleton模式为全局变量使用配置类:

有了这个,您还可以为每种情况创建一个getter函数,并使其更加动态。

例如:

//config.php
final class Config {
    private static $instance = null;
    private $imagePath = "/style/images";
    private $sqlDatabaseName = "db-name";
    public function getImagePath($image = null) {
        $retVal = $this->imagePath;
        if(strlen($image) > 0) {
            $retVal .= "/" . $image;
        }
        return $retVal;
    }
    public function getSqlDatabaseName() {
        return $this->sqlDatabaseName;
    }
    public static function instance() {
        if(self::$instance === null) {
            self::$instance = new self();
        }
        return self::instance;
    }
    private function __construct() { }
    private function __clone() { }
}

用法很简单:

//index.php
include("config.php");
function renderImage($imageName)
{
    return  '<img src="' . Config::instance()->getImagePath($imageName) . '" alt="img" />';
}
//Usage later in template:
<div class="bla blub">
    <?php echo renderImage("header.png"); ?>
</div>

也许你喜欢这种面向对象的方法,因为你有很多可能用函数来操纵返回值的行为。

它还使"全局"过时,因为只要包含一次包含配置的文件,就可以简单地在任何地方导入$config的单个实例。