您是否认为在 PHP 中访问类方法中的超级全局变量是一种不好的形式?

发布于 2024-07-16 19:03:45 字数 1649 浏览 7 评论 0原文

Account 类 中的 login() 函数为例。

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(),这个全局访问是坏juju吗? 我通常避免在类中使用 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
}

虽然我知道在类之外创建一个函数处理这个问题是一种选择,那不是和在类中混淆全局变量一样糟糕吗?

Take an example login() function within a 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 */
}

Try for this moment to ignore any concerns about unseen methods for data sanitizing, password salting, and such. Concentrating strictly on login(), is this global access bad juju? I avoid using PHP super globals within classes normally, but I can't think of a good reason not to do it in this situation.

I can understand why you wouldn't want magic-in-the-background occuring with globals interacting across classes, but these globals are built into PHP, aren't modified by the class, and are only used by this class.

It would result in this at the beginning of pages you needed a user logged in on:

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

instead of this on every page, the logic of which may need to be changed later:

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

And while I'm aware that creating a function outside of the class to handle that is an option, wouldn't that be just as bad as obfuscating globals in a class?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

梦旅人picnic 2024-07-23 19:03:45

我不会说这个问题有一个直接的是或否的答案。 (所有超全局变量 $_GET $_POST $_SESSION)的想法是,您正在请求位于整个应用程序中的数据,并且不在您要求的范围内。

这些超全局变量可能发生的情况是,如果它们在函数执行之前或(上帝禁止)期间由于某种原因在某个地方发生了变化,该怎么办? 这可能会成为一个非常烦人的错误。

所以我想说这是不好的形式。

I wouldn't say there is a straight yes or no answer to this one. What the idea (with all superglobals $_GET $_POST $_SESSION) is that you are asking for data that sits in your entire application, and not local to the scope you are asking for.

What can happen with these superglobals is that what if they change somewhere for whatever reason just before or (god forbid) during the execution of your function. That can turn out to be a very annoying bug to reproduce.

So I would say it is bad form.

梅倚清风 2024-07-23 19:03:45

为了回答我自己的问题,我会说是的,访问超级全局变量很好,只要您不修改它们以跨多个类访问即可。 后台并没有发生什么魔法——您只是读取状态,而超级全局变量就是 PHP 为您提供的方式。

但是,您永远不应该修改类中的全局变量并在其他地方访问它。 那就是你使单元测试变得不可能的时候。

To answer my own question, I'd say yes, it's fine to access super globals, provided you aren't modifying them to be accessed across multiple classes. There's no magic going on in the background - you're just reading the state, and super globals are how PHP provides that to you.

However, you should never, ever, ever modify a global within a class and access it somewhere else. That's when you make unit testing impossible.

时光与爱终年不遇 2024-07-23 19:03:45

一种方法是将所有超全局变量包装到它自己的类中。 我非常确定 Zend Framework 有一个自己的类,例如用于操作 Cookie。

One approach is to wrap all superglobals into a class of its own. I'm pretty sure Zend Framework has a class of its own for e.g. manipulating Cookies.

剩一世无双 2024-07-23 19:03:45

我想说这取决于您的应用程序的设计。 如果该类是一些通用的、松散耦合的类或模块,并且突然使用此类全局变量,那么在我的书中,这将是不好的做法。 但是,如果该类显然是针对需要这些特定全局变量的特定任务(例如您的登录示例),我没有看到任何明确的反对意见。

I would say it depends on your application's design. If the class is some general, loosly coupled class or module and suddenly it uses such global vars, that would be bad practice in my book. But if the class is clearly geared towards a specific task for which those specific global vars are needed anyway (eg your login example), I don't see any clear objections.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文