“数组链接”的最佳解决方案
对于我的项目,我编写了一个小型配置类,它从 .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 中默认激活)。
有什么建议、改进、意见吗?
For my project I wrote a small config class that loads its data from a .ini file. It overwrites the magic __get() method in order to provide simplified access to the (read only) config values.
Example config.ini.php:
;<?php exit; ?>
[General]
auth = 1
user = "halfdan"
[Database]
host = "127.0.0.1"
My config class (singleton pattern - simplified here) looks like this:
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];
}
}
Loading the config would create an array structure like this:
array(
"General" => array(
"auth" => 1,
"user" => "halfdan"
),
"Database" => array(
"host" => "127.0.0.1"
)
)
It's possible to access the first level of the array by doing Config::getInstance()->General
, and the values using Config::getInstance()->General['user']
. What I really want though is being able to access all configuration variables by doing Config::getInstance()->General->user
(syntactic sugar). The array is not an object and the "->" isn't defined on it, so this simply fails.
I thought of a solution and would like to get some public opinion about it:
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];
}
}
}
This would allow me to chain my configuration access. As I'm using PHP 5.3 it might also be a good idea to let ConfigArray extend ArrayObject (SPL is activated per default in 5.3).
Any suggestions, improvements, comments?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果
$this->config
数组的元素也是Config
类的实例,那么它就可以工作。Zend Framework 有一个类似的组件,他们称之为 Zend_Config。您可以下载源代码并检查他们是如何实现它的。他们不必一路去扩展
ArrayObject
。Zend_Registry 类具有类似的用法,并且它确实扩展了
数组对象
。因此,Zend_Registry 的代码稍微简单一些。If the elements of your
$this->config
array are also instances of yourConfig
class, then it works.The Zend Framework has a similar component they call Zend_Config. You can download the source and examine how they implemented it. They didn't have to go all the way to extending
ArrayObject
.The Zend_Registry class has similar usage and it does extend
ArrayObject
. The code for Zend_Registry is somewhat simpler as a result.如果你想在 PHP 中使用数组链接,你真的应该看看 Chain。这是一个非常小的项目,您可以像编写 Java 代码一样使用
filter
和count
等链接方法!变得
很棒吧?
您可以在此博客上找到更多信息。
If you want array chaining in PHP, you should really take a look into Chain. It's a really small project were you can use chaining methods like
filter
andcount
like you are coding Java!becomes
Awesome right?
More info you can find on this blog.