PHP:构建IF子句的最有效方法

时间:2015-06-09 17:38:56

标签: php if-statement

我正在研究使用“不要重复自己”的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变量?

5 个答案:

答案 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();
}