Лучшее решение для "Array Chaining" - PullRequest
4 голосов
/ 16 сентября 2010

Для моего проекта я написал небольшой класс конфигурации, который загружает данные из файла .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).

Есть предложения, улучшения, комментарии?

Ответы [ 2 ]

1 голос
/ 16 сентября 2010

Если элементы вашего массива $this->config также являются экземплярами вашего класса Config, то он работает.

В Zend Framework есть аналогичный компонент, который они называют Zend_Config .Вы можете скачать исходный код и изучить, как они его реализовали.Они не должны были пройти весь путь до расширения ArrayObject.

Класс Zend_Registry имеет аналогичное использование и расширяет ArrayObject.В результате код для Zend_Registry несколько проще.

0 голосов
/ 27 февраля 2019

Если вы хотите связать массив в PHP, вам действительно стоит взглянуть на Chain .Это действительно маленький проект, где вы можете использовать методы цепочки, такие как filter и count, как будто вы кодируете Java!

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

Удивительно, верно?Более подробную информацию вы можете найти в этом блоге .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...