Arrays

Examples

PHP arrays are internally stored as maps. And PHP arrays have an internal order to their elements that is independent of the keys and values, and there are functions that you can use to traverse the arrays based on this internal order. The order is normally that in which values were inserted into the array, but the sorting functions described later let you change the order to one based on keys, values, or anything else you choose.

<?php
$a1 = array("item");
$a2 = range("a","k");
$a3[0] = "abc";
$a3[1] = "def";
$a3[]  = “ghi”; // adds third element
$a4 = array("k1" => "v1", "k2" => "v2");

If keys are omitted when defining an asso. array, a numeric key beginning with 0 is assumed. The key for “v3” is 0, for “v4” 1. This is most likely not wanted.

$a5 = array(“k1” => “v1”, “k2” => “v2”, “v3”, “v4” );

Multidimensional arrays can be created:

<?php
$row_0 = array(1, 2, 3);
$row_1 = array(4, 5, 6);
$row_2 = array(7, 8, 9);
$multi = array($row_0, $row_1, $row_2);
echo("The value at row 2, column 0 is {$multi[2][0]}\n");

The sizeof() and count() operators return the number of elements.

Extracting Multiple Values Using the list() construct

The list() construct lets you copy array elements into variables:
<?php
$person = array('name' => 'Fred', 'age' => 35, 'wife' => 'Betty');
list($n, $a, $w) = $person;  // $n is 'Fred', $a is 35, $w is 'Betty'
list($n, $a) = $person;     // $n is 'Fred', $a is 35
$values = array('hello', 'world');

/* Extra variables are fill with NULL */
list($a, $b, $c) = $values;   // $a is 'hello', $b is 'world', $c is NULL
$values = range('a', 'e');

/* Use two or more commas to skip values */
list($m,,$n,,$o) = $values;   // $m is 'a', $n is 'c', $o is 'e'

Slicing an Array

To extract a subset from an numerically-indexed array, use array_slice():

<?php
$subset = array_slice(array, offset, length);

$people = array('Tom', 'Dick', 'Harriet', 'Brenda', 'Jo');
$middle = array_slice($people, 2, 2); // $middle is array('Harriet', 'Brenda')

array_slice() returns a new array consisting of a consecutive series of values from the original array. The offset parameter identifies the initial element to copy (0 represents the first element in the array), and the length parameter identifies the number of values to copy. The new array has consecutive numeric keys starting at 0.

It is generally only meaningful to use array_slice() on indexed arrays (i.e., those with consecutive integer indexes, starting at 0):

<?php
// this use of array_slice() makes no sense
$person = array('name' => 'Fred', 'age' => 35, 'wife' => 'Betty');
$subset = array_slice($person, 1, 2);  // $subset is array(0 => 35, 1 => 'Betty')
array_slice() can be combined with list() to extract only some values to variables:
$order = array('Tom', 'Dick', 'Harriet', 'Brenda', 'Jo');
list($second, $third) = array_slice($order, 1, 2); // $second is 'Dick', $third is 'Harriet'

Splitting an Array into Chunks

<?php
$chunks = array_chunk(array, size [, preserve_keys]);

array_chunk() returns a multidimensional array whose inner arrays or are smaller, evenly-sized arrays (chunks) of the original array. The third argument, preserve_keys, is a Boolean value that determines whether the elements of the new arrays have the same keys as in the original (useful for associative arrays) or new numeric keys starting from 0 (useful for indexed arrays). The default is to assign new keys, as shown here:

<?php
$nums = range(1, 7);
$rows = array_chunk($nums, 3);
print_r($rows);

outputs:

Array
(
    [0] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
        )
    [1] => Array
        (
            [0] => 4
            [1] => 5
            [2] => 6
        )
    [2] => Array
        (
            [0] => 7
        )
)

This example divides an array into three parts corresponding to three rows of a table.

<?php
$columns = 3;
$citylist = array('Black Canyon City', 'Chandler', 'Flagstaff', 'Gilbert', 'Glendale', 'Globe', 'Mesa', 'Miami',
        'Phoenix', 'Peoria', 'Prescott', 'Scottsdale', 'Sun City', 'Surprise', 'Tempe', 'Tucson', 'Wickenburg');

$columns = array_chunk($citylist, ceil(count($citylist) / $rows));
buildtable1($columns);

// buildtable1(&$columns) will creates a table with $columns as the columns
function buildtable1(&$columns)
{
   $size = array();

   for ($i =0; $i < count($columns); $i++) {
        $size[$i] = count($columns[$i]);
   }

   $max = max($size);
   echo '<table>';
   for ($j = 0; $j < $max; $j++) {
          echo '<tr>';
          for ($i = 0; $i < count($columns); $i++) {

                  echo '<td>'.($size[$i] <= $max ? $columns[$i][$j] : "&nbsp;").'</td>';
          }
          echo '</tr>';
   }
   echo '</table>';
}
$rows = $columns;

buildtable2(&$rows) creates a table whose rows are $row ???????. output the data is horizontally

<?php
 function buildtable2(&$rows)
 {
         echo '<table>';
         foreach ($rows as $a) {
                 echo '<tr>';
                 foreach ($a as $value) {
                         echo "<td>$value</td>";
                 }
                 echo '</tr>';
         }
         echo '</table>';
 }

Keys and Values

array array_keys() returns an array consisting of only the keys in the array, in internal order (the order in which the elements were inserted):

<?php
 $person = array('name' => 'Fred', 'age' => 35, 'wife' => 'Wilma');
 $keys = array_keys($person);   // $keys is array('name', 'age', 'wife')

array array_of_values() is a less generally useful function to retrieve an array of just the values in an array. The values are returned in the array| ‘s internal order:

<?php
 $values = array_values($person);   // $values is array('Fred', 35, 'Wilma');

Checking Whether an Element Exists

bool array_key_exists(key, array) returns TRUE if the given key is set in the array. key can be any value possible for an array index. array_key_exists() also works on objects. array_key_exists() should be used in if-tests because it is dangerous to do:

<?php
if ($person['name']) { ... }    // this can be misleading

$person[‘name’] might 0, NULL, or the empty string, which will cause the if-test to fail. We therefore should prefer array_key_exists():
$person['age'] = 0;     // unborn

if ($person['age']) { //

  echo "true!\n";
}

if (array_key_exists('age', $person)) {
  echo "exists!\n";
}

outputs:

exists!
<?php
$a = array(0,NULL,'');

function trueORfalse($v)
{
   return $v ? "T" : "F";
}

for ($i=0; $i < 4; $i++) {

  printf("%d: %s %s<br />\n", $i, trueORfalse(isset($a[$i])), trueORfalse(array_key_exists($i, $a)));
}

The first column is the index. The second is the result of calling isset() on the element. The third is array_key_exists():

0: T T 1: F T // NULL fails isset() but not array_key_exists() 2: T T 3: F F

http://www.alternateinterior.com/2006/11/comparing-array_key_exists-with-isset.html explains that it is faster to use isset() than array_key_exists(), and argues it is therefore better to avoid using NULL as a valid array elements.

Removing and Inserting Elements in an Array

array array_splice(array &$input , int $offset [,int $length [,mixed $replacement ]]) removes the elements designated by offset and length from the input array, and replaces them with the elements of the replacement array, if supplied. It returns the array consisting of the extracted elements . Numeric keys in input are not preserved. If offset is positive, then the start of removed portion is at that offset from the beginning of the input array. For example:

<?php
 $subjects = array("physics", "chem", "math", "bio", “cs”, “drama”, “classics”);

We can remove the math, bio, and cs elements by telling array_splice() to start at position 2 and remove 3 elements:

<?php
 $removed = array_splice($subjects, 2, 3); // remove 3 elements starting with index 2
 // $removed is ("math", “bio”, “cs”)
 // subjects is array(‘physics’, “chem”, “drama”, “classics”)

 $colors = array("red", "green", "blue", "yellow", “violet”, “pink”);
 $removed = array_splice($colors, 1, 3); // remove 3 elements starting with index 1
 // $removed is now array(“green”, “blue”, “yellow”)
 // $colors is now array("red", “violet”, “pink”)

If you omit the length, array_splice() removes from the offset to the end of the array:

<?php
 $removed = array_splice($subjects, 2); // remove from index 2 to end of array

 // $removed is ("math", “bio”, “cs”, “drama”, “classics”)
 // $subjects is array(“physics”, “chem”)

If you simply want to delete the elements and you don‘t care about their values, you don‘t need to assign the results of array_splice():

<?php
array_splice($colors, 2);
// $colors is now array("red", "green")

If offset is negative, the removal starts that far from the end of the input array, where -1 corresponds to the last element, -2 to the next to last, and so on. Thus: array_splice($colors, -3, 2) removes two elements starting with the third element from the end. $colors is now array(“red”, “green”, “blue”, “pink”)

i   <?php
   array_splice($colors, -2, 1);
   // $colors is now array(“red”, “green”, “blue”, “yellow”, “pink”)
   array_splice($colors, -1);
   // $colors is now array("red”, “green”, “blue”, “yellow”, “violet”)
   array_splice($colors, -3); // removed all elements from the third element from the end.
   // $colors is now array("red”, “green”, “blue”)

A negative length is equivalent to array_splice($input, $offset, count($input)–$offset+$length)). For example, if length is -1, everything from offset up to (but excluding) the last element will be removed. If length is -2, the last two elements are kept, but everything up to this will be removed. Using a negative length means: remove from $offset up to the $length element from the end.

<?php
$colors = array("red", "green", "blue", "yellow", “violet”, “pink”);
array_splice($colors, 1, -2); // equivalent to array_splice($colors, 1, 3)
 // $colors is now array("red", "violet”, “pink”)
array_splice($colors, 2, -1);  // equivalent to array_splice($colors, 2, 3);
// $colors is now array("red", "green”, “pink”)

To insert elements where others were removed, use the fourth argument. (If the replacement array is just one element, array() doesn’t have to be used, unless the element is an array itself).

<?php
$colors = array("red", "green", "blue", "yellow");
array_splice($colors, 1, count($colors), "orange");
// $colors is now array("red", "orange")

$colors = array("red", "green", "blue", "yellow");
array_splice($colors, -1, 1, array("black", "maroon"));
// $colors is now array("red", "green", "blue", "black", "maroon")

The size of the replacement array doesn‘t have to be the same as the number of elements you delete. The array grows or shrinks as needed:

<?php
$subjects = array("physics", "chem", "math", "bio", “cs”, “drama”, “classics”);
$new = array("law", "business", "IS");
$removed = array_splice($subjects, 2, 4, $new);
// $subjects is now array("physics”, “chem”, “law”, “business”, “IS”, “classics”)
// $removed is array("math", "bio", “cs”, “drama”)

To get the effect of inserting new elements into the array, delete zero elements. The inserted elements are placed before offset. Keys in the replacement array will not be preserved. array_splice($a1, $offset, 0, $replace) is thus an idiom for inserting elements into an existing array.

<?php
$colors = array("red", "green", "blue", "yellow");
array_splice($colors, 3, 0, "purple");
// idiom for how to insert elements using array_splice(): set value to delete to 0.
// $colors is now array("red", "green", "blue", "purple", "yellow");

Although the examples so far have used an indexed array, array_splice() also works on associative arrays:

<?php
$capitals = array ( "USA"  => "Washington", "Great Britain"=> "London", "New Zealand" => "Wellington",
    "Australia" => "Canberra", "Italy" => "Rome");
);

$down_under = array_splice($capitals, 2, 2);  // Remove New Zealand and Australia
$france = array("France"  => "Paris");
array_splice($capitals, 1, 0, $france);     // insert France between USA and G.B.
// $capitals is: array([USA] => Washington [0] => Paris [Great Britain] => London [Italy] => Rome )

array array_pad(array $input, int $pad_size , mixed $pad_value)

returns a copy of the input padded to (increased to) the size specified by pad_size, padded with pad_value. If pad_size is positive then the array is padded on the right, if it‘s negative then on the left. If the absolute value of pad_size is less than or equal to the length of the input then no padding takes place.

<?php
$input = array(12, 10, 9);

$result = array_pad($input, 5, 0);
// result is array(12, 10, 9, 0, 0)

$result = array_pad($input, -7, -1);
// result is array(-1, -1, -1, -1, 12, 10, 9)

$result = array_pad($input, 2, "noop");
// not padded

If you pad an associative array, existing keys will be preserved. New elements will have numeric keys starting at 0.

array array_fill (int $start_index, int $num, mixed $value)

Fills an array with num entries of the value of the value parameter, keys starting at the start_index parameter. Returns the filled array.

<?php
$a = array_fill(5, 6, 'banana');
$b = array_fill(-2, 2, 'pear');
print_r($a);
print_r($b);

outputs:

<?php
$a = array_fill(5, 6, 'banana');
$b = array_fill(-2, 2, 'pear');
Array
(
    [5]  => banana
    [6]  => banana
    [7]  => banana
    [8]  => banana
    [9]  => banana
    [10] => banana
)
Array
(
    [-2] => pear
    [0] => pear
)

Converting Between Arrays and Variables

Creating Variables from an Array

The extract() function automatically creates local variables from an array. The indexes of the array elements are the variable names:

<?php
$var_array = array("color" => "blue",
                   "size"  => "medium",
                   "shape" => "sphere");

extract($var_array);

This will create the variables $color, $size, and $shape. If a variable created by the extraction has the same name as an existing one, the extracted variable overwrites the existing variable. You can modify extract()‘s behavior by passing a second argument. The function reference (at PHP.net) describes the possible values for this second argument. The most useful value is EXTR_PREFIX_SAME, which says that the third argument to extract() is a prefix for the variable names that are created. This helps ensure that you create unique variable names when you use extract(). It is good PHP style to always use EXTR_PREFIX_SAME, as shown here:

<?php
$shape = "round";
$array = array("cover" => "bird", "shape" => "rectangular");
extract($array, EXTR_PREFIX_SAME, "book");   // prefixes only variables when there is a name collison
echo "Cover: $cover, Book Shape: $book_shape, Shape: $shape";

ouputs:

Cover: bird, Book Shape: rectangular, Shape: round
<?php
$shape = "round";
$array = array("cover" => "bird", "shape" => "rectangular");
extract($array, EXTR_PREFIX_ALL, "book");        // unconditionally prefixes all variables
echo "Cover: $book_cover, Book Shape: $book_shape, Shape: $shape";

outputs:

Cover: bird, Book Shape: rectangular, Shape: round

Creating an Array from a Variable

compact(), and its opposite extract(), create an associative array whose keys are the variable names and whose values are the variable‘s values. Any names in the array that do not correspond to actual variables are skipped. Here‘s an example of compact() in action:

$color = 'indigo';
$shape = 'curvy';
$floppy = 'none';

$a = compact('color', 'shape', 'floppy');
// or
$names = array('color', 'shape', 'floppy');
$a = compact($names);
foreach($a as $key => $val) {
        print(“[$key] => $val<br />”);
}

outputs:

[color] => indigo
[shape] => curvy
[floppy] => none

Compact is also handy for debugging, to quickly show a bunch of variables and their values. We first use explode()to create an array and then hand it off to compact():

<?php
$count = 70;
$acw = 9;
$cols = 7;
$coldepth = 10;

print_r(compact(explode(' ', 'count acw cols coldepth')));

gives:

Array
(
    [count] => 70
    [acw] => 9
    [cols] => 7
    [coldepth] => 10
)

Traversing Arrays

The foreach Construct

foreach() returns are copies of array elements; however, you can easily modify an array‘s elements by returning a reference. This allows you to modify the array:

<?php
$arr = array(1, 2, 3, 4);
foreach ($arr as &$value) {  // when & precedes $value a reference is returned.
    $value = $value * 2;     // assigning it changing the corresponding array element
}
// $arr is now array(2, 4, 6, 8)
unset($value); // break the reference with the last element

Because the reference of $value to the last element will remain after the loop ends, we must destroy it using unset().

Iterator functions

In PHP every array has an internal iterator that tracks the current element. The iterator functions are:

  • current() returns the element currently pointed at by the iterator. It does not advance the internal iterator.
  • reset() moves the iterator to the first element in the array and returns it
  • next() moves the iterator to the next element in the array and returns it
  • prev() moves the iterator to the previous element in the array and returns it
  • end() moves the iterator to the last element in the array and returns it
  • each() returns the key and value of the current element as an array and moves the iterator to the next element in the array
  • key() returns the key of the current element
  • each() can be used to loop over the elements of an array using the internal iterator. It returns in a four-element associtive array, with keys of 0, 1, key, and value. Elements 0 and key contain the key name of the array element, and 1 and value contain the data. For example:
<?php
$foo = array("bob", "fred", "jussi", "jouni", "egon", "marliese");
$bar = each($foo);
print_r($bar);

outputs:

<?php
Array
(
    [1] => bob
    [value] => bob
    [0] => 0
    [key] => 0
)
<?php
    $foo = array("Robert" => "Bob", "Seppo" => "Sepi");
    $bar = each($foo);
    print_r($bar);
<?php
Array
(
    [1] => Bob
    [value] => Bob
    [0] => Robert
    [key] => Robert
)

each() is typically used in conjunction with list() to traverse an array. For example:

<?php
$fruit = array('a' => 'apple', 'b' => 'banana', 'c' => 'cranberry');

reset($fruit);
while (list($key, $val) = each($fruit)) { // each() advances internal iterator
    echo "$key => $val\n";
}

ouptputs:

a => apple b => banana c => cranberry
<?php
$addresses = array('[email protected]', '[email protected]');
    //. . .
reset($addresses);

while (list($key, $value) = each($addresses)) {

  echo "$key is $value<br />\n";
}

0 is spam@cyberpromo.net 1 is abuse@example.com

You should not assign the array being traversed by each() to another array within the each-loop. This will reset the internal iterator, resulting in an infinite loop. If the internal pointer for the array points past the end of the array contents, each() returns FALSE, and you must call reset() after traversing the array to reset the internal iterator. Calling a Function for Each Array Element array_walk() bool array_walk(array &$array , callback $funcname [, mixed $userdata ]) applies a user-defined function to each element of the array. array_walk() is not affected by the internal array pointer of array. array_walk() will walk through the entire array regardless of pointer position. The function you define takes in two or, optionally, three arguments: the element’s value, the element’s key, and the third is a value supplied to array_walk() when it is called. If the first paramter of the callback function takes a reference, the values of the array can be changed. array_walk() is like C++ for_each(). But the functor for_each() only receives the element, not the element and its key (plus an optional third parameter). So for_each() is more similar to array_map(). In fact, you can pass a functor of sorts to array walk by passing a class instance and a member function. This will be explained toward the end of the discussion. In this example, array_walk() is used to build table columns from the contents of an associative array: $person = array(‘name’ => ‘Fred’, ‘age’ => 35, ‘wife’ => ‘Wilma’);

function print_row($value, $key) {

print(“<tr><td>$value</td><td>$key</td></tr>n”);

} echo ‘<table>’; array_walk($person, ‘print_row’); echo ‘</table>’; Notice that the key is passed as the second parameter to the callback and the value as the first parameter. A variation of this example specifies a background color using the optional third argument to array_walk(). This parameter gives us the flexibility we need to print many tables, with many background colors: $person = array(‘name’ => ‘Fred’, ‘age’ => 35, ‘wife’ => ‘Wilma’);

function print_row($value, $key, $color) {     print(“<tr><td bgcolor=$color>$value</td><td bgcolor=$color>$key</td></tr>n”); }

echo ‘<table>’; array_walk($person, ‘print_row’, ‘blue’); echo ‘</table>’; If callback() needs to change the actual values of the array, specify the first parameter as a reference. Then, any changes made to those elements will be made in the original array itself. For example: $fruits = array(“d” => “lemon”, “a” => “orange”, “b” => “banana”, “c” => “apple”);

function test_alter(&$item1, $key, $prefix) // using a reference allows us to change values in the array {     $item1 = ”$prefix: $item1”; }

function test_print($item2, $key) {     echo ”$key. $item2<br />n”; }

echo “Before ...:n”; array_walk($fruits, ‘test_print’);

array_walk($fruits, ‘test_alter’, ‘fruit’); echo ”... and after:n”;

array_walk($fruits, ‘test_print’); Before ...: d. lemon a. orange b. banana c. apple ... and after: d. fruit: lemon a. fruit: orange b. fruit: banana c. fruit: apple

All the array traversal functions will accept a class method as a callback. The second parameter must be an array with two elements. If the class method is static, then the array would contain: the name of the class, followed by the name of the static method. If the method is not static, the array would contain: a class instance, followed by the name of the class method.

For example, give a class with a static display() method that echos the input value:

class Show {

public static function display(&$value, $key) {

echo ‘<p>the value is ‘.$value.’</p>’;

}

} $numbers = range(1, 10); array_walk($numbers,array(“Show”, “display”));

If the class method is not static, instantiate an object and pass it:

class Sum {

private $sum; function __construct() { $sum = 0;}

public function sum($value) { $this->sum += $value; }

public function display() { echo “sum is ”.$this->sum.’<br />’; }

}

$numbers = range(1, 10); $sum = new Sum(); array_walk($numbers, array($sum, “sum”)); $sum->display(); echo “<hr />”;

Here is the table builder example again. This time we use array_walk() together with a class method:

echo “<p>example two</p>”;

class Tablebuilder {
private $table; function __construct() {} public function build($value, $key)
{
$this->table .= “<tr><td>$key</td><td>$value</td></tr>n”;

} public function display() {

echo “<table><tr><th>Value</th><th>Key</th></tr>”.$this->table.’</table>’;

}

}; $fruits = array(“d” => “lemon”, “a” => “orange”, “b” => “banana”, “c” => “apple”); $tb = new TableBuilder(); array_walk($fruits, array($tb, “build”)); $tb->display() array_reduce() A cousin of array_walk(), array_reduce(), applies a function to each element of the array in turn, to build a single value: $result array_reduce ( array $input , callback $function [, int $initial ] ) array_reduce() is similar to the C++ accumulate() function found in <numeric>. If the array is empty and initial is not passed, array_reduce() returns NULL. The callback takes two parameters. The first is the result-in-progress (or “acumulator”) value being assembled. If you supply an $initial value, the accumulator will start with this value; otherwise, it starts as NULL (so be careful). The second parameter is the current value of the array being visited. The return value of the callback will become the new value passed as the first parameter. When the array is exhausted, array_reduce() returns this accumulated value. If you were to write a PHP function that mimiced array_reduce()it might therefore look something like this (less details like error checking and so on):

<?php
 function array_reduce($array, $callback, $initial=null)
 {
     $acc = $initial;
     foreach($array as $a)
         $acc = $callback($acc, $a);
     return $acc;
 }
 ?>

This example, which adds up the squares of the values of an array, demonstrates the operation of array_reduce:

<?php
 function add_up ($running_total, $current_value) {
    if ($running_total === NULL) {
           print("add_up(NULL, $current_value)");
   } else {
         print("add_up($running_total, $current_value)");
   }

   $running_total += $current_value * $current_value;

   echo "&nbsp;&nbsp;&nbsp;&nbsp;returns&nbsp;$running_total<br />";

   return $running_total;
 }

 $numbers = array(2, 3, 5, 7);
 $total = array_reduce($numbers, 'add_up');

 print("Total = $total");// $total is now 87

The output from array_reduce() will be:

add_up(NULL, 2) returns 4 add_up(4, 3) returns 13 add_up(13, 5) returns 38 add_up(38, 7) returns 87

A second example

<?php
 function add_up($running_total, $current_value)
 {
   $running_total += $current_value;
   return $running_total;
 }

 $total = array_reduce($numbers, 'add_up', 0);
 echo "The total is $total<br />";

If the array is empty, array_reduce() returns the default value, the third parameter. If no default value is given and the array is empty, array_reduce() returns NULL. Using a class method doesn’t seem to offer much benefit (that I can see), though one can put several static methods in a class that can be reused for various ‘reductions’.

<?php
 class Reductions {
         static $initial = 0;
    public static function sum($running_total, $value)
    {
      return $running_total += $value;
      return $running_total;
    }
    public static function multi($accum, $value)
    {
            $accum *= $value;
            return $accum;
    }
    public static function multi_debug($accum, $value)
    {
            if (self::$initial == 0) {
                    self::$initial = 1;
                    echo '<table><tr><th>1st param&nbsp;</th><th>&nbsp;2nd param</th></tr>';
            }
            printf("<tr><td>%d</td><td>%2d</td></tr>", $accum, $value);
            $accum *= $value;
            return $accum;
    }
 }
 echo "<p><span  style=\"font-family: 'Courier new'\">array_reduce(\$numbers, array('Reductions', 'multi_debug'), 1)</span>
         <br />where multi() is: <span style=\"font-family: 'Courier new'\">function static Reductions::multi_debug(accum, value)</span></p>";

 $numbers = range(1, 10);
 $result = array_reduce($numbers, array("Reductions", "multi_debug"), 1);
 echo '</table>';
 echo "<p>The result is $result</p>";
 array_reduce($numbers, array('Reductions', 'multi_debug'), 1)

where multi() is: function static Reductions::multi_debug(accum, value)

1st param 2nd param 1 1 1 2 2 3 6 4 24 5 120 6 720 7 5040 8 40320 9 362880 10 The result is 3628800 You can also use a class without static methods. This will allow you to call array_reduce()without needing to set an initial value in the optional third parameter, but this offers no real extra benefit.

class Reductions2 {

private $multi_initial; private $multi_invoked;

function __construct() {

$this->multi_initial = 1; $this->multi_invoked = 0;

} public function sum($accum, $value) {

$accum += $value; return $accum;

} public function multi($accum, $value) {

// we don’t rely on $accum having been given an initial value. We will use 1.

if ($this->multi_invoked == 0) {

$this->multi_invoked = 1;

$accum = 1;

}

echo “<p>1st param = $accum. 2nd param = $value</p>”; $accum *= $value; return $accum;

}

}

echo “<p>using static member function</p>”; // 1 (or some initial value) is need; otherwise, the result will always be 0 because NULL (which is 0) is passed initially. $red2 = new Reductions2(); $result = array_reduce($numbers,array($red2, “multi”)); echo “The result is $result<br />”;

array_walk() with a class method can do what array_reduce() does:

class Multiply {

private $accum;

function __construct($init = 1) {

$this->accum = $init;

} public function multi(&$value, $key) {

$this->accum *= $value; return $this->accum;

} public function result() {

return $this->accum;

}

} $numbers = range(1, 10); $multi = new Multiply(); array_walk($numbers,array($multi, “multi”)); echo ‘The result of array_walk() is ‘.$multi->result().’<br />’; array_map() array array_map ( callback $callback , array $arr1 [, array $... ] ) array_map() returns an array containing all the elements of arr1 after applying the callback function to each one. The number of parameters that the callback function accepts should match the number of arrays passed to the array_map(). array_map() differs from array_walk() in that the callback only takes one parameter, the array value, rather than two (plus an optional third), the key and the value. array_map() is similar to the C++ algorithm for_each(). Some examples: // Create an array or cubed values (of the elements of input array) function cube($n) {     return($n  $n  $n); }

$a = array(1, 2, 3, 4, 5); $b = array_map(“cube”, $a); print_r($b); print_r($a); Array (

[0] => 1 [1] => 8 [2] => 27 [3] => 64 [4] => 125

) Array (

[0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5

)

// return a string function show_Spanish($n, $m) {     return(“The number $n is called $m in Spanish”); } // return an associative array of one key/value element function map_Spanish($n, $m) {     return(array($n => $m)); }

$a = array(1, 2, 3, 4, 5); $b = array(“uno”, “dos”, “tres”, “cuatro”, “cinco”);

$c = array_map(“show_Spanish”, $a, $b); print_r($c);

$d = array_map(“map_Spanish”, $a , $b); print_r($d); // output of $c Array (

[0] => The number 1 is called uno in Spanish [1] => The number 2 is called dos in Spanish [2] => The number 3 is called tres in Spanish [3] => The number 4 is called cuatro in Spanish [4] => The number 5 is called cinco in Spanish

) // output of $d Array (

[0] => Array
(
[1] => uno

)

[1] => Array
(
[2] => dos

)

[2] => Array
(
[3] => tres

)

[3] => Array
(
[4] => cuatro

)

[4] => Array
(
[5] => cinco

)

)

This example shows how to use a class method with array_map():

class Spanish {

public function show_Spanish($n, $m) {     return(“The number $n is called $m in Spanish”); }

}

$a = array(1, 2, 3, 4, 5); $b = array(“uno”, “dos”, “tres”, “cuatro”, “cinco”); $c = array_map(array(new Spanish(), “show_Spanish”), $a, $b);

array_filter()

array array_filter (array $input [, callback $callback ])

Iterates over each value in the input array passing them to the callback function. If the array is an associative array, the value (not the key) is passed. If the callback function returns true, the current value from input is returned into the result array. Array keys are preserved. array_filter() can be compared to the C++ remove_if() algorithm; however, remove_if() removes elements whereas array_filter()returns a new array.

Example:

function odd($var) {     return($var & 1); }

function even($var) {     return(!($var & 1)); }

$array1 = array(“a”=>1, “b”=>2, “c”=>3, “d”=>4, “e”=>5);

$array2 = array(6, 7, 8, 9, 10, 11, 12);

echo “Odd :n”; print_r(array_filter($array1, “odd”));

echo “Even:n”; print_r(array_filter($array2, “even”));

Odd : Array (

[a] => 1 [c] => 3 [e] => 5

) Even: Array (

[0] => 6 [2] => 8 [4] => 10 [6] => 12

)

Note: Be aware array_filter() preserves array indexes:

<?php function f($item) {     return $item < 50; }

print_r( array_filter(array( 10, 100, 20 ),”f”) );

Array (     [0] => 10     [2] => 20 )

Reassign numerical indexes using array_values():

print_r2(array_values(array_filter(array(10, 100, 20),”f”)));

Array([0] => 10 [1] => 20 )

You can use a class method as a callback:

class Test {

public static function odd($var) {
return($var & 1);

}

};

$array1 = array(“a”=>1, “b”=>2, “c”=>3, “d”=>4, “e”=>5); $newArray = array_filter($array1, array(“Test”, “odd”)); print_r2($newArray); array([a] => 1 [c] => 3 [e] => 5 )//output

array_fill() array array_fill ( int $start_index , int $num , mixed $value )

Fills an array with num entries of the value of the value parameter, keys starting at the start_index parameter. array_fill() is analogous to C++’s fill() algorithm, but array_fill() creates a new arrary (whereas C++’s fill()fills an existing container). Example:

$a = array_fill(5, 6, ‘banana’); $b = array_fill(-2, 2, ‘pear’); print_r($a); print_r($b);

Array (

[5] => banana [6] => banana [7] => banana [8] => banana [9] => banana [10] => banana

) Array (

[-2] => pear [0] => pear

) Searching for Values

bool in_array ( mixed $needle , array $haystack [, bool $strict ] )

Searches for $needle in array $haystack. If $strict is TRUE, then the type is also compared. For example,

$a = array(‘1.10’, 12.4, 1.13);

if (in_array(‘12.4’, $a, true)) {     echo “‘12.4’ found with strict checkn”; }

will not find ‘12.4’ in $a because it is a string type. in_array() is much faster than a loop that checks every value to find the one you want.

mixed array_search ( mixed $needle , array $haystack [, bool $strict ] )

array_search() returns the key of the element found (in_array() returns a bool). If $hatstack is a string, a case insensitive search is done. array_search() returns FALSE if $needle is not found.

If $needle is found in $haystack more than once, only the first matching key is returned. In this example, only the key of the first ‘a’ is returned.

$haystack = range(“a”, “z”); $haystack[] = ‘a’; $haystack[] = ‘b’; $result = array_search(‘a’, $haystack); echo “haystack is:<br />”; print_r2($haystack); echo “<br />result of array_search(‘a’, $haystack) is: $result”;

haystack is: Array([0] => a [1] => b [2] => c [3] => d [4] => e [5] => f [6] => g [7] => h [8] => i [9] => j [10] => k [11] => l [12] => m [13] => n [14] => o [15] => p [16] => q [17] => r [18] => s [19] => t [20] => u [21] => v [22] => w [23] => x [24] => y [25] => z [26] => a [27] => b ) result of array_search(‘a’, Array) is: 0

In this example we search for an array (within the haystack):

$haystack = range(“a”, “z”); $search = range(“a”, “d”); $haystack[] = $search; // append an inner array $result = array_search($search, $haystack);

echo “haystack is:<br />”; print_r2($haystack); echo “<br />search is:<br />”; print_r2($search);

echo “<br />The result of array_search($search, $haystack) is: $result”;

$haystack = range(“a”, “z”); $search = range(“a”, “d”); $haystack[] = $search;

$result = array_search($search, $haystack);

echo “haystack is:<br />”; print_r2($haystack); echo “<br />search is:<br />”; print_r2($search); echo “<br />The result of array_search($search, $haystack) is: $result”;

Array([0] => a [1] => b [2] => c [3] => d [4] => e [5] => f [6] => g [7] => h [8] => i [9] => j [10] => k [11] => l [12] => m [13] => n [14] => o [15] => p [16] => q [17] => r [18] => s [19] => t [20] => u [21] => v [22] => w [23] => x [24] => y [25] => z [26] => Array([0] => a [1] => b [2] => c [3] => d ) ) search is: Array([0] => a [1] => b [2] => c [3] => d ) The result of array_search($search, $haystack) is: 26

This example searches an associative array: <?php $a=array(“a”=>”5”,”b”=>5,”c”=>”5”); echo array_search(5,$a,true); ?> b // output

To search for all occurances of $needle in $haystack, use array_keys(), specifying the second, optional parameter of a search values:

$array = array(“blue”, “red”, “green”, “blue”, “blue”); print_r(array_keys($array, “blue”)); // This will return the keys of all occurances of “blue” in $array Array (

[0] => 0 [1] => 3 [2] => 4

)

If the third parameter $strict is set to TRUE then the array_search() function will also check the types of the $needle in the $haystack.

$array = array(0 => ‘blue’, 1 => ‘red’, 2 => ‘green’, 3 => ‘red’);

$key = array_search(‘green’, $array); // $key = 2; $key = array_search(‘red’, $array);   // $key = 1;

array_keys() returns an array of all the keys in input. Example of array_keys() with and without search criteria:

$array = array(0 => 100, “color” => “red”);

print_r2(array_keys($array)); // no search criteria echo ‘<br />’;

$array = array(“blue”, “red”, “green”, “blue”, “blue”); print_r2(array_keys($array, “blue”)); // search criteria

Array([0] => 0 [1] => color ) Array([0] => 0 [1] => 3 [2] => 4 )

Sorting

Sorting changes the internal order of elements in an array and optionally rewrites the keys to reflect this new order. For example, you might use sorting to arrange a list of scores from biggest to smallest, to alphabetize a list of names, or to order a set of users based on how many messages they posted.

PHP provides three ways to sort arrays—sorting by keys, sorting by values without changing the keys, or sorting by values and then changing the keys. Each kind of sort can be done in ascending order, descending order, or an order defined by a user-defined function.

The functions provided by PHP to sort an array are:

Effect Ascending Descending User-defined order Sort array by values, then reassign indexes starting with 0 sort() rsort() usort() Sort array by values asort() arsort() uasort() Sort array by keys ksort() krsort() uksort()

The sort(), rsort(), and usort() functions are designed to work on numerically indexed arrays, because they assign new numeric keys to represent the ordering. They’re useful when you need to answer questions like “what are the top 10 scores?” and “who’s the third person in alphabetical order?” The other sort functions can be used on indexed arrays, but you’ll only be able to access the sorted ordering by using traversal functions such as foreach and next().

To sort names into ascending alphabetical order, you’d use this:

$names = array(‘cath’, ‘angela’, ‘brad’, ‘dave’); echo ‘$names before sort($names) <br />‘.$names.’<br />’; sort($names); echo ‘$names after sort($names) <br />‘.$names.’<br />’;

$names before sort($names) Array([0] => cath [1] => angela [2] => brad [3] => dave ) $names after sort($names) Array([0] => angela [1] => brad [2] => cath [3] => dave )

To get them in reverse, descending alphabetic order, simply call rsort() instead of sort().

If you have an associative array, use arsort(). Here the associative array $logins maps usernames to minutes logged on.

$logins2 = $logins = array(‘njt’ => 415,

‘kt’ => 492, ‘rl’ => 652, ‘jht’ => 441, ‘jj’ => 441,

‘wt’ => 402);

echo ‘<p>Before ksort() of ‘; print_r2($logins2);

echo ‘<p>After ksort() = ‘; ksort($logins2); print_r2($logins2); $logins = Array([njt] => 415 [kt] => 492 [rl] => 652 [jht] => 441 [jj] => 441 [wt] => 402 ) arsort($logins) = Array([rl] => 652 [kt] => 492 [jj] => 441 [jht] => 441 [njt] => 415 [wt] => 402 ) If you want that table displayed in ascending order by username, use ksort(), to sort on the keys:

ksort($logins); // sorts based on the key

echo(“<table>n”); foreach ($logins as $user => $time) {

echo(“<tr><td>$user</td><td>$time</td></tr>n”);

} echo(“</table>n”);

<table> <tr><td>jht</td><td>441</td></tr> <tr><td>jj</td><td>441</td></tr> <tr><td>kt</td><td>492</td></tr> <tr><td>njt</td><td>415</td></tr> <tr><td>rl</td><td>652</td></tr> <tr><td>wt</td><td>402</td></tr> </table>

User-defined ordering requires that you provide a function that takes two values and returns a value that specifies the order of the two values in the sorted array. The function should return 1 if the first value is greater than the second, -1 if the first value is less than the second, and 0 if the values are the same for the purposes of your custom sort order.

This example is a program that lets you try the various sorting functions on the same data.

Here is code that creates a html form that allows you demo the various sorts.

<?php require_once ‘HTML/QuickForm. <?php’; include “print_array. <?php”; // Using HTML_QuickFor

function user_sort($a, $b) {

//Simply do a case insensitive compare return strcasecmp($a, $b);

}

$selections = array(‘sort’, ‘rsort’, ‘usort’, ‘asort’, ‘arsort’, ‘uasort’, ‘ksort’, ‘uksort’);

$assoarray = array(“i”=>”tom”, “b”=>”anne”, “c”=>”DAVE”, “e”=>”Dave”, “d”=>”fred”, “k”=>”silvia”, “g”=>”kelly”, “j”=>”Kelly”,
“a”=>”dave”, “h”=>”chris”, “f”=>”vivian”);

$other = array(“tom”, “anne”, “DAVE”, “Dave”, “fred”, “silvia”, “kelly”, “Kelly”, “dave”, “chris”, “vivian”);

try {
// create a text field of size 40 that is required

$form = new HTML_QuickForm();

$select =& $form->addElement(‘select’, ‘sortTest’, ‘Test sort:’, $selections);

$select->setSize(8);

$form->addElement(‘submit’, null, ‘Submit’);

if ($form->validate()) {

// Form is validated, then processes the data $form->freeze();

// Returns all values in an associative array $data = $form->exportValues();

$index = $data[“sortTest”];

$sort = $selections[$index];

$ar = ($index > 2) ? $assoarray : $other;

echo “<p>The array before doing ”.$sort.”() is </p>”;

print_r2($ar);

if ($index == 2 || $index == 5) {

$sort($ar, “user_sort”);

} else {

$sort($ar);

}

echo “<p>The array after doing ”.$sort.”() is </p>”;

print_r2($ar);

} else {

echo “<h2>PHP sort demo</h2>”; echo “<p>For asort(), arsort(), uasort(), ksort() and uksort() this array will be sorted:</p>”;

print_r2($assoarray);

echo “<p>For sort(), rsort() and usort() this array will be sorted:</p>”;

print_r2($other);

$form->display();

}

}

catch(Exception $e) {

echo ‘Message: ‘ .$e->getMessage().”<br />”; exit();

} Natural-Order Sorting PHP’s built-in sort functions correctly sort strings and numbers, but they don’t correctly sort strings that contain numbers. For example, if you have the filenames ex10. <?php, ex5. <?php, and ex1. <?php, the normal sort functions will rearrange them in this order: ex1. <?php, ex10. <?php, ex5. <?php. To correctly sort strings that contain numbers, use the natsort() and natcasesort() functions: $output = natsort(input); $output = natcasesort(input); Sorting Multiple Arrays at Once bool array_multisort(array1 [, array2, ... ]); array_multisort()sorts multiple indexed arrays at once, or a multi-dimensional array by one or more dimensions. Associative keys will be maintained, but numeric keys wil be re-indexed. We pass it a series of arrays and sorting orders (identified by the SORT_ASC or SORT_DESC constants), and it reorders the elements of all the arrays, assigning new indexes. It is similar to a join operation on a relational database. Imagine that you have a lot of people, and several pieces of data on each person: $names = array(‘Tom’, ‘Dick’, ‘Harriet’, ‘Brenda’, ‘Joe’); $ages = array(25, 35, 29, 35, 35); $zips = array(80522, ‘02140’, 90210, 64141, 80522); The first element of each array represents a single record—all the information known about Tom. Similarly, the second element constitutes another record—all the information known about Dick. The array_multisort() function reorders the elements of the arrays, preserving the records. That is, if Dick ends up first in the $names array after the sort, the rest of Dick’s information will be first in the other arrays too. (Note that we needed to quote Dick’s zip code to prevent it from being interpreted as an octal constant.) Here’s how to sort the records first ascending by age, then descending by zip code, and lastly by ascending names: array_multisort($ages, SORT_ASC, $zips, SORT_DESC, $names, SORT_ASC); We need to include $names in the function call to ensure that Dick’s name stays with his age and zip code. Printing out the data shows the result of the sort: $names = array(‘Tom’, ‘Dick’, ‘Harriet’, ‘Brenda’, ‘Joe’, ‘Amy’); $ages = array(25, 35, 29, 35, 35, 35 ); $zips = array(80522, ‘02140’, 90210, 64141, 80522, 64141);

function display($ages, $zips, $names) { for ($i = 0; $i < count($ages); $i++) {

echo “<tr><td>$ages[$i]</td><td>$zips[$i]</td><td>$names[$i]</td></tr>”;

echo “<p>Before array_multi_sort():</p><p><table>”;

display($ages, $zips, $names);

echo “</table></p><p>Doing array_multisort($ages, SORT_ASC, $zips, SORT_DESC, $names, SORT_ASC)...</p>”; echo “<p>We sort first by age, then (within age) by zip code (with higher zip codes coming first), and lastly we sort by name in ascending order</p>”;

array_multisort($ages, SORT_ASC, $zips, SORT_DESC, $names, SORT_ASC);

echo “<table>”; display($ages, $zips, $names); echo “</table>”;

<table> <tr><td>25</td><td>80522</td><td>Tom</td> <tr><td>29</td><td>90210</td><td>Harriet</td> <tr><td>35</td><td>80522</td><td>Joe</td> <tr><td>35</td><td>64141</td><td>Amy</td> <tr><td>35</td><td>64141</td><td>Brenda</td> <tr><td>35</td><td>02140</td><td>Dick</td> </table>

Since two individuals are both 35 years old, the individual with the numerically larger zip code is displayed first. Since there are two such individuals, Amy is displayed first because we sort names in ascending order. Reversing Arrays

$result = array_reverse(array $a) [, bool $preserve_keys ] ) takes an input array and returns a new array with the order of the elements reversed. Example: $ar = range(1, 20, 3); echo “array to reverse is ”; print_r2($ar); echo “<br />output of array_reverse()</br>”; $reversed = array_reverse($ar); print_r2($reversed); array to reverse is: Array([0] => 1 [1] => 4 [2] => 7 [3] => 10 [4] => 13 [5] => 16 [6] => 19 ) output of array_reverse(): Array([0] => 19 [1] => 16 [2] => 13 [3] => 10 [4] => 7 [5] => 4 [6] => 1 ) Numeric keys are renumbered starting at 0, while string indexes are unaffected. In general, it’s better to use the reverse-order sorting functions instead of sorting and then reversing the order of an array. The array_flip() function returns an array that reverses the order of each original element’s key-value pair: $flipped = array_flip(array); That is, for each element of the array whose value is a valid key, the element’s value becomes its key and the element’s key becomes its value. For example, if you have an array mapping usernames to home directories, you can use array_flip() to create an array mapping home directories to usernames: $u2h = array(‘gnat’ => ‘/home/staff/nathan’,

‘rasmus’ => ‘/home/elite/rasmus’, ‘ktatroe’ => ‘/home/staff/kevin’);

$h2u = array_flip($u2h); $user = $h2u[‘/home/staff/kevin’]; // $user is now ‘ktatroe’ Elements whose original values are neither strings nor integers are left alone in the resulting array. The new array lets you discover the key in the original array given its value, but this technique works effectively only when the original array has unique values. In this example, after sorting, the first array will transform to “10”, 100, 100, 11, “a” (it was sorted as strings in ascending order). The second will contain 1, 3, “2”, 2, 1 (sorted as numbers, in descending order). $ar = array(        array(“10”, 11, 100, 100, “a”),        array(   1,  2, “2”,   3,   1)       );

array_multisort($ar[0], SORT_ASC, SORT_STRING,                 $ar[1], SORT_NUMERIC, SORT_DESC); var_dump($ar);

array(2) {
[0]=> array(5) {
[0]=> string(2) “10” [1]=> int(100) [2]=> int(100) [3]=> int(11) [4]=> string(1) “a”

} [1]=> array(5) {

[0]=> int(1) [1]=> int(3) [2]=> string(1) “2” [3]=> int(2) [4]=> int(1)

}

} Randomizing Order To traverse the elements in an array in a random order, use the shuffle( ) function. All existing keys, whether string or numeric, are replaced with consecutive integers starting at 0. Here’s how to randomize the order of the days of the week: $days = array(‘Monday’, ‘Tuesday’, ‘Wednesday’,

‘Thursday’, ‘Friday’, ‘Saturday’, ‘Sunday’);

shuffle($days);

print_r($days); Array (

[0] => Tuesday [1] => Thursday [2] => Monday [3] => Friday [4] => Wednesday [5] => Saturday [6] => Sunday

) Obviously, the order after your shuffle() may not be the same as the sample output here. Unless you are interested in getting multiple random elements from an array, without repeating any specific item, using the rand() function to pick an index is more efficient. Acting on Entire Arrays PHP has several useful functions for modifying or applying an operation to all elements of an array. You can merge arrays, find the difference, calculate the total, and more, all using built-in functions. Calculating the Sum of an Array The array_sum( ) function adds up the values in an indexed or associative array: $sum = array_sum(array); For example: $scores = array(98, 76, 56, 80); $total = array_sum($scores); // $total = 310

Calculating the Product of an Array

The array_product() returns the product of the values of an array as either an integer or float. This function can be used to test if all values in an array of booleans are TRUE:

<?php

function outbool($test) {     return (bool) $test; }

$check[] = outbool(TRUE); $check[] = outbool(1); $check[] = outbool(FALSE); $check[] = outbool(0);

$result = (bool) array_product($check); // $result is set to FALSE because only two of the four values evaluated to TRUE

?>

The above is equivalent to:

<?php

$check1 = outbool(TRUE); $check2 = outbool(1); $check3 = outbool(FALSE); $check4 = outbool(0);

$result = ($check1 && $check2 && $check3 && $check4);

?>

And array_product() obviously lends itself for factorials:

<?php $ar = range(1,5); $r = array_product($ar); ?> Merging Two Arrays The array_merge( ) function intelligently merges two or more arrays. The values of one are appended to the end of the previous one. It returns the resulting array. $merged = array_merge(array1, array2 [, array ... ]) If a numeric key from an earlier array is repeated, the value from the later array is assigned a new numeric key: $first = array(‘hello’, ‘world’); // 0 => ‘hello’, 1 => ‘world’ $second = array(‘exit’, ‘here’); // 0 => ‘exit’, 1 => ‘here’ $merged = array_merge($first, $second); // $merged = array(‘hello’, ‘world’, ‘exit’, ‘here’) If a string key from an earlier array is repeated, the earlier value is replaced by the later value: $first = array(‘bill’ => ‘clinton’, ‘tony’ => ‘danza’); $second = array(‘bill’ => ‘gates’, ‘adam’ => ‘west’); $merged = array_merge($first, $second); // $merged = array(‘bill’ => ‘gates’, ‘tony’ => ‘danza’, ‘adam’ => ‘west’)

This example merges numeric and string index arrays:

$array1 = array(“color” => “red”, 2, 4); $array2 = array(“a”, “b”, “color” => “green”, “shape” => “trapezoid”, 4); $result = array_merge($array1, $array2); print_r($result); Array (

[color] => green [0] => 2 [1] => 4 [2] => a [3] => b [shape] => trapezoid [4] => 4

)

Calculating the Difference Between Two Arrays The array_diff() function identifies values from one array (the first paramater) that are not present in others (the subsequent parameters): $diff = array_diff(array1, array2 [, array ... ]); For example: $a1 = array(‘bill’, ‘claire’, ‘elle’, ‘simon’, ‘judy’); $a2 = array(‘jack’, ‘claire’, ‘toni’); $a3 = array(‘elle’, ‘simon’, ‘garfunkel’);

// find values of $a1 not in $a2 or $a3 $diff = array_diff($a1, $a2, $a3);

// $diff is array(‘bill’, ‘judy’); Values are compared using ===, so 1 and “1” are considered different. The keys of the first array are preserved, so in $diff the key of ‘bill’ is 0 and the key of ‘judy’ is 4. In PHP 5 array_udiff() was added. It computes the difference of arrays by using a callback function for data comparison. The callback must return an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second. Example: class cr {     private $priv_member;     function cr($val)     {         $this->priv_member = $val;     }

    static function comp_func_cr($a, $b)     {         if ($a->priv_member === $b->priv_member) return 0;

        return ($a->priv_member > $b->priv_member) ? 1 : -1;     } } $a = array(“0.1” => new cr(9), “0.5” => new cr(12), 0 => new cr(23), 1=> new cr(4), 2 => new cr(-15),); $b = array(“0.2” => new cr(9), “0.5” => new cr(22), 0 => new cr(3), 1=> new cr(4), 2 => new cr(-15),);

$result = array_udiff($a, $b, array(“cr”, “comp_func_cr”)); print_r($result); Array (

[0.5] => cr Object
(
[priv_member:private] => 12

)

[0] => cr Object
(
[priv_member:private] => 23

)

)

Filtering Elements from an Array To identify a subset of an array based on its values, use the array_filter() function: $filtered = array_filter(array, callback);

array_filter(array, callback) is analogous to the C++ standard library function remove_if(). Each value of array is passed to the function named in callback. The returned array contains only those elements of the original array for which the function returns a true value. For example: function is_odd ($element) {

return $element % 2;

}

$numbers = array(9, 23, 24, 27);

$odds = array_filter($numbers, ‘is_odd’);

// $odds is array(0 => 9, 1 => 23, 3 => 27)

An alternate to the above code is:

function odd($var) {     return($var & 1); }

function even($var) {     return(!($var & 1)); }

$array1 = array(“a”=>1, “b”=>2, “c”=>3, “d”=>4, “e”=>5); $array2 = array(6, 7, 8, 9, 10, 11, 12);

echo “Odd :n”; print_r(array_filter($array1, “odd”));

echo “Even:n”; print_r(array_filter($array2, “even”)); Odd : Array (

[a] => 1 [c] => 3 [e] => 5

) Even: Array (

[0] => 6 [2] => 8 [4] => 10 [6] => 12

) As you see, the keys are preserved. This function is most useful with associative arrays. Using Arrays Arrays crop up in almost every PHP program. In addition to their obvious use for storing collections of values, they’re also used to implement various abstract data types. In this section, we show how to use arrays to implement sets and stacks. Sets Arrays let you implement the basic operations of set theory: union, intersection, and difference. Each set is represented by an array, and various PHP functions implement the set operations. The values in the set are the values in the array—the keys are not used, but they are generally preserved by the operations. The union of two sets is all the elements from both sets, with duplicates removed. The array_merge() and array_unique() functions let you calculate the union. Here’s how to find the union of two arrays: function array_union($a, $b) {

$union = array_merge($a, $b); // duplicates may still exist $union = array_unique($union); return $union;

}

$first = array(1, ‘two’, 3); $second = array(‘two’, ‘three’, ‘four’); $union = array_union($first, $second); print_r($union);

Array (

[0] => 1 [1] => two [2] => 3 [4] => three [5] => four

) The intersection of two (or more) sets (arrays) is the set of elements they have in common. It is analogous to the C++ set_intersection() functiion. PHP’s built-in array_intersect( ) function takes any number of arrays as arguments and returns an array of those values that exist in each. If multiple keys have the same value, the first key with that value is preserved. Example: $array1 = array(“a” => “green”, “red”, “blue”); $array2 = array(“b” => “green”, “yellow”, “red”); $result = array_intersect($array1, $array2); print_r($result); Array (

[a] => green [0] => red

) Another common function to perform on a set of arrays is to get the difference: the values in one array that are not present in another array. The array_diff() function returns an array containing all the entries from array1 that are not present in any of the other arrays. It is analogous to C++ algorithm set_difference(). The following code takes the difference of two arrays: $first = array(1, ‘two’, 3); $second = array(‘two’, ‘three’, ‘four’);

$difference = array_diff($first, $second); print_r($difference);

Array (

[0] => 1 [2] => 3

)

Example two:

$array1 = array(“a” => “green”, “red”, “blue”, “red”); $array2 = array(“b” => “green”, “yellow”, “red”);

$result = array_diff($array1, $array2);

print_r($result);

Array (

[1] => blue

) More specialized versions of the difference and intersection functions

In addition to array_diff() and array_interset(), there are versions of these functions that 1.) compare both the key and the value (this is more applicable to string-indexed arrays). 2.) compare only keys 3.) use a callbacks to do the comparison The functions array_diff_assoc() and array_intersect_assoc()use both the key and the value in the comparison. For example, $array1 = array(“a” => “green”, “b” => “brown”, “c” => “blue”, “red”); $array2 = array(“a” => “green”, “yellow”, “red”); $result_array = array_intersect_assoc($array1, $array2); // both values and keys must be identical print_r($result_array); Array (

[a] => green

)

The value “red” was not returned because in $array1 its key is 0 while the key of “red” in $array2 is 1. The two values from the key => value pairs are considered equal only if (string) $elem1 === (string) $elem2 . In other words a strict type check is executed so the string representation must be the same. Example of array_diff_assoc(): $array1 = array(“a” => “green”, “b” => “brown”, “c” => “blue”, “red”); $array2 = array(“a” => “green”, “yellow”, “red”); $result = array_diff_assoc($array1, $array2); print_r($result); Array (

[b] => brown [c] => blue [0] => red

) Like array_intersect_assoc()two key => value pairs are considered equal only if (string) $elem1 === (string) $elem2 . In other words a strict check takes place so the string representations must be the same. The pair 0 => “red” is in the ouput because in the second argument “red” has key which is 1 but its is 0 in the first argument. The functions array_diff_key() and array_assoc_key()use the key and not its value in the comparison. Two keys are considered equal only if (string) $key1 === (string) $key2. For each version of the difference and intersection functions, there is a callback version. For the assoc version there are two callback versions. These tables summarizes this. Difference functions array_diff() (string) $value1 === (string) $value2 array_diff_assoc() (string) $key1 === (string) $key2 && (string) $value1 === (string) $value2 array_diff_key() (string) $key1 === (string) $key2

Difference function that use callbacks array_udiff()

callback($value1, $value2)
array_udiff_assoc()
callback($value1, $value2) && (string) $value1 === (string) $value2
array_udiff_uassoc()
callback($key1, $key2) && callback($value1, $value2)
array_diff_ukey()
callback($key1, $key2)

Intersection functions array_intersect() (string) $value1 === (string) $value2 array_intersect_assoc() (string) $key1 === (string) $key2 && (string) $value1 === (string) $value2 array_intersect_key() (string) $key1 === (string) $key2

Intersection functions that use callbacks array_uintersect()

callback($value1, $value2)
array_uintersect_assoc()
callback($value1, $value2) && (string) $value1 === (string) $value2
array_uintersect_uassoc()
callback($key1, $key2) && callback($value1, $value2)
array_intersect_ukey()
callback($key1, $key2)

The callback function must return an integer either less than zero, zero, or greater than zero, indicating whether the first argument is, respectively, less than, equal to, or greater than the second. These examples illustrate the use of the callback versions of the intersection functions. The callback will do a case insensitive comparison. $array1 = array(“a” => “green”, “b” => “brown”, “c” => “blue”, “red”); $array2 = array(“a” => “GREEN”, “B” => “brown”, “yellow”, “red”);

print_r(array_uintersect($array1, $array2, “strcasecmp”)); Array (

[a] => green [b] => brown [0] => red

)

Next we use array_uintersect_assoc() $array1 = array(“a” => “green”, “b” => “brown”, “c” => “blue”, “red”); $array2 = array(“a” => “GREEN”, “B” => “brown”, “yellow”, “red”);

print_r(array_uintersect_assoc($array1, $array2, “strcasecmp”, “strcasecmp”)); Array (

[a] => green

)

Next we use array_uintersect_uassoc() $array1 = array(“a” => “green”, “b” => “brown”, “c” => “blue”, “red”); $array2 = array(“a” => “GREEN”, “B” => “brown”, “yellow”, “red”);

print_r(array_uintersect_uassoc($array1, $array2, “strcasecmp”)); Array (

[a] => green [b] => brown

)

The difference callback version function the same way. Stacks Although not as common in PHP programs as in other programs, one fairly common data type is the last-in first-out (LIFO) stack. We can create stacks using a pair of PHP functions, array_push() and array_pop(). array_push()treats array as a stack, and pushes the passed variables onto the end of array . The length of array increases by the number of variables pushed. It has the same effect as: <?php $array[] = $var; ?> repeated for each var. Example of array_push(): $stack = array(“orange”, “banana”); array_push($stack, “apple”, “raspberry”); print_r($stack); Array (

[0] => orange [1] => banana [2] => apple [3] => raspberry

) array_pop() pops and returns the last value of the array, shortening the array by one element. If array is empty (or is not an array), NULL will be returned. It will produce a warning when called on a non-array. Note: This function will reset()the array pointer after use. $stack = array(“orange”, “banana”, “apple”, “raspberry”); $fruit = array_pop($stack); echo $fruit.’<br />’; print_r($stack); raspberry Array (

[0] => orange [1] => banana [2] => apple

) Using array_push() and array_pop() makes it clear that we’re working with stacks. If you only want to add one element to the end of an array, $arr[] = $var is much faster than calling array_push(). Stacks are particularly useful for maintaining state. This example provides a simple state debugger that allows you to print out a list of which functions have been called up to this point (i.e., the stack trace). Example: State debugger $call_trace = array();

function enter_function($name) {

global $call_trace;

array_push($call_trace, $name); // same as $call_trace[] = $name

echo “Entering $name (stack is now: ” . join(‘ -> ‘, $call_trace) . ‘)<br />’;

}

function exit_function( ) {

echo ‘Exiting<br />’;

global $call_trace;

array_pop($call_trace); // we ignore array_pop()’s return value

}

function first( ) {

enter_function(‘first’); exit_function();

}

function second() {
enter_function(‘second’);
first( );

exit_function( );

}

function third() {
enter_function(‘third’);
second( ); first( );

exit_function( );

}

first(); third(); Here’s the output from the Example: Entering first (stack is now: first) Exiting Entering third (stack is now: third) Entering second (stack is now: third -> second) Entering first (stack is now: third -> second -> first) Exiting Exiting Entering first (stack is now: third -> first) Exiting Exiting The functions array_shift() and array_unshift() treat an array like a queue. Thus, array_shift() shifts the first value of the array off and returns it (or NULL if array is empty or is not an array), shortening the array by one element and moving everything down. All numerical array keys will be modified to start counting from zero while literal keys won’t be touched. array_shift()will reset() the array pointer after use. $queue = array(“orange”, “banana”, “apple”, “raspberry”); $fruit = array_shift($queue); echo $stack.’<br />’; print_r($queue); orange Array (

[0] => banana [1] => apple [2] => raspberry

) int array_unshift (array &$array , mixed $var [, mixed $... ] ) prepends elements to the front of the array. The list of elements is prepended as a whole, so the elements stay in the same order. All numerical array keys will be modified to start counting from zero while literal keys won’t be touched. array_unshift()returns the new number of elements in the array. Example: $queue = array(“orange”, “banana”); $count = array_unshift($queue, “apple”, “raspberry”); print_r($queue); echo $count.’<br />’; 4 Array (

[0] => apple [1] => raspberry [2] => orange [3] => banana

)

To do: Complete the additional array difference and intersection functions PHP has a Standard Library: http://www. <?php.net/manual/en/book.spl. <?php and http://www. <?phpbuilder.com/columns/bosanac20030225. <?php3 http://www.alternateinterior.com/2007/01/recursive-data-structures-in- <?php.html

http://www.devshed.com/c/a/PHP/Iterators-in-the-Simplest-Sense-Traversing-Different-Data-Structures/1/

array_slice versus array_splice

A: array_slice returns a segment of the input array, which it does not alter. array_splice is used to remove a segment and replace it will something else, or simply to insert or remove a segment. Examples:

<?php
$i6 = $i5 = $i4 = $i3 = $i2 = $i1 = $input;

array_splice($i1, 2, 2); // removes "law" and "math"
print_r($i1);

array_splice($i2, 2);    // leaves "chem", "biology"
print_r($i2);

// Negative values indicate "from (or up to) the end"
// Remove from offset 1 up to (but not including) last element, -1
array_splice($i3, 1, -1); // leaves "chem", "physics"
print_r($i3);

// Remove starting at last element and moving toward front, removing 1 total elements
array_splice($i4, -1, 1); // removes "physics"
print_r($i4);

// To replace a segment
array_splice($i5, 2, 2, array("English", "art")); // replaces "law", "math" with "English", "art"
print_r($i5);

// To insert the segment, use 0 for removal
array_splice($i6, 2, 0, array("English", "art"));
print_r($i6);