Считаете ли вы плохой формой в PHP доступ к суперглобальным переменным внутри методов класса? - PullRequest
3 голосов
/ 13 апреля 2009

Возьмем пример функции login() в пределах class Account.

class Account {
 /* Class variables */

    public function login() {
        if(isset($_POST['username']) && isset($_POST['password']))
            return $this->_formLogin();
        else if(isset($_SESSION['accountId']))
            return $this->_sessionLogin();
        else if(isset($_COOKIE['username']) && isset($_COOKIE['password']))
            return $this->_cookieLogin();
        else return false;
    }

    private function _formLogin() {
        //perform login actions using $_POST data
    }
    /* All that other stuff */
}

Постарайтесь на этот момент игнорировать любые опасения по поводу невидимых методов очистки данных, посылки паролей и тому подобного. Концентрируясь строго на login(), это глобальный доступ - это плохо? Я не использую PHP суперглобальные переменные внутри классов, но не могу придумать вескую причину не делать этого в этой ситуации.

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

Это приведет к тому, что в начале страницы вам понадобится войти в систему:

$user = new Account($whatever, $objects, $we, $depend, $on);
if($user->login()) {
    //Do this stuff when logged in
}

вместо этого на каждой странице, логику которой, возможно, придется изменить позже:

$user = new Account($whatever, $objects, $we, $depend, $on);
if(isset($_POST['username']) && isset($_POST['password']))
    $user->formLogin($_POST['username'], $_POST['password']);
else if(isset($_SESSION['accountId']))
    $user->sessionLogin($_SESSION['accountId']);
else if(isset($_COOKIE['username']) && isset($_COOKIE['password']))
    $user->cookieLogin($_COOKIE['username'], $_COOKIE['password']);
if($user->isLoggedIn() {
    //Do this stuff when logged in
}

И хотя я знаю, что создание функции вне класса для обработки этого параметра, не будет ли это так же плохо, как запутывание глобалов в классе?

Ответы [ 4 ]

7 голосов
/ 13 апреля 2009

Я бы не сказал, что есть прямой ответ «да» или «нет» на этот вопрос. Идея (со всеми суперглобалами $_GET $_POST $_SESSION) заключается в том, что вы запрашиваете данные, которые содержатся во всем приложении, а не локально по отношению к области, которую вы запрашиваете.

Что может случиться с этими суперглобалами, так это то, что если они изменятся где-то по какой-либо причине непосредственно перед (или не дай бог) во время выполнения вашей функции. Это может оказаться очень раздражающей ошибкой для воспроизведения.

Так что я бы сказал, что это дурной тон.

7 голосов
/ 13 апреля 2009

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

Однако вы никогда не должны изменять глобальное поле внутри класса и обращаться к нему где-либо еще. Тогда вы делаете невозможным юнит-тестирование.

2 голосов
/ 13 апреля 2009

Один из подходов - объединить все суперглобальные классы в свой собственный класс. Я уверен, что Zend Framework имеет собственный класс, например манипулирование Cookies.

0 голосов
/ 13 апреля 2009

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

...