“数组链接”的最佳解决方案

发布于 2024-09-19 00:31:33 字数 1799 浏览 4 评论 0原文

对于我的项目,我编写了一个小型配置类,它从 .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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

还不是爱你 2024-09-26 00:31:33

如果 $this->config 数组的元素也是 Config 类的实例,那么它就可以工作。

Zend Framework 有一个类似的组件,他们称之为 Zend_Config。您可以下载源代码并检查他们是如何实现它的。他们不必一路去扩展ArrayObject

Zend_Registry 类具有类似的用法,并且它确实扩展了 数组对象。因此,Zend_Registry 的代码稍微简单一些。

If the elements of your $this->config array are also instances of your Config 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.

清旖 2024-09-26 00:31:33

如果你想在 PHP 中使用数组链接,你真的应该看看 Chain。这是一个非常小的项目,您可以像编写 Java 代码一样使用 filtercount 等链接方法!

$arr = array_filter(
    array_map(
        function ($v) { return rand(0, $v); },
        array_fill(0, 10, 20)
    ),
    function ($v) { return $v & 1; }
);

变得

$chain = Chain::fill(0, 10, 20)
    ->map(function ($v) { return rand(0, $v); })
    ->filter(function ($v) { return $v & 1; });

很棒吧?
您可以在此博客上找到更多信息。

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 and count like you are coding Java!

$arr = array_filter(
    array_map(
        function ($v) { return rand(0, $v); },
        array_fill(0, 10, 20)
    ),
    function ($v) { return $v & 1; }
);

becomes

$chain = Chain::fill(0, 10, 20)
    ->map(function ($v) { return rand(0, $v); })
    ->filter(function ($v) { return $v & 1; });

Awesome right?
More info you can find on this blog.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文