【发布时间】:2011-04-12 22:05:40
【问题描述】:
对于我的项目,我编写了一个小型配置类,用于从 .ini 文件加载其数据。它覆盖了神奇的 __get() 方法,以提供对(只读)配置值的简化访问。
config.ini.php 示例:
;<?php exit; ?>
[General]
auth = 1
user = "halfdan"
[Database]
host = "127.0.0.1"
我的配置类(单例模式 - 此处简化)如下所示:
class Config {
protected $config = array();
protected function __construct($file) {
// Preserve sections
$this->config = parse_ini_file($file, TRUE);
}
public function __get($name) {
return $this->config[$name];
}
}
加载配置会创建一个这样的数组结构:
array(
"General" => array(
"auth" => 1,
"user" => "halfdan"
),
"Database" => array(
"host" => "127.0.0.1"
)
)
可以通过Config::getInstance()->General 访问数组的第一级,使用Config::getInstance()->General['user'] 访问值。我真正想要的是能够通过执行Config::getInstance()->General->user(语法糖)来访问所有配置变量。该数组不是一个对象,并且没有在其上定义“->”,所以这根本失败。
我想到了一个解决方案,并希望得到一些公众意见:
class Config {
[..]
public function __get($name) {
if(is_array($this->config[$name])) {
return new ConfigArray($this->config[$name]);
} else {
return $this->config[$name];
}
}
}
class ConfigArray {
protected $config;
public function __construct($array) {
$this->config = $array;
}
public function __get($name) {
if(is_array($this->config[$name])) {
return new ConfigArray($this->config[$name]);
} else {
return $this->config[$name];
}
}
}
这将允许我链接我的配置访问。由于我使用的是 PHP 5.3,因此让 ConfigArray 扩展 ArrayObject 可能也是一个好主意(SPL 在 5.3 中默认激活)。
有什么建议、改进、cmets?
【问题讨论】:
-
如果你真的想将
[]换成->,我会选择一个裸ArrayObject,但是我并没有那么费心去改变它。每次请求时创建一个 new 对象会很麻烦,我会递归遍历数组并将数组修改为 arrayobjects 一次。 -
@Wrikken:没错,会在实际实现中改变这种行为。
标签: php multidimensional-array php-5.3