PHP脚本结构和范围,以避免不必要的函数参数

时间:2011-10-06 14:50:13

标签: php

假设您有这样的计划:

$info = array(
    'username'=>'jeff',
    'password'=>'kay'
);

function authenticate($user, $pass) {
    if($user == $info['username'] && $pass == $info['password']) {
        return true;
    }
    return false;
}

此代码无效,因为$info数组不在authenticate()的范围内。您必须将$info作为authenticate()的参数传递,如下所示:

function authenticate($info, $user, $pass) { // ... }

这对我来说不合适。

我当然可以在global $info;内添加authenticate,但感觉更加错误。构建PHP程序以避免像这样的范围问题的最佳实践是什么?您没有看到要求您在现代代码中传递“全局”对象的函数。如何避免不必要的函数参数?

6 个答案:

答案 0 :(得分:2)

大多数人都没有注意到,但这实际上是一个非常好的问题。

许多其他语言(特别是功能语言)具有词汇范围。使用PHP 5.3 lambdas,您可以获得该功能,但仅限于lambdas。让我告诉你我的意思:

$info = array(
    'username'=>'jeff',
    'password'=>'kay'
);

$authenticate = function ($user, $pass) use ($info) {
    if ($user == $info['username'] && $pass == $info['password']) {
        return true;
    }
    return false;
}

if ($authenticate($_POST['username'], $_POST['password'])) {
    // use authenticated
}

使用use,您可以从外部作用域导入变量,但它仅适用于匿名函数。这实际上取决于你在/用什么样的风格和框架。

如果你不想定义这些内联(因为你必须将它们分配给变量,这不是那么好),我建议你选择你的直觉,所以将$info传递给{{1或者使authenticate成为$info所属类的实例变量。

答案 1 :(得分:0)

在这种情况下,只是不使用功能会更好。例如,您将拥有:

if( authenticate($user, $pass, $info))

尝试:

if( Array("username"=>$user,"password"=>$pass) == $info)

然而,作为更一般的事情,我更喜欢在需要时传递函数参数。我也喜欢使用关联数组,就像你有$info一样,尽可能在很少的参数中包含大量数据。

答案 2 :(得分:0)

因此,在将变量注入范围的两种可能方式中,您都感觉不对劲?这毫无意义。

构建内容的最佳方法是什么?最简单的一个 - 如果你知道需要的参数数量以及你需要什么类型的参数 - 将这些参数发送给函数。

你的示例代码没问题,它没有任何问题(当然保存,$ info没有通过)。

不要重新发明热水。

答案 3 :(得分:0)

通常,登录信息不会硬编码到这样的脚本中,因此这是一个相当难以扩展的示例。

如果您将信息存储在数据库或文件中,那么您只需在函数中引用该数据存储,就不需要像这样的全局变量。


如果你这样做死了,你可以这样做:

function authenticate($user, $pass) {
    if(checkUser($user, $pass)) {
        // I am assuming you'll do more here than just return true   
        return true;
    }
    else {
        return false;
    }
}

function checkUser($user, $pass) {
    $info = array(
        'username'=>'jeff',
        'password'=>'kay'
    );

    if($user == $info['username'] && $pass == $info['password']){
        return true;
    }
    else {
        return false;
    }
}

这样,如果您决定更改数据存储或检查用户代码,只要它返回正确的布尔值进行身份验证,您就可以了。 Hurray抽象!

答案 4 :(得分:0)

这实际上取决于数据的确切来源。

鉴于以上例子:

  • 如果您的数据存储在数据库中,请从函数范围内检索数据库中的数据,而不是将其存储在内存中。
  • 如果数据存储在硬编码数组中,则应该在另一个文件中。然后你可以在函数中include()放置该文件,$info将在函数范围内。
  • 如果您的数据是硬编码数组,由于某些奇怪的原因必须存储在主文件中,它需要在函数中定义,或者您必须将其作为参数传递,或者明确地将数据提取到函数的范围内(使用global$GLOBALS等)。

我会说(你自己)应该问的真正问题是:

“我如何优化存储和检索数据的方式以避免存在范围问题?”

答案 5 :(得分:0)

编辑回复评论:

假设'global'对象是一个实际对象(如在类的实例化中),那么你只需要为它提供一个返回必要数据的静态函数。所述功能可以从任何地方访问,包括你的身份验证功能。