Delicious Bookmark this on Delicious Share on Facebook SlashdotSlashdot It! Digg! Digg



PHP : Function Reference : Variable Handling Functions : is_array

is_array

Finds whether a variable is an array (PHP 4, PHP 5)
bool is_array ( mixed var )

Example 2588. Check that variable is an array

<?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';
?>

The above example will output:

Array
not an Array

Related Examples ( Source code ) » is_array






Code Examples / Notes » is_array

gabriel

Yet another safer, faster way of detecting whether an array is associative.
The principle is: using array reduction on the keys, we verify that each key is numeric and is equal to its rank.
Beware: integer keys that are not in sequence, or are negative, or with "holes", still make an associative array.
<?php
/**
 * @param array $arr
 * @returns boolean
 */
function isNotAssocArray($arr)
{
return (0 !== array_reduce(
array_keys($arr),
create_function('$a, $b', 'return ($b === $a ? $a + 1 : 0);'),
0
)
);
}
?>
Of course, it is still faster if the callback for array_reduce is not an anonymous function:
<?php
function callbackReduceNotArray($a, $b)
{
return ($b === $a ? $a + 1 : 0);
}
function isVector($arr)
{
return (0 !== array_reduce(
array_keys($arr),
'callbackReduceNotArray',
0
)
);
}
?>


alfred j fazio
Yet another associative array test:
function binary_nand ($a, $b) { return !$a && !$b; }
function binary_nor ($a, $b)  { return !$a || !$b; }
// Returns true if array has elements with non-numeric keys
function is_associative_array ($arr) {
 return is_array($arr) && !empty($arr) && array_reduce(array_map("is_numeric", array_keys($arr)), "binary_nor", true);
}
// Returns true if all elements of array have a non-numeric key
function is_strict_associative_array ($arr) {
 return is_array($arr) && !empty($arr) && array_reduce(array_map("is_numeric", array_keys($arr)), "binary_nand", false);
}


jupiter

Will check a Multi-Dimentional Array to any specified level.  This is a fix to 11/16/05 submission, which would break since you must supply a foreach with an array. Beware recursive functions shouldn't go over 100 deep or could break the memory stack on server.
<?php
// checks for multiarray to defined depth level recursively
// original $level must be 2 or more, else will instantly return true
function isDeepMultiArray($multiarray, $level = 2) {  // default is simple multiarray
   if (is_array($multiarray)) {  // confirms array
       if ($level == 1) {  // $level reaches 1 after specified # of recursions  
           return true;  // returns true to recursive function conditional
       }  // end conditional
       foreach ($multiarray as $array) {  // goes one level deeper into array
           if (isDeepMultiArray($array, $level - 1)) {  // check subarray
               $message = "I'm a multiarray";  // optional message
               return $message;  // best if $message = true so function returns boolean
           }  // end recursive function
       }  // end loop
   } else {  // not an array at specified level
   return false;  // is also used recursively so can't change to message
   }
}
if (isDeepMultiArray(array(array()), 2)); // beware this returns true eventhough arrays are empty
?>
BTW my notation is consistent with the PEAR manual on coding standards, which is what php.net says to follow. I hope a function like this gets included in PHP6.


yonman

To expand a bit on dan at cain dot sh's comment - is_array will not properly identify Iterator implementing classes.

rjg4013

To add to the chaos (or perhaps clarification) of these notes, here's another is_associative_array() function that I made and use..
<?php
function is_associative_array( $var ) {

return is_array( $var ) && !is_numeric( implode( array_keys( $var ) ) );
}
?>
I guess with this logic you could do the following too:
<?php
function is_sequential_array( $var ) {

return is_array( $var ) && is_numeric( implode( array_keys( $var ) ) );
}
?>
I never saw a reason to check if it was empty because if it is, the type seems inconsequential.
RJ Gilligan


doker0

This should hack the hack to accept tables
NOTICE! Works only for 1-dim arrays.
if (!function_exists('http_build_query')) {
  function http_build_query($formdata, $numeric_prefix = "")
  {
      $arr = array();
      foreach ($formdata as $key => $val)
        $arr[] = is_array($val) ? http_build_query($val,$key)  :
        ( $numeric_prefix !='' ? (urlencode($numeric_prefix) . '[' . urlencode($key) . ']')  
        : urlencode($key))  . "=".urlencode($val) ;
      return implode($arr, "&");
  }
}
for query '?a[0]=w&b=ggg&a[1]=x&a[2]=y&a[3]=z'
var_export($_GET); shows
array (
 'a' =>
 array (
   0 => 'w',
   1 => 'x',
   2 => 'y',
   3 => 'z',
 ),
 'b' => 'ggg',
)
and
echo (http_build_query($_GET));
shows
a[0]=w&a[1]=x&a[2]=y&a[3]=z&b=ggg


ryanyoder

this is my attempt at writing a function that would check for a multi dimentional array.  where $dim is the number of dimentions you are checking for and $array is of course the variable that is being check.  i dont know if there's a better way out there, but this is what i do.
  function is_multi_array($array,$dim)
  {
     if(($dim==1)&&(is_array($array)))
     {
        return 1;
     }
     foreach($array as $level2)
     {
        if(is_multi_array($level2,$dim-1))
        {
           return 1;
        }
     }
     return 0;
  }


junkpost

There is another example of check to associative array. (See below early versions.)
<?php
funciton is_assoc_array($var) {
   return is_array($var) && !empty($var) && !preg_match('/^\d+$/', implode('', array_keys($var)));
}
?>


angelo

The is_associative_array() and is_sequential_array() functions posted by 'rjg4013 at rit dot edu' are not accurate.
The functions fail to recognize indexes that are not in sequence or in order.  For example, array(0=>'a', 2=>'b', 1=>'c') and array(0=>'a', 3=>'b', 5=>'c') would be considered as sequential arrays. A true sequential array would be in consecutive order with no gaps in the indices.
The following solution utilizes the array_merge properties. If only one array is given and the array is numerically indexed, the keys get re-indexed in a continuous way.  The result must match the array passed to it in order to truly be a numerically indexed (sequential) array.  Otherwise it can be assumed to be an associative array (something unobtainable in languages such as C).
The following functions will work for 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 ) ) ) );
}
?>
If you are not concerned about the actual order of the indices, you can change the comparison to == and != respectively.


jupiter

Simple check for a Multi-Dimentional Array of any depth
<?php
// checks for multiarray (2 or more levels deep)
function isMultiArray($multiarray) {
 if (is_array($multiarray)) {  // confirms array
   foreach ($multiarray as $array) {  // goes one level deeper
     if (is_array($array)) {  // is subarray an array
       return true;  // return will stop function
     }  // end 2nd check
   }  // end loop
 }  // end 1st check
 return false;  // not a multiarray if this far
}
?>


bcuffley

pardon my newbiness, but how about:
function is_seq_array( $php_val ) {
 return is_array($php_val) && ($php_val === array_values($php_val);
}
this is taking for granted that array_values would return the "same" object and not a copy, which it currently does for indexed arrays.  If you don't like this assumption, just compare the arrays by values.


vhermecz

Mike's function is quite cool, it is just the one, I was searching for. Using range is a great idea! But it's a bit long for me. Here is a shorter version:
function is_assoc_array($var) {
if (!is_array($var)) {
return false;
}
return array_keys($var)!==range(0,sizeof($var)-1);
}
Or, if you don't want to type that much:
function is_assoc($var) {
return is_array($var) && array_keys($var)!==range(0,sizeof($var)-1);
}


adam

Just looked at all the checks to see if anyone had solved the problem of knowing if an array is "associative" or not.
As mentioned, all arrays are "associative" in a sense as keys are automatically set as numbers if not manually done.
It's just better to say "associative" so we know that keys are alpha based. If the keys were all numbers then we'd call it "sequential".
Here's the common way to create "associative" and "sequential" arrays.
Method 1 (Sequential)
---------------------
$my_array = Array("january","february");
Method 2 (Associative)
----------------------
$my_array = Array("jan"=>"January","feb"=>"February");
So to me the obvious way to check if it's an associative array or not is to see if the first key of the array is numeric or not. If it's numeric then I know it's sequential, otherwise if it's blank or alphanumberic, i know its associative.
I certainly know I wouldnt mix keys so that some were just a number and other were text.... so this check works perfectly for me..  Might be useful to someone else too.....
<?php
//Get first array line, check key
function is_associative($array){
     if(is_array($array) &&
       !is_numeric(array_shift(array_keys($array)))){
           return true;
     }
     return false;
}
?>


dan

is_array() under PHP 5.0.2 will return FALSE when passed an object descended from the internal class interface ArrayAccess(http://www.php.net/spl) even though said object behaves as an array would in most instances.
I've found the following user function helpful with my own classes and functions that expect array(s) as arguments, but work fine with objects that behave as an array would.
<?php
function is_array_abled(&$x)
{
   return (bool)($x instanceof ArrayAccess or is_array($x));
}
?>


lukas.skowronski

If You want to del all slashes from database query result , try this function:
function no_slashes($array)
{
foreach($array as $key=>$value)
{
if(is_array($value))
{
$value=no_slashes($value);
$array_temp[$key]=$value;
}
else
{
$array_temp[$key]=stripslashes($value);
}
}
return $array_temp;
}


mot4h

I was looking at several of the other examples for testing if an array is associative and they seemed a little limited, or a little bulky. Here's my take on it, I think it's a nice balance:
<?php
function is_associative($array){
 if (!is_array($array)) return false;
 foreach(array_keys($array) as $key=>$value) {
   if ($key != $value) return true;
 }
 return false;
}
?>
The idea being that the array_keys() function returns a non-associative array, so if the array you fed it wasn't associative, all the key/value pairs in the array of keys should be identical. Otherwise it must have been associative.


mmalone

I was just profiling a rather large php app I have been working on using APD, and noticed that the is_array() function is (apparently) rather inefficient in terms of 'real' time.  Not sure why this might be, but it could be a bottleneck in an application where performance is important.
Here is the applicable pprofp output, for those interested:
        Real         User        System             secs/    cumm
%Time (excl/cumm)  (excl/cumm)  (excl/cumm) Calls    call    s/call  Memory Usage Name
--------------------------------- -----------------------------------------------------
36.9 0.76 0.76  0.00 0.00  0.05 0.05    53  0.0143   0.0143       -99704 is_array


rob

Here's another way to see if an array is associative (nobody actually uses the term "vector" ;-) ). It's a little less breakable than the other current leading suggestion, and it's somewhat faster. Tested with 1000 iterations of two simple arrays (one associative, one not).
<?php
function array_is_associative ($array)
{
   if ( is_array($array) && ! empty($array) )
   {
       for ( $iterator = count($array) - 1; $iterator; $iterator-- )
       {
           if ( ! array_key_exists($iterator, $array) ) { return true; }
       }
       return ! array_key_exists(0, $array);
   }
   return false;
}
?>


elanthis

First, "sequential array" is a silly term.  Use "vector."  Likewise, it's not an "associative array," it's a "map."  We have common computer science terms for a reason.  :)
"If the keys were all numbers then we'd call it "sequential"."
But that's not true.  The following array, with all-numeric keys, is a map, not a vector:
$ar[1] = 'foo';
$ar[12] = 'bar';
$ar[578] = 'baz';
A vector would be an array in which all keys are integers, each successive key is equal to the previous key plus one, and the first key is 0.
So, the only proper, always correct, fail-proof way I can think of to do this is (and this is lame we have to do ths, since the internal PHP implementation clearly knows in a much more efficient manner):
function is_vector (&$array) {
 $next = 0;
 foreach ($array as $k=>$v) {
   if ($k != $next)
     return false;
   $next++;
 }
 return true;
}
Yes, it might look cleaner to use array_keys() in there, but I think that will be far more inefficient, since it would have to create a whole new array and copy all the keys into it.  The above should be faster.  In theory.


march

And here is another variation for a function to test if an array is associative. Based on the idea by mot4h.
<?php
function is_associative($array)
{
 if (!is_array($array) || empty($array))
   return false;
 $keys = array_keys($array);
 return array_keys($keys) !== $keys;
}
?>


mike-php

All arrays in PHP are associative arrays, but it is quite easy to treat an associative array just like it is a sequential array. However, when dealing with XML-RPC, it is necessary to know whether an array is associative or sequential, so I created this function.
It isn't perfect, since an associative array that just happens to have sequential, integer keys starting with 0 will 'look' exactly like a sequential array, and will fool this function.
/****************************************************************
* is_assoc_array tries to decide whether or not a given array   *
* is an associative array, or a sequential array. Of course, no *
* such distinction is made by PHP, so it really just tests      *
* whether or not a given array could possibly be a sequential   *
* array. Since an associative array with sequential, integer    *
* keys 'looks' just like a sequential array, this function will *
* be fooled.                                                    *
*                                                               *
* BUG: Associative arrays with sequential, integer keys 'look'  *
* just like sequential arrays, and will be identified as such.  *
*                                                               *
****************************************************************/
function is_assoc_array( $php_val ) {
  if( !is_array( $php_val ) ){
     # Neither an associative, nor non-associative array.
     return false;
  }
  $given_keys = array_keys( $php_val );
  $non_assoc_keys = range( 0, count( $php_val ) );
  if( function_exists( 'array_diff_assoc' ) ) { # PHP > 4.3.0
     if( array_diff_assoc( $given_keys, $non_assoc_keys ) ){
        return true;
     }
     else {
        return false;
     }
  }
  else {
     if( array_diff( $given_keys, $non_assoc_keys ) and array_diff( $non_assoc_keys, $given_keys ) ){
        return true;
     }
     else {
        return false;
     }
  }
}


michael

A slight modification of what's below:
<?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;
}
?>


markus-rehrs

@elanthis at awesomeplay dot com, your function to check whether an array is a map or a vector has a little flaw.
Comparing $k != $value will return true if $value is  0. If you check a map containing just one element like array('foo'=>'bar') your check assumes that this is a vector. Use the operator !== (not identical with) to avoid that:
<?php
function is_vector (&$array) {
 $next = 0;
 foreach ($array as $k=>$v) {
   if ($k !== $next)
     return false;
   $next++;
 }
 return true;
}
?>


elliot dot winkler

@ markus-rehrs at gmx dot de: I don't see anywhere that $k is compared to $v -- it's compared to $next. In any case, you're right that there's an error -- but it's that $k == $next will be true if $next is 0 and $k is "0", or $next is 1 and $k is "1", etc. So yeah, it's probably better to use !== rather than !=. OTOH, this is really only a problem if you give your arrays ambiguously number-like string key names like "0", "1", etc.

Change Language


Follow Navioo On Twitter
debug_zval_dump
doubleval
empty
floatval
get_defined_vars
get_resource_type
gettype
import_request_variables
intval
is_array
is_binary
is_bool
is_buffer
is_callable
is_double
is_float
is_int
is_integer
is_long
is_null
is_numeric
is_object
is_real
is_resource
is_scalar
is_string
is_unicode
isset
print_r
serialize
settype
strval
unserialize
unset
var_dump
var_export
eXTReMe Tracker