此刻,我使用称为$config
变量,这对于像文件夹的配置,数据库连接,网址应用程序以匹配大缔含阵列设置,等等。此变量在其中得到由主文件system/config.php
包括它自己的文件system/index.php
定义。
分别位于即system/request.php
某些系统功能使通过global $config;
此全局配置变量
这是不好的做法,为什么?什么会是一个更好的方式来处理全局配置?
恕我直言,只要有一个全局变量不simulatenously通过不同的工艺修改(即它是只读的所有的),它是确定有它在全球范围内。
模拟只读变量的方法是用它和一个私有变量,将返回该变量的公共方法来封装它在一个全局对象。
例:
class Config {
private $conf = array(/*read from file?*/...);
function getconf() {
//AFAIK, any attempt to write into the returned array will make PHP's
//core to duplicate it, so the original config won't be modified
//(as long as $conf does not contain objects, which are always addressed
//by reference)
return $conf;
}
}
不知从何处(全局命名空间)中的变量拉不好,因为你不知道他们是如何得到他们的价值,因为每一个类或函数可以改变它们。所以,除非你使用某种形式的最后,常量的,等来保护他们,他们会打破从长远看系统,你会花时间找出他们是如何得到他们的价值观。
for循环的替代解决方案是使用一个容器和依赖注入。
$container = new Container(array(
'x' => array(
'a' => 8,
'y' => array(
'b' => 123,
'z' => 456
)
)
));
$x = $container->getX();
$x->doSomething();
如果类之间的强耦合,因为你不希望他们是普通的东西,那么你可以这样做:
class Container {
public function __construct(array $config){
$this->config = $config;
}
public function getX(){
return new X($this->$config['x']);
}
}
class X {
public function __construct(array $config){
$this->a = $config['a'];
$this->y = new Y($config['y']);
}
public function doSomething(){}
}
class Y {
public function __construct(array $config){
$this->b = $config['b'];
$this->z = new Z($config['z']);
}
}
class Z {
public function __construct($number){
$this->number = $number;
}
}
如果这些类是松散耦合的,但你要保持层次的配置(例如,因为你必须在不同的CONFIGS您的容器多个Y和Z的实例),那么你可以这样做:
class Container {
public function __construct(array $config){
$this->config = $config;
}
public function getX(){
return new X($this->$config['x']['a'], $this->getXY());
}
public function getXY(){
return new Y($config['x']['y']['b'], $this->getXYZ());
}
public function getXYZ(){
return new Z($config['x']['y']['z']);
}
}
class X {
public function __construct($a, Y $y){
$this->a = $a;
$this->y = $y;
}
public function doSomething(){}
}
class Y {
public function __construct($b, Z $z){
$this->b = $b;
$this->z = $z
}
}
class Z {
public function __construct($number){
$this->number = $number;
}
}
即使你没有OOP开发,你应该把你的依赖作为参数,而不是全局变量。
function main($config){
$x = $config['x'];
$a = $x['a'];
$y = $x['y'];
doXSomething($a, $y);
}
function doXSomething($a, array $y){
$b = $y['b'];
$z = $y['z'];
$p = doY($b, $z);
// ...
}
function doY($b, $z){
$q = doZ($z);
// ...
}
function doZ($z){
// ...
}
$config = array(
'x' => array(
'a' => 8,
'y' => array(
'b' => 123,
'z' => 456
)
)
);
main($config);
你的代码应该只依赖于局部变量,所以你可以肯定的是,该应用程序运行时,他们没有从不同的功能改变。
使用全局变量的另一个原因是糟糕的可测试性。如果你写一个测试的功能,那么你必须设置一个配置变量。如果深度嵌套的,那么你这样做
$config = array('x' => array('y' => array('z' => 123)))`;
$result = doZ();
expect($result)->toBe(435);
如果没有全局变量,你可以做
$result = doZ(123);
expect($result)->toBe(435);
基于文件的名字,我想你当时5年前有某种的意大利面条代码。