Использование массива $config в классах MVC

Я довольно много читал об этом, и многие люди говорят, что мне следует использовать одноэлементный класс. Я думал о написании класса «Config», который включал бы файл «config.php» в __construct и перебирал значения массива $config и помещал их в значения $this->...

Но потом я все больше и больше читал о том, что синглтоны никогда не следует использовать. Итак, мой вопрос: каков наилучший подход для этого? Я хочу иметь файл конфигурации для организационных целей, который содержит все мои переменные $config. Я не хочу жестко кодировать такие вещи, как имена пользователей и пароли базы данных, непосредственно в методы для обеспечения гибкости и многого другого.

Например, я использую следующий код в проекте MVC, над которым работаю:

public/index.php

<?php

include '../app/bootstrap.php';

?>

приложение/bootstrap.php

<?php

session_start();

function __autoload ($class) {  
    $file = '../app/'.str_replace('_', '/', strtolower($class)).'.php';

    if (file_exists($file)) {
        include $file;
    }
    else {
        die($file.' not found');
    }
}

$router = new lib_router();

?>

приложение/lib/router.php

<?php

class lib_router {

    private $controller = 'controller_home'; // default controller
    private $method = 'index'; // default method
    private $params = array();

    public function __construct () {
        $this->getUrl()->route();
    }

    private function getUrl () {
        if (isset($_GET['url'])) {
            $url = trim($_GET['url'], '/');
            $url = filter_var($url, FILTER_SANITIZE_URL);
            $url = explode('/', $url);      

            $this->controller = isset($url[0]) ? 'controller_'.ucwords($url[0]) : $this->controller;
            $this->method = isset($url[1]) ? $url[1] : $this->method;

            unset($url[0], $url[1]);

            $this->params = array_values($url);
        }

        return $this;
    }

    public function route () {
        if (class_exists($this->controller)) {
            if (method_exists($this->controller, $this->method)) {
                call_user_func(array(new $this->controller, $this->method), $this->params);
            }
            else {
                die('Method '.$this->method.' does not exist');             
            }
        }
        else {          
            die('Class '.$this->controller.' does not exist');
        }
    }

}

?>

Теперь предположим, что я посещаю http://localhost/myproject/lead/test

Он будет вызывать класс controller_lead и внутри него метод test.

Вот код для app/controller/lead

<?php

class controller_lead extends controller_base {

    public function test ($params) {        
        echo "lead test works!";
    }

}

?>

приложение/контроллер/база

<?php

class controller_base {

    private $db;
    private $model;

    public function __construct () {
        $this->connect()->getModel();
    }

    private function connect () {
        //$this->db = new PDO($config['db_type'] . ':host=' . $config['db_host'] . ';dbname=' . $config['db_name']. ', $config['db_user'], $config['db_pass'], $options);
        return $this;
    }

    private function getModel () {
        $model = str_replace('controller', 'model', get_class($this));
        $this->model = new $model($this->db);
    }

}

?>

Здесь я столкнулся с проблемой. Как видите, метод connect попытается создать новый объект PDO. Теперь, как мне внедрить эту переменную $config, учитывая весь остальной код, который я только что предоставил?

Мои варианты выглядят так:

  • Использовать синглтон (плохо)
  • Используйте глобальный (хуже)
  • Включите config.php в bootstrap.php и внедрите его в несколько классов (зачем мне внедрять это в мой класс lib_router, если lib_router не имеет абсолютно никакого отношения к базе данных? Это звучит как ужасная практика.)

Какой еще вариант у меня есть? Я не хочу делать ни одну из этих трех вещей...

Любая помощь будет принята с благодарностью.


person inkd    schedule 16.04.2015    source источник
comment
частный $ дб; следует ввести через общедоступную функцию __construct ($ db) в controller_base, а затем пойти и посмотреть, как лучше создается PDO (возможно, lazyload , в bootstrap.php).   -  person s.d.a.p.e    schedule 17.04.2015
comment
или попробуйте это, чтобы включить MVC github.com/AnthonyWlodarski/ Design-Pattern-Examples/blob/master/   -  person s.d.a.p.e    schedule 17.04.2015
comment
Это синглтон. Спасибо за ваши комментарии, но мой первоначальный вопрос остается в силе. Кроме того, внедрение $db в controller_base требует, чтобы я сначала внедрил его в lib_router, а, как я уже упоминал, lib_router не имеет абсолютно никакого отношения к базе данных. Его единственная цель — направить пользователя к соответствующему контроллеру на основе запрашиваемого URL-адреса.   -  person inkd    schedule 17.04.2015
comment
$c=Registry::get('config'); $this-›db = newPDO($c[0],$c[1]); В любом случае вы перепутаете эти 3 вещи... Вопросы: Сколько раз вы меняете $config и когда вы создаете новые экземпляры PDO?   -  person s.d.a.p.e    schedule 17.04.2015


Ответы (2)


В итоге я включил файл конфигурации в свой бутстрап, который просто содержал константы, и использовал константы.

person inkd    schedule 17.04.2015
comment
Звучание просто прекрасное, в этом много плюсов. - person sitilge; 20.04.2015

В итоге я включил файл конфигурации в свой бутстрап, который просто содержал константы, и использовал константы.

У меня было то же самое - требовался файл в Model. Подход, основанный на файлах, был наиболее подходящим, поскольку он имеет некоторые преимущества: вы можете .gitignore установить собственный набор разрешений, все ваши параметры хранятся централизованно и т. д.

Однако, если файл конфигурации содержит только параметры подключения к БД, я предпочитаю требовать файл конфигурации только в Model. Возможно, вы также могли бы разбить на несколько более конкретных файлов конфигурации и потребовать их при необходимости.

public function __construct()
{
    if (self::$handle === FALSE)
    {
        $db = array();

        require APP_DIR.DIR_SEP.'system'.DIR_SEP.'config'.DIR_SEP.'Database.php';

        if (!empty($db))
        {
            $this->connect($db['db_host'], $db['db_user'], $db['db_password'], $db['db_name']);
        }
        else
        {
            Error::throw_error('Abimo Model : No database config found');
        }
    }
}
person sitilge    schedule 20.04.2015