Должен ли я хранить суперглобальные переменные как свойство класса-обертки или я должен получить к нему прямой доступ? - PullRequest
3 голосов
/ 26 апреля 2011

Я хотел создать оболочку для Session и Request, чтобы у меня не было доступа к суперглобалам PHP напрямую.Я понял, что если я создаю оболочку для суперглобалей и использую их, модульное тестирование моего приложения будет проще, поскольку класс оболочки может быть смоделирован.

Пытаясь создать класс оболочки, я исследовал некоторые примеры классов оболочки.,Некоторые из них хранят суперглобальный элемент как свойство класса при инициализации:

class Session
{
    protected $vars;

    public function __construct()
    {
        session_start();

        // POINT OF INTEREST
        // Store the superglobal as a class property
        $this->vars = $_SESSION;
    }    

    public function get($index)
    {
        // POINT OF INTEREST
        // Accesses the class property instead of the superglobal
        return $this->vars[$index];
    }

    public function write($index, $value)
    {
        // Writes both class property and session variable
        $this->vars[$index] = $value;
        $_SESSION[$index] = $value;
    }
}

Мой вопрос: есть ли какая-то особая причина, по которой при создании класса-оболочки мы сохраняем суперглобальный элемент как свойство класса вместо прямого доступа к ним??Сравните приведенный выше код с этим:

class Session
{
    public function __construct()
    {
        session_start();
    }

    public function get($index)
    {
        // Accesses the superglobal directly
        return $_SESSION[$index];
    }

    public function write($index, $value)
    {
        // Accesses the superglobal directly
        $_SESSION[$index] = $value;
    }
}

IMO, так как класс-оболочка все равно будет подвергнут ложной проверке, зачем беспокоиться о сохранении суперглобальных переменных как свойства класса?Есть ли конкретная причина, почему так много людей делают это?Стоит ли хранить суперглобальные переменные как свойство в их оболочке вместо прямого доступа к нему?

Спасибо за любой ввод.

Ответы [ 2 ]

5 голосов
/ 27 апреля 2011

Сессия - довольно специфический случай.Но вы спросили, есть ли какая-либо причина, чтобы обернуть суперглобальные.Вот несколько возможных причин (не по порядку и не по полному):

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

  2. Чтобы сделать код более гибким, так как тогда вы можете подделать запросы и подзапросы для выполненияинтересные вещи, которые были бы невозможны при истинном глобальном состоянии.

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

  4. Для применения дополнительных ограничений на переменную.Поскольку $ _SESSION позволяет вам устанавливать внутри себя все, что вы хотите, вы можете получить несериализуемое состояние, которое может вызвать проблемы.С оболочкой у вас есть одна централизованная точка, где вы можете проверить состояние, чтобы определить, соответствует ли оно необходимым ограничениям.

  5. Чтобы сделать ваш код более читабельным.Конечно, почти каждый разработчик php знает, что вы делаете, если у вас есть доступ к $ _POST в методе.Но они должны знать об этой детали реализации?Или $request->getFromPostData('foo'); более многословно?

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

  7. Чтобы облегчить понимание зависимостей вашего класса.Если бы я дал вам API для класса, который использовал суперглобальные переменные, вы не можете сказать, обращался ли этот класс к нему, и, следовательно, точно, что класс должен работать.Но если вам требуется, чтобы класс запроса был внедрен, вы могли бы сразу заметить, что классу действительно нужно что-то из запроса для работы.Таким образом, улучшается читабельность и уточняется ваш API.

В действительности есть и другие причины, но это те, которые я могу придумать не по себе.

3 голосов
/ 27 апреля 2011

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

С этой точки зрения я считаю не очень разумным метод write первой предоставленной вами реализации, который записывает как свойство класса, так и переменную сеанса, как вы отметили.

Однако все это кажется немного излишним (и переосмысленным). Просто будьте просты и делайте то, что вам полезно.

...