PHP - 重构这个if语句以避免重复

3
在这段代码中,我们3次使用了$inputs['user_id']
if (isset($inputs['user_id']) && $inputs['user_id']) { // The consumer is passing a user_id
    doSomethingWith($inputs['user_id']);
}

我可以做什么最易读且最稳健的重构,以避免重复,并避免任何提示索引user_id不存在?

谢谢。

4个回答

4

这里并没有重复的问题。在检查是否设置$inputs ['user_id']之前,您无法将其分配给一个变量,否则这将产生一个Notice undefined index ...

唯一可以做的就是省略isset调用,并改用!empty。像这样:

if(!empty($inputs['user_id'])) {
    doSomething($inputs['user_id']);
}

现在你只需输入两次并检查。
!empty($inputs['user_id'])

等于

isset($inputs['user_id']) && $inputs['user_id']

编辑:基于评论,这里是文档中的一句话引用:

The following things are considered to be empty:

"" (an empty string)
0 (0 as an integer)
0.0 (0 as a float)
"0" (0 as a string)
NULL
FALSE
array() (an empty array)
$var; (a variable declared, but without a value)
因此,无论是empty(0)还是empty('0'),都将返回true。这意味着:
if(!empty('0') || !empty(0)) { echo "SCREW YOU!"; }

将不会输出任何内容... 或者,用礼貌的说法,我会重复上面的声明:

!empty($inputs['user_id']) === (isset($inputs['user_id']) && $inputs['user_id'])

编辑 2:

通过省略isset并替换为!empty,变量仍然会被检查,无论索引是否已设置,请阅读文档,其中写道:

如果变量不存在,则不会生成警告。这意味着empty()实际上相当于!isset($var) || $var == false


2
empty('0') = true,大家应该注意这个事实。 - ComFreek

1
这是什么意思:
// put validation check to the function body
function doSomethingWith($userId) {
     if($userId === -1) {
         // if this is not a valid user id -> return
         return;
     }
     // do something ...
}

// initalize $user with proper default values.
// doing so you can be sure that the index exists
$user = array(
    'id' => -1,
    'name' => '',
    ...
);

// merge inputs with default values:
$user = array_merge($user, $request);

// now you can just pass the value:
doSomethingWith($user['id']);

@AmalMurali 你所说的重构是什么意思? - hek2mgl
这与我即将建议的类似;如果有一个“默认”的无效值,doSomethingWith不能接受(我通常会选择null,而不是-1-1通常最终成为error,因为它是ID的正确数据类型),在开头加上一个保护语句,以便提前返回。 - Izkata
@hek2mgl - 如果变量未定义,您可能希望在参数doSomethingWith(&$userId)之前添加&,以便php不会抱怨。 - i--
@i-- 你能解释一下吗? - hek2mgl
@hek2mgl - 我不确定为什么在函数声明中使用引用传递而不是值传递不会产生警告,我只知道它可以工作。很好奇为什么会这样。猜测可能与变量在这种情况下自动赋值有关。 - i--
显示剩余4条评论

1
以下可能不是每种情况的最佳方式,但肯定可以减少重复。
您的示例代码将转换为:
doSomethingWith($inputs['user_id']);

你的函数应该像这样 (注意通过引用提供的参数,以避免未定义变量警告):

function doSomethingWith(&$userID) {
   if (empty($userID)) return;
   // ... actual code here ...
}

在 PHP 中通过引用传递参数会带来许多(有时是意想不到的)副作用,因此必须小心处理。这就是为什么我不建议将其作为一般解决方案的原因。但在这种情况下,它确实有效,给这个 hack 加 1 分!但在生产代码中我不会使用它... - hek2mgl
1
谢谢。我同意对于代码的小心谨慎,但是如果一个人知道自己在做什么,这也会给语言带来另一种层次的能力。 - i--
这个问题其实也不难解决!:) 当我说“解决这个问题”时,我的意思是,在处理字符串或数字时可能会出现意外的副作用(尤其是性能问题)。但正如你所说,如果小心处理,应该没问题。 - hek2mgl

0
假设0""null不是有效的用户ID:
if ($id = $inputs['user_id']) { 
    doer($id);
}

你也可以使用恶意的@来避免在日志中被注意到(我不喜欢这种方式):

if ($id = @$inputs['user_id']) { 
    doer($id);
}

1
这也假设索引 user_id 总是已设置 - 我从原始问题中的 isset 假设可能并非如此。 - halfer
不会通过检查的是一个空变量,而有效的变量则会。 - Daniele Vrut

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接