假设您有这样的计划:
$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程序以避免像这样的范围问题的最佳实践是什么?您没有看到要求您在现代代码中传递“全局”对象的函数。如何避免不必要的函数参数?
答案 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'对象是一个实际对象(如在类的实例化中),那么你只需要为它提供一个返回必要数据的静态函数。所述功能可以从任何地方访问,包括你的身份验证功能。