is_array

(PHP 4, PHP 5, PHP 7, PHP 8)

is_array查找变量是否为数组

说明

is_array(混合 $value): 布尔值

查找给定变量是否为数组。

参数

value

要评估的变量。

返回值

如果 value 是一个 数组,则返回 true,否则返回 false

示例

示例 #1 检查变量是否为数组

<?php
$yes
= array('this', 'is', 'an array');

echo
is_array($yes) ? 'Array' : 'not an Array';
echo
"\n";

$no = 'this is a string';

echo
is_array($no) ? 'Array' : 'not an Array';
?>

上面的示例将输出

Array
not an Array

参见

添加注释

用户贡献的注释 19 则注释

Rob Thomas
7 年前
请注意,“强制转换为数组”检查已过时。

在 PHP 5.6 上运行该代码会导致以下结果

is_array : 0.93975400924683
强制转换,=== : 1.2425191402435

因此,请使用“is_array”,而不是可怕的强制转换技巧。
skaimauve at yahoo dot ca
15 年前
或者您可以使用 array_diff_key 和 array_key 函数

<?php

function is_assoc($var)
{
return
is_array($var) && array_diff_key($var,array_keys(array_keys($var)));
}

function
test($var)
{
echo
is_assoc($var) ? "我是一个关联数组。\n" : "我不是一个关联数组。\n";
}

// 一个关联数组
$a = array("a"=>"aaa","b"=>1,"c"=>true);
test($a);

// 一个数组
$b = array_values($a);
test($b);

// 一个对象
$c = (object)$a;
test($c);

// 其他类型
test($a->a);
test($a->b);
test($a->c);

?>

上面的代码输出
我是一个关联数组。
我不是一个关联数组。
我不是一个关联数组。
我不是一个关联数组。
我不是一个关联数组。
我不是一个关联数组。
ari at umbrella dot bz
7 年前
hperrin 的结果在 PHP 7 中确实发生了变化。现在情况相反,is_array 比比较速度更快

is_array : 0.52148389816284
强制转换,=== : 0.84179711341858

测试了 1000000 次迭代。
alex frase
16 年前
另一个更简单、更快的 is_assoc()

<?php
function is_assoc($array) {
foreach (
array_keys($array) as $k => $v) {
if (
$k !== $v)
return
true;
}
return
false;
}
?>

在我的测试中,它运行速度大约是 Michael/Gabriel 的 array_reduce() 方法的两倍。

(说到这个:Gabriel 的版本在编写时不起作用;如果只有第一个键是非数字,或者键是数字但顺序相反,它会将关联数组报告为数字。Michael 通过将 array_reduce() 与 count() 进行比较解决了这个问题,但这会花费另一个函数调用;它也可以与 -1 而不是 0 进行比较,因此将回调中的三元运算符 else 返回为 -1)。
hperrin at gmail dot com
14 年前
我找到了一个更快的确定数组的方法。如果您使用 is_array() 数百万次,您会注意到一个*巨大的*差异。在我的机器上,这种方法大约是使用 is_array() 的时间的 1/4。

将值强制转换为数组,然后检查(使用 ===)它是否与原值相同。

<?php
if ( (array) $unknown !== $unknown ) {
echo
'$unknown 不是数组';
} else {
echo
'$unknown 是数组';
}
?>

您可以使用此脚本测试两种方法的速度。

<pre>
什么方法更快地确定数组?

<?php

$count
= 1000000;

$test = array('im', 'an', 'array');
$test2 = 'im not an array';
$test3 = (object) array('im' => 'not', 'going' => 'to be', 'an' => 'array');
$test4 = 42;
// Set this now so the first for loop doesn't do the extra work.
$i = $start_time = $end_time = 0;

$start_time = microtime(true);
for (
$i = 0; $i < $count; $i++) {
if (!
is_array($test) || is_array($test2) || is_array($test3) || is_array($test4)) {
echo
'error';
break;
}
}
$end_time = microtime(true);
echo
'is_array : '.($end_time - $start_time)."\n";

$start_time = microtime(true);
for (
$i = 0; $i < $count; $i++) {
if (!(array)
$test === $test || (array) $test2 === $test2 || (array) $test3 === $test3 || (array) $test4 === $test4) {
echo
'error';
break;
}
}
$end_time = microtime(true);
echo
'cast, === : '.($end_time - $start_time)."\n";

echo
"\nTested $count iterations."

?>
</pre>

输出结果类似

什么方法更快地确定数组?

is_array : 7.9920151233673
cast, === : 1.8978719711304

测试了 1000000 次迭代。
yousuf at philipz dot com
15 年前
alex frase 的例子很快,但 elanthis at awesomeplay dot com 的例子更快,而 Ilgar 对 alex 代码的修改是有错误的(“ || $_array[$k] !== $v” 部分)。此外,我认为 Ilgar 建议在变量不是数组时返回假值并不适合,我认为在代码运行之前检查数组是否为空也是一个合适的检查。

所以这是修改后的 (is_vector) 版本

<?php
function is_vector( &$array ) {
if ( !
is_array($array) || empty($array) ) {
return -
1;
}
$next = 0;
foreach (
$array as $k => $v ) {
if (
$k !== $next ) return true;
$next++;
}
return
false;
}
?>

以及修改后的 (alex's is_assoc) 版本

<?php
function is_assoc($_array) {
if ( !
is_array($_array) || empty($array) ) {
return -
1;
}
foreach (
array_keys($_array) as $k => $v) {
if (
$k !== $v) {
return
true;
}
}
return
false;
}
?>
jim at akubo dot net
15 年前
yousef 的例子是错误的,因为如果找到键,is_vector 返回 true 而不是 false
以下是修正后的版本(只有两行不同)
<?php
function is_vector( &$array ) {
if ( !
is_array($array) || empty($array) ) {
return -
1;
}
$next = 0;
foreach (
$array as $k => $v ) {
if (
$k !== $next ) return false;
$next++;
}
return
true;
}
?>
angelo [at] mandato <dot> com
17 年前
由“rjg4013 at rit dot edu”发布的 is_associative_array() 和 is_sequential_array() 函数并不准确。

这些函数无法识别非顺序或非有序的索引。例如,array(0=>'a', 2=>'b', 1=>'c') 和 array(0=>'a', 3=>'b', 5=>'c') 将被视为顺序数组。真正的顺序数组应该按连续顺序排列,索引之间没有间隙。

以下解决方案利用了 array_merge 属性。如果只给出一个数组,并且该数组是数字索引的,则键将以连续的方式重新索引。结果必须与传递给它的数组匹配,才能真正成为数字索引(顺序)数组。否则,可以假定它是一个关联数组(在 C 等语言中无法获得)。

以下函数适用于 PHP >= 4。

<?php
function is_sequential_array($var)
{
return (
array_merge($var) === $var && is_numeric( implode( array_keys( $var ) ) ) );
}

function
is_assoc_array($var)
{
return (
array_merge($var) !== $var || !is_numeric( implode( array_keys( $var ) ) ) );
}
?>

如果您不关心索引的实际顺序,可以将比较更改为 == 和 !=。
dmitry dot sushilov at gmail dot com
9 年前
function is_associate_array($array)
{
return $array === array_values($array);
}

或者您可以在函数中添加 is_array 检查
JTS
14 年前
我会更改比较的顺序,因为如果它真的是一个空数组,最好在执行几个“cpu 和内存密集型”函数调用之前停止。

最终,在一个比率为 3 个非空数组对 1 个空数组的情况下,为 1000000 次迭代计算的结果是,它需要少 10% 的时间。
或者换个说法
如果数组不为空,它需要大约 3% 到 4% 的时间,但在空数组上至少快 4 倍。

此外,内存消耗确实更少。

<?php
function is_assoc($array) {
return (
is_array($array) && (count($array)==0 || 0 !== count(array_diff_key($array, array_keys(array_keys($array))) )));
}
?>
Michael
16 年前
对下面内容的细微修改

<?php

function is_assoc($array)
{
return
is_array($array) && count($array) !== array_reduce(array_keys($array), 'is_assoc_callback', 0);
}

function
is_assoc_callback($a, $b)
{
return
$a === $b ? $a + 1 : 0;
}

?>
gwschnell at ewe dot net
6 年前
如果对不存在的变量应用 is_array(),将抛出错误。
March
18 年前
这是另一个测试数组是否为关联数组的函数变体。基于 mot4h 的想法。

<?php
function is_associative($array)
{
if (!
is_array($array) || empty($array))
return
false;

$keys = array_keys($array);
return
array_keys($keys) !== $keys;
}
?>
rik at mmod dot co
6 年前
在 if 语句中使用 in_array 之前使用 is_array 可以安全地避免在使用 in_array 时检查可能为非数组的变量。例如

注意:一个实际的用例可能是我们有一组可能的标志,在数据库中我们存储了每个标志是 0 还是 1。我们希望返回值为 1 的标志列表。

这里我们的例子不会使用那么多技术工件,而是基于类似的逻辑,只是为了说明这一点。

<?php

// 我们有一个已知值的列表
$knownVars = ['apple', 'orange'];

// 要检查的值列表
$listToCheck = ['pear', 'banana'];

// 以及一个方法,它接受要检查的值列表并返回一个新列表
// 从该列表中找到的有效项目...
public function getValidItemsList( $listToCheck /*['pear', 'banana']*/)
{
$returnList = [];
foreach(
$listToCheck as $key => $val)
{
if(
in_array($val, $knownVars))
{
array_push($returnList, $val);
}
}

if(empty(
$returnList))
{
// 如果没有找到有效的项目,我们有一个特殊情况,这是我们要处理的情况
return -1;
}

// 否则,通常返回一个找到有效的项目的列表
return $returnList;
}

// 调用该方法并检查任何可用于某些目的的有效项目
$validItemsList = getValidItemsList($listToCheck);

// 在这种用法中,我们可能会得到一个异常,因为
// in_array() 要求参数 #2 为数组,检查值 != -1 不会跳出 if 语句:
if(isset($validItemsList) && $validItemsList != -1 && in_array('apple', $validItemsList))
{
//...
}

// 在这种用法中,我们安全地跳出 if 语句:
if(isset($validItemsList) && $validItemsList != -1 && is_array($validItemsList) && in_array('apple', $validItemsList))
{
//...
}

?>

希望这能帮助到某些人,我知道它帮助了我。
lrgbx0 at gmail dot com
6 年前
is_assoc() 基准测试

<?php

function is_assoc1($array) {
if (!
is_array($array)) return false;
$i = count($array);
while (
$i > 0) unset($array[--$i]);
return (bool)
$array;
}

function
is_assoc2(&$array) {
if (!
is_array($array)) return false;
$i = count($array);
while (
$i > 0) {
if (!isset(
$array[--$i])) return true;
}
return
false;
}

function
is_assoc3(&$array) {
if (!
is_array($array)) return false;
$i = count($array);
while (
$i > 0) {
if (!
array_key_exists(--$i, $array)) return true;
}
return
false;
}

function
is_assoc4($array) {
if (!
is_array($array)) return false;
ksort($array);
foreach (
array_keys($array) as $k => $v) {
if (
$k !== $v) return true;
}
return
false;
}

function
is_assoc5(&$array) {
return
is_array($array) && array_diff_key($array, array_keys($array));
}

$arr1 = array(); // not associative
$arr2 = $arr3 = array('foo', 'bar', 'baz', 'foo', 'bar', 'baz', 'foo', 'bar', 'baz', 'foo'); // not associative
asort($arr3); // not associative, shuffled keys
$arr4 = array('foo', 'bar', 'baz', 'foo', 'bar', null, 'foo', 'bar', 'baz', 'foo'); // not associative but is_assoc2() thinks it is
$arr5 = array(0 => 'foo', 1 => 'bar', 2 => 'baz', 3 => 'foo', 4 => 'bar', 5 => 'baz', 'foo3' => 'foo', 'bar3' => 'bar', 'baz3' => 'baz', 'foo4' => 'foo'); // associative

$i = $j = 0;
$time = array(0.0, 0.0, 0.0, 0.0, 0.0);

for (
$j = 0; $j < 2000; $j++) {
$time[0] -= microtime(true);
for (
$i = 0; $i < 1000; $i++) {
if (
is_assoc1($arr1) || is_assoc1($arr2) || is_assoc1($arr3) || is_assoc1($arr4) || !is_assoc1($arr5)) {
echo
'error';
break;
}
}
$time[0] += microtime(true);
$time[1] -= microtime(true);
for (
$i = 0; $i < 1000; $i++) {
if (
is_assoc2($arr1) || is_assoc2($arr2) || is_assoc2($arr3) || !is_assoc2($arr4) || !is_assoc2($arr5)) { // $arr4 tweaked
echo 'error';
break;
}
}
$time[1] += microtime(true);
$time[2] -= microtime(true);
for (
$i = 0; $i < 1000; $i++) {
if (
is_assoc3($arr1) || is_assoc3($arr2) || is_assoc3($arr3) || is_assoc3($arr4) || !is_assoc3($arr5)) {
echo
'error';
break;
}
}
$time[2] += microtime(true);
$time[3] -= microtime(true);
for (
$i = 0; $i < 1000; $i++) {
if (
is_assoc4($arr1) || is_assoc4($arr2) || is_assoc4($arr3) || is_assoc4($arr4) || !is_assoc4($arr5)) {
echo
'error';
break;
}
}
$time[3] += microtime(true);
$time[4] -= microtime(true);
for (
$i = 0; $i < 1000; $i++) {
if (
is_assoc5($arr1) || is_assoc5($arr2) || is_assoc5($arr3) || is_assoc5($arr4) || !is_assoc5($arr5)) {
echo
'error';
break;
}
}
$time[4] += microtime(true);
}

echo
'is_assoc1(): ' . $time[0] . "\n";
echo
'is_assoc2(): ' . $time[1] . "\n";
echo
'is_assoc3(): ' . $time[2] . "\n";
echo
'is_assoc4(): ' . $time[3] . "\n";
echo
'is_assoc5(): ' . $time[4] . "\n";

?>

is_assoc1() - 使用 unset(),有点慢,但内存友好且没有函数调用
is_assoc2() - 使用 isset(),是最快的,但只要数组包含 NULL 就会返回 TRUE
is_assoc3() - 修复了 is_assoc2(),使用 array_key_exists(),速度快且内存友好,比下面那个更智能(无需检查所有那些键)
is_assoc4() - alex 的版本,具有正确的检查和键排序
is_assoc5() - 修复了 JTS 版本,非常不错,但使用太多函数,并且检查所有键

结果

is_assoc1(): 2.1628699302673
is_assoc2(): 1.1079933643341
is_assoc3(): 1.7120850086212
is_assoc4(): 3.9194552898407
is_assoc5(): 1.9509885311127
Anonymous
15 年前
在匿名用户之前发布的示例中使用 empty() 会导致“致命错误:无法在写入上下文中使用函数返回值”。我建议使用 count() 代替

<?php
function is_assoc($array) {
return (
is_array($array) && 0 !== count(array_diff_key($array, array_keys(array_keys($array)))));
}
?>
mbrodala at pagemachine dot de
7 年前
请注意,来自 hperrin at gmail dot com 的基准测试结果在此期间已发生变化

is_array : 0.31888604164124
cast, === : 0.58448791503906

(使用 PHP 5.6.24,我希望在 PHP 7 中得到其他结果)
Daniel
5 年前
下一篇文章不正确,因为它在空数组索引方面存在问题
https://php.net/manual/es/function.is-array.php#89332

以下代码使用上面的链接 PHP 代码

<?php
function is_assoc($var)
{
return
is_array($var) && array_diff_key($var,array_keys(array_keys($var)));
}

function
test($var)
{
echo
is_assoc($var) ? "I'm an assoc array.\n" : "I'm not an assoc array.\n";
}

// 一个关联数组
$a = array("a"=>"aaa","b"=>1,"c"=>true);
test($a);

// 也许是关联数组?
$b = array(0 => "aaa", 1 => 1, 3 => true); // 索引 2 不存在
test($b);
?>

# 输出
我是一个关联数组。
我是一个关联数组。

"关联数组是指使用命名键的数组,这些键是由你分配给它们的。"
https://w3schools.org.cn/php/php_arrays.asp

解决方案

<?php
function is_assoc(array $array)
{
return
count(array_filter(array_keys($array), 'is_string')) > 0;
}
function
test(array $array)
{
echo
is_assoc($array) ? "I'm an assoc array.\n" : "I'm not an assoc array.\n";
}
// 一个关联数组
$a = array("a"=>"aaa","b"=>1,"c"=>true);
test($a);
// 一个数组
$b = array(0=>"aaa",1=>1,3=>true);
test($b);
?>

# 输出
我是一个关联数组。
我不是一个关联数组。

如果你想检查纯关联数组,将 > 0 替换为 === count($array)
jupiter at nospam dot com
18 年前
将检查多维数组到任何指定的级别。这是对 11/16/05 提交的修复,它会中断,因为你必须为 foreach 提供一个数组。注意递归函数不应该超过 100 层,否则可能会在服务器上破坏内存堆栈。

<?php
// 递归检查多维数组到指定深度
// 原始 $level 必须大于等于 2,否则会立即返回 true
function isDeepMultiArray($multiarray, $level = 2) { // 默认是简单多维数组
if (is_array($multiarray)) { // 确认数组
if ($level == 1) { // 指定次数递归后 $level 达到 1
return true; // 返回 true 给递归函数条件
} // 结束条件
foreach ($multiarray as $array) { // 进入数组下一级
if (isDeepMultiArray($array, $level - 1)) { // 检查子数组
$message = "I'm a multiarray"; // 可选信息
return $message; // 最好 $message = true,这样函数返回布尔值
} // 结束递归函数
} // 结束循环
} else { // 指定级别不是数组
return false; // 也用于递归,所以不能更改为消息
}
}

if (
isDeepMultiArray(array(array()), 2)); // 注意,即使数组为空,这也返回 true

?>
顺便说一句,我的符号与 PEAR 手册的编码标准一致,这也是 php.net 建议遵循的标准。我希望这样的函数能够包含在 PHP6 中。
To Top