isset()的反直觉行为

时间:2011-11-29 03:18:52

标签: php

我将一个变量$ foo传递给一个函数。此输入变量可以是数组或字符串。如果是数组,那么我想设置:

$name = $foo['name']

如果它是一个字符串,那么我想设置:

$name = $foo

为实现这一目标,我编写了以下代码:

$name = isset($foo['name']) ? $foo['name'] : $foo

不幸的是,这不起作用 原因是:当$ foo是一个字符串时,isset($ foo ['name'])返回TRUE。

这种行为令我感到惊讶。我原以为isset($ foo ['name'])返回FALSE,因为没有设置$ foo ['name']。有人可以解释这种看似违反直觉的行为吗?或者当$ foo是一个字符串时,建议在$ foo ['name']上返回FALSE的替代isset()?

更新: 请参阅下面的克里斯托弗的建议:

$name = ( is_array( $foo ) && isset( $foo['name'] ) ) ? $foo['name'] : $foo;

2 个答案:

答案 0 :(得分:4)

set中的isset并不代表“一组项目”,而是“松散地分配给它”。因此,正如您在问题中所说,请改用is_array。如果您意识到在没有isset的情况下可以完成您想要的任务,为什么不这样做

请参阅the documentation for isset

答案 1 :(得分:3)

这应该不足为奇。

为什么当$ foo是一个字符串时它会评估为真:$ foo ['name']与$ foo的零字符相同,当它是一个字符串时 - 因为'name'或'camel'或'cigar '或'任何其他字符串'将被强制转换为该上下文中的整数值。

array_key_exists()可能也不是你想要的,因为如果键设置它将返回true ,即使它具有空值。

in_array()也会很糟糕,因为它会毫无怨言地悄悄地搜索字符串数组。

改为考虑:

 $name = ( is_array( $foo ) && isset( $foo['name'] ) ) ? $foo['name'] : $foo;

请注意,如果键'name'的数组和值为null,或者string和$ foo为null等,则不会考虑计划要执行的操作。这是语言的一个缺点,而是一个特定于你的应用程序的逻辑。