如OP所述:
PHP将所有数组都视为关联数组
恕我直言,写一个函数来检查数组是否关联是不太明智的。首先,PHP数组中的键是什么?:
键可以是整数,也可以是字符串。
这意味着有三种可能的情况:
案例1。所有键都是数字/整数。
例2。所有键都是字符串。
例3。有些键是字符串,有些键是数字/整数。
我们可以用下面的函数检查每种情况。
情况1:所有键都是数字/整数。
注意:该函数对于空数组也返回true。
//! Check whether the input is an array whose keys are all integers.
/*!
\param[in] $InputArray (array) Input array.
\return (bool) \b true iff the input is an array whose keys are all integers.
*/
function IsArrayAllKeyInt($InputArray)
{
if(!is_array($InputArray))
{
return false;
}
if(count($InputArray) <= 0)
{
return true;
}
return array_unique(array_map("is_int", array_keys($InputArray))) === array(true);
}
情况2:所有键都是字符串。
注意:该函数对于空数组也返回true。
//! Check whether the input is an array whose keys are all strings.
/*!
\param[in] $InputArray (array) Input array.
\return (bool) \b true iff the input is an array whose keys are all strings.
*/
function IsArrayAllKeyString($InputArray)
{
if(!is_array($InputArray))
{
return false;
}
if(count($InputArray) <= 0)
{
return true;
}
return array_unique(array_map("is_string", array_keys($InputArray))) === array(true);
}
例3。有些键是字符串,有些键是数字/整数。
注意:该函数对于空数组也返回true。
//! Check whether the input is an array with at least one key being an integer and at least one key being a string.
/*!
\param[in] $InputArray (array) Input array.
\return (bool) \b true iff the input is an array with at least one key being an integer and at least one key being a string.
*/
function IsArraySomeKeyIntAndSomeKeyString($InputArray)
{
if(!is_array($InputArray))
{
return false;
}
if(count($InputArray) <= 0)
{
return true;
}
return count(array_unique(array_map("is_string", array_keys($InputArray)))) >= 2;
}
由此可见:
如果值不是数组,3个函数都返回false。
如果值为空数组,所有3个函数都返回true
(根据定义,“空集合是任何集合a的子集,因为它的所有元素都属于a”)。
如果值是非空数组,则只有一个函数返回true。
现在,一个数组要成为我们都习惯的“真正的”数组,这意味着:
它的键都是数字/整数。
它的键是顺序的(即按步骤1递增)。
它的键从零开始。
我们可以用下面的函数来检查。
例3。键包括数字/整数、顺序和从零开始。
注意:该函数对于空数组也返回true。
//! Check whether the input is an array whose keys are numeric, sequential, and zero-based.
/*!
\param[in] $InputArray (array) Input array.
\return (bool) \b true iff the input is an array whose keys are numeric, sequential, and zero-based.
*/
function IsArrayKeyNumericSequentialZeroBased($InputArray)
{
if(!is_array($InputArray))
{
return false;
}
if(count($InputArray) <= 0)
{
return true;
}
return array_keys($InputArray) === range(0, count($InputArray) - 1);
}
注意事项/陷阱(或者,PHP中关于数组键的更奇怪的事实)
整数键
这些数组的键都是整数:
array(0 => "b");
array(13 => "b");
array(-13 => "b"); // Negative integers are also integers.
array(0x1A => "b"); // Hexadecimal notation.
字符串键
这些数组的键都是字符串:
array("fish and chips" => "b");
array("" => "b"); // An empty string is also a string.
array("stackoverflow_email@example.com" => "b"); // Strings may contain non-alphanumeric characters.
array("stack\t\"over\"\r\nflow's cool" => "b"); // Strings may contain special characters.
array('$tα€k↔øv∈rflöw⛄' => "b"); // Strings may contain all kinds of symbols.
array("functіon" => "b"); // You think this looks fine? Think again! (see https://stackoverflow.com/q/9246051/1402846)
array("ま말轉转ДŁ" => "b"); // How about Japanese/Korean/Chinese/Russian/Polish?
array("fi\x0sh" => "b"); // Strings may contain null characters.
array(file_get_contents("https://www.google.com/images/nav_logo114.png") => "b"); // Strings may even be binary!
看起来像字符串的整数键
如果你认为数组中的键("13" => "b")是一个字符串,那你就错了。医生说:
包含有效整数的字符串将被转换为整数类型。例如,键“8”实际上存储在8下面。另一方面,"08"不会被强制转换,因为它不是一个有效的十进制整数。
例如,这些数组的键都是整数:
array("13" => "b");
array("-13" => "b"); // Negative, ok.
但是这些数组的键都是字符串:
array("13." => "b");
array("+13" => "b"); // Positive, not ok.
array("-013" => "b");
array("0x1A" => "b"); // Not converted to integers even though it's a valid hexadecimal number.
array("013" => "b"); // Not converted to integers even though it's a valid octal number.
array("18446744073709551616" => "b"); // Not converted to integers as it can't fit into a 64-bit integer.
而且,据医生说,
整数的大小取决于平台,尽管通常的最大值约为20亿(有32位符号)。64位平台通常有大约9E18的最大值,除了Windows,它总是32位。PHP不支持无符号整数。
所以这个数组的键可能是整数,也可能不是整数——这取决于你的平台。
array("60000000000" => "b"); // Array key could be integer or string, it can fit into a 64-bit (but not 32-bit) integer.
更糟糕的是,如果整数接近231 = 2,147,483,648边界(参见bug 51430, bug 52899), PHP就容易出现bug。例如,在我的本地环境(PHP 5.3.8 on XAMPP 1.7.7 on Windows 7)中,var_dump(array("2147483647" => "b")给出
array(1) {
[2147483647]=>
string(1) "b"
}
但是在codepad (PHP 5.2.5)上的这个现场演示中,相同的表达式给出
array(1) {
["2147483647"]=>
string(1) "b"
}
因此,密钥在一个环境中是整数,而在另一个环境中是字符串,即使2147483647是一个有效的有符号32位整数。