【问题标题】:Best solution for "Array chaining"“数组链接”的最佳解决方案
【发布时间】: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()-&gt;General 访问数组的第一级,使用Config::getInstance()-&gt;General['user'] 访问值。我真正想要的是能够通过执行Config::getInstance()-&gt;General-&gt;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?

【问题讨论】:

  • 如果你真的想将[] 换成-&gt;,我会选择一个裸ArrayObject,但是我并没有那么费心去改变它。每次请求时创建一个 new 对象会很麻烦,我会递归遍历数组并将数组修改为 arrayobjects 一次。
  • @Wrikken:没错,会在实际实现中改变这种行为。

标签: php multidimensional-array php-5.3


【解决方案1】:

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

$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; });

很棒吧? 更多信息请访问this blog。

【讨论】:

    【解决方案2】:

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

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

    Zend_Registry 类有类似的用法,它确实扩展了ArrayObject。因此,Zend_Registry 的代码稍微简单一些。

    【讨论】:

    • 查看 Zend_Config::__construct:他们使用new self($value, ..) 来获得更深的数组维度。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-12
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 2014-09-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多