Устранение необходимости глобального ключевого слова в PHP - PullRequest
0 голосов
/ 24 ноября 2011

Я делаю простое PHP-приложение с дизайном MVC.Все запросы отправляются на index.php и затем направляются на соответствующий контроллер.Поскольку все запросы проходят через index.php, я хочу создать там некоторые объекты и иметь возможность использовать их глобально, независимо от того, какой контроллер обрабатывает запрос.А именно, эти объекты имеют тип User, ErrorHandler и Database.

Наличие глобального класса User, например, позволяет любому контроллеру проверять, вошел ли пользователь в систему, проверяя$user->loggedIn (или что-то подобное), где $user создается в index.php.

Вот что я описываю в коде:

// index.php:

<?php
    include('lib/User.php');

    $user = new User();

    // other stuff that index.php needs to do, perhaps route to FooController
?>

// FooController.php:

<?php
    class FooController {
        function __construct() {
            global $user;        

            if ($user->loggedIn) {
                // do whatever
            }
        }
    }
?>

Это просто случайный кодпросто набрал, поэтому прошу прощения за любые глупые ошибки - но я надеюсь, вы поняли идею.Этот код будет работать, но строка global $user; должна быть включена в каждую функцию внутри FooController.php.

Это будет раздражать, когда каждая функция должна иметь три оператора global, один для User, ErrorHandler и Database.Есть ли лучший способ сделать это, сохранив мой дизайн MVC?

Ответы [ 2 ]

2 голосов
/ 24 ноября 2011

Вам вряд ли когда-нибудь понадобится global.Просто не создавайте глобалы.

Первый.Есть такая вещь, как параметры, например:

function __construct($user)
{ ... }

Теперь вы можете позвонить:

$controller = new MyController($user);

.. и вам не нужен «глобальный».

Еще лучше, если ваш контроллер - это контроллер, который управляет потоком всего вашего приложения.В этом случае вам нужно будет передать ему только несколько классов, например, класс базы данных и, возможно, анализатор для ввода.Если вас это не волнует, вы можете заставить контроллер создавать экземпляр класса базы данных и сам синтаксический анализатор.Вы всегда можете выполнить рефакторинг этой части, если вам нужно поддерживать несколько типов баз данных и несколько видов ввода.

Затем эти базы данных можно установить как свойство контроллера.Каждый следующий класс будет знать об этом контроллере.Вы можете установить экземпляр контроллера в глобальном или, что еще лучше, передать его в конструктор других классов, чтобы они вообще не зависели от глобальных.

Если этим классам не нужен контроллер,но просто нужна база данных, вы можете передать только класс базы данных.Это сделает эти классы еще более независимыми от контроллера и от любых глобальных переменных, так что вы сможете очень легко использовать их в других приложениях при условии, что сама база данных не зависит (прямо или косвенно) от контроллера.

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

1 голос
/ 12 декабря 2011

В итоге я сделал это:

class BaseController
{
    public $user, $db, $errors;

    function __construct()
    {
         global $user, $db, $errors;

         $this->user = $user;
         $this->db = $db;
         $this->errors = $errors;
    }
}

Каждый контроллер расширяет BaseController (который также имеет некоторые абстрактные функции, это всего лишь пример BaseController, который решает эту конкретную проблему).Таким образом, мне нужно было использовать global только один раз, а затем я мог использовать экземпляры user, db и error handler на каждом контроллере, просто вызывая parent::__construct() в конструкторе каждого контроллера, а затем ссылаясь на них с помощью $this->user и т. Д.

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