我正在研究使用“不要重复自己”的DRY原则构建if
条款的方法。
这是涉及大约15年的脚本以及用全局等编写得不好的脚本的工作,我被要求将这个脚本/站点拖到21世纪 - 但由于时间和成本的限制,我可以虽然我知道远更好,但不能从头开始重写完整的网站。
我有一个以前是全球价值的价值,我不知道它来自哪里,它可能来自不同页面的不同地方。
我有一些活动正在检查$_POST
或$_GET
数据中的输入值,如果输入值为空(或无效),则检查该值是否实际上位于{ {1}}。如果输入值仍然为空(或无效),则启动到另一页。
我的代码:
$_SESSION
我重复两次$userId = $_REQUEST['userid'];
if (empty($userId)) {
$userId = $_SESSION['userid'];
}
if(empty($userId) || !is_numeric($userId))
{
header("Location:contactdetails.php");
die();
}
函数,我可以将两个IF包装成一行但是需要一个IF来传递empty()
或REQUEST
中的值进入SESSION
变量。
是否有(更好的)方法可以检查两个可能的输入,以查看此[以前全球]' ['用户ID']'变量来自并将该值应用于页面本地$userId
变量?
答案 0 :(得分:3)
您可以使用ternary operator。如果计算结果为true,则使用第一个表达式,否则使用后者。在这种情况下,$userId = $_REQUEST['userid'] ?: $_SESSION['userid'];
if (empty($userId) || !is_numeric($userId)) {
header("Location:contactdetails.php");
exit;
}
超全局优先,如问题中的代码:
0
然而正如Havenard在上面的评论中所说,盲目信任请求数据可能是一个安全问题。
另请注意,如果任何用户ID为null
,则条件为真,在这种情况下,$userId = $_REQUEST['userid'] ?: $_SESSION['userid'];
if ($userId === null || !is_numeric($userId)) {
header("Location:contactdetails.php");
exit;
}
检查会更好:
$_SESSION
当然,假设您没有将{{1}}中的假值存储为非空值。
答案 1 :(得分:3)
如果保证设置$_SESSION['userid']
,rink.attendant.6's answer似乎是一种干净的方法。否则,您必须对$_REQUEST
和$_SESSION
执行必要的检查,以确保$userId
设置正确:
if (isset($_REQUEST['userid']) && is_numeric($_REQUEST['userid']))
$userId = $_REQUEST['userid'];
else if (isset($_SESSION['userid']) && is_numeric($_SESSION['userid']))
$userId = $_SESSION['userid'];
else // no acceptable value for $userId in sight
{
header("Location: contactdetails.php");
exit;
}
您可能还想重新考虑使用is_numeric()
,因为它会以true
的形式验证任何格式的数字表示形式,而不仅仅是您可能期望的正整数。
答案 2 :(得分:2)
您在这里解决了两个不同的问题。首先是默认的问题,其次是过滤。依次拿走每一个。
对于默认,你可以实现一个简单的" get from数组,如果它存在,否则默认"助手:
function array_get(array $a, $key, $default = null) {
return (array_key_exists($key, $a) ? $a[$key] : $default);
}
然后,您可以使用此帮助程序提供默认链接:
$userId = array_get($_REQUEST, 'userid', $_SESSION['userid']);
对于过滤,您从该链中知道您从两个阵列中的一个获得了null或值。既然您正在寻找表面上的数据库ID,我喜欢这样的函数:
function is_id_like($it) {
$rc = filter_var($it, FILTER_VALIDATE_INT, array ('options' => array (
'default' => false, 'min_range' => 1,
)));
return (false === $rc ? false : true);
}
这可以确保您提供的数字看起来像一个int,为1或更高,如果没有,则返回false
。所有这些都通过了:1
,"1"
和"1.0"
,但这些都失败了:0
和"1.1"
。
组合这些,并允许会话没有用户ID:
$userId = array_get($_REQUEST, 'userid', array_get($_SESSION, 'userid'));
if (! is_id_like($userId)) {
header('Location: contactdetails.php');
die();
}
支票总数已更改为一个array_key_exists
和一个filter_var
,但代码更具可读性,这些方法可在整个代码库中重复使用。
答案 3 :(得分:0)
如果只在请求或会话中设置该值,则连接可能的值并验证一次。
答案 4 :(得分:-2)
你应该对双向语句使用if-else,并为n-way语句使用switch。
swicth($myVar){
case 1: doX();break;
case 'a': doY();break;
case 2: doZ();break;
default: doA();
}