• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • array_shift()

    (PHP 4, PHP 5, PHP 7)

    将数组开头的单元移出数组

    说明

    array_shift(array &$array): mixed

    array_shift()$array的第一个单元移出并作为结果返回,将$array的长度减一并将所有其它单元向前移动一位。所有的数字键名将改为从零开始计数,文字键名将不变。

    Note:使用此函数后会重置(reset())array指针。

    参数

    $array

    输入的数组。

    返回值

    返回移出的值,如果$array为空或不是一个数组则返回NULL

    范例

    Example #1array_shift()例子

    <?php
    $stack = array("orange", "banana", "apple", "raspberry");
    $fruit = array_shift($stack);
    print_r($stack);
    ?>
    

    以上例程会输出:

    Array
    (
        [0] => banana
        [1] => apple
        [2] => raspberry
    )
    

    并且orange被赋给了$fruit

    参见

    Using array_shift over larger array was fairly slow. It sped up as the array shrank, most likely as it has to reindex a smaller data set.
    For my purpose, I used array_reverse, then array_pop, which doesn't need to reindex the array and will preserve keys if you want it to (didn't matter in my case). 
    Using direct index references, i.e., array_test[$i], was fast, but direct index referencing + unset for destructive operations was about the same speed as array_reverse and array_pop. It also requires sequential numeric keys.
    Notice:
    the complexity of array_pop() is O(1). 
    the complexity of array_shift() is O(n).
    array_shift() requires a re-index process on the array, so it has to run over all the elements and index them.
    Just a useful version which returns a simple array with the first key and value. Porbably a better way of doing it, but it works for me ;-)
    <?php
    function array_kshift(&$arr)
    {
     list($k) = array_keys($arr);
     $r = array($k=>$arr[$k]);
     unset($arr[$k]);
     return $r;
    }
    // test it on a simple associative array
    $arr = array('x'=>'ball','y'=>'hat','z'=>'apple');
    print_r($arr);
    print_r(array_kshift($arr));
    print_r($arr);
    ?>
    Output:
    Array
    (
      [x] => ball
      [y] => hat
      [z] => apple
    )
    Array
    (
      [x] => ball
    )
    Array
    (
      [y] => hat
      [z] => apple
    )
    Here is a little function if you would like to get the top element and rotate the array afterwards.
    function array_rotate(&$arr)
    {
     $elm = array_shift($arr);
     array_push($arr, $elm);
     return $elm;
    }
    <?php
    //----------------------------------------------------------
    // The combination of array_shift/array_unshift 
    // greatly simplified a function I created for 
    // generating relative paths. Before I found them 
    // the algorithm was really squirrely, with multiple 
    // if tests, length calculations, nested loops, etc. 
    // Great functions.
    //----------------------------------------------------------
    function create_relative_path($inSourcePath, $inRefPath)
    {
      // break strings at slashes
      $s_parts      = explode('/', $inSourcePath);
      $r_parts      = explode('/', $inRefPath);
      
      // delete items up to the first non-equal part
      while ($s_parts[0] === $r_parts[0])
      {
        array_shift($s_parts);
        array_shift($r_parts);
      }
      
      // add wild card to r_parts for each remaining 
      // item of s_parts
      while ($s_parts[0])
      {
        array_unshift($r_parts, '..');
        array_shift($s_parts);
      }
      
      return implode('/', $r_parts);
    }
    //----------------------------------------------------------
    // Example:
    //   Given a source path $sp generates the relative 
    //   location of $rp. $sp could be assigned using 
    //   $_SERVER['PHP_SELF'] but it's hardcoded for 
    //   the example.
    //----------------------------------------------------------
    $sp = '/WebServer/Documents/MyBigProject/php/project_script.php';
    $rp = '/WebServer/Documents/MyLibraries/lib_script.php';
    // plugging them into the function
    $rel_path = create_relative_path($sp, $rp);
    // yeilds
    '../../../MyLibraries/lib_script.php'
    // and it could be used like
    include_once(create_relative_path($_SERVER['PHP_SELF'], $rp));
    This function will save the key values of an array, and it will work in lower versions of PHP:
    <?php
    function array_shift2(&$array){
      reset($array);
      $key = key($array);
      $removed = $array[$key];
      unset($array[$key]);
      return $removed;
    }
    ?>
    
    If you want to loop through an array, removing its values one at a time using array_shift() but also want the key as well, try this. 
    <?php
    while($key = key($array))
    {
       $value = array_shift($array);
       //code goes here
    }
    ?>
    its like foreach but each time the value is removed from the array so it eventually ends up empty
    <?php
    //example below
    $airports = array
    (
      "LGW" => "London Gatwick",
      "LHR" => "London Heathrow",
      "STN" => "London Stanstead"
    );
    echo count($airports)." Airport in the array<br /><br />";
    while($key = key($airports))
    {
      $value = array_shift($airports);
      echo $key." is ".$value."<br />";
    }
    echo "<br />".count($airports)." Airport left in the array";
    ?>
    Example Outputs:
    3 Airport in the array
    LGW is London Gatwick
    LHR is London Heathrow
    STN is London Stanstead
    0 Airport left in the array
    This removeAdd function, the first argument shift your array then unshif the second argument to your array. first argument is an array and second argument can be int or str.
    <?php
    function removeAdd ($arr, $newer){
      $a = array_shift($arr);
      $b = array_unshift($arr, $newer);
      foreach ($arr as $value){
        echo $value."<br />";
      }
    }
    $a = array(1,2,3,4,5,6);
    foreach ($a as $current){
      echo $current."<br />";
    }
    echo "<hr />";
    removeAdd($a, 0);
    ?>
    OUTPUT:
    1
    2
    3
    4
    5
    6
    _______
    0
    2
    3
    4
    5
    6
    while(array_shift()) can be used to process multiple arrays and/or database results in a single loop. The || short circuts and only evaluates the first statement until it runs out of data.
    It can help to reduce duplicated code (the rule is code once and once only).
    Note that each ($row = ) statement much be encased in ()'s otherwise you will get funny results. If you use two array_shift($array) statements and forget the ()'s, you will repeatedly get the first element of the first array for the for the count of the $array.
    <?php
    require_once('class.db.php');
    $sql = "SELECT title FROM links";
    $result = mysql_query($sql, $db->connection);
    $defaults = array(
       array('title' => 'None'), 
       array('title' => 'Unknown')
    );
    while ( ($row = mysql_fetch_assoc($result)) 
       || ($row = array_shift($defaults))) 
    {
     echo $row['title'] . "<br>";
    }
    ?>
    This will print out (depending on database contents):
    Title1
    Title2
    Title3
    ...
    None
    Unknown
    For those that may be trying to use array_shift() with an array containing references (e.g. working with linked node trees), beware that array_shift() may not work as you expect: it will return a *copy* of the first element of the array, and not the element itself, so your reference will be lost.
    The solution is to reference the first element before removing it with array_shift():
    <?php
    // using only array_shift:
    $a = 1;
    $array = array(&$a);
    $b =& array_shift($array);
    $b = 2;
    echo "a = $a, b = $b<br>"; // outputs a = 1, b = 2
    // solution: referencing the first element first:
    $a = 1;
    $array = array(&$a);
    $b =& $array[0];
    array_shift($array);
    $b = 2;
    echo "a = $a, b = $b<br>"; // outputs a = 2, b = 2
    ?>
    
    Im using this function to browse arrays from database. For example data:
    <?php
    $data = array(
       array('row 1-cell 1','row 1-cell 2'),
       array('row 2-cell 1','row 2-cell 2'),
       array('row 3-cell 1','row 3-cell 2'),
    );
    while($row=array_shift($data)) {
       echo $row[0];
    }
    ?>
    Output:
    row 1-cell 1
    row 2-cell 1
    row 3-cell 1
    As pointed out earlier, in PHP4, array_shift() modifies the input array by-reference, but it doesn't return the first element by reference. This may seem like very unexpected behaviour. If you're working with a collection of references (in my case XML Nodes) this should do the trick.
    <?php
    /**
     * This function exhibits the same behaviour is array_shift(), except
     * it returns a reference to the first element of the array instead of a copy.
     *
     * @param array &$array
     * @return mixed
     */
    function &array_shift_reference(&$array)
    {
     if (count($array) > 0)
     {
      $key = key($array);
      $first =& $array[$key];
     }
     else
     {
      $first = null;
     }
     array_shift($array);
     return $first;
    }
    class ArrayShiftReferenceTest extends UnitTestCase
    {
      
     function testFunctionRemovesFirstElementOfNumericallyIndexedArray()
     {
      $input = array('foo', 'bar');
      array_shift_reference($input);
      $this->assertEqual(array('bar'), $input, '%s: The array should be shifted one element left');
     }
     function testFunctionRemovesFirstElementOfAssociativeArray()
     {
      $input = array('x' => 'foo', 'y' => 'bar');
      array_shift_reference($input);
      $this->assertEqual(array('y' => 'bar'), $input, '%s: The array should be shifted one element left');
     }
     function testFunctionReturnsReferenceToFirstElementOfNumericallyIndexedArray()
     {
      $foo = 'foo';
      $input = array(&$foo, 'bar');
      $first =& array_shift_reference($input);
      $this->assertReference($foo, $first, '%s: The return value should reference the first array element');
     }
     function testFunctionReturnsReferenceToFirstElementOfAssociativeArray()
     {
      $foo = 'foo';
      $input = array('x' => &$foo, 'y' => 'bar');
      $first =& array_shift_reference($input);
      $this->assertReference($foo, $first, '%s: The return value should reference the first array element');
     }
     function testFunctionReturnsNullIfEmptyArrayPassedAsInput()
     {
      $input = array();
      $first = array_shift_reference($input);
      $this->assertNull($first, '%s: Array has no first element so NULL should be returned');
     }
    }
    ?>
    
    // Ex. 1: signedShiftArray (['A', 'B', 'C', 'D'], 2)    ->    ['C', 'D', 'A', 'B']
    // Ex. 2: signedShiftArray (['A', 'B', 'C', 'D'], -3)    ->    ['B', 'C', 'D', 'A']
    // Ex. 3: signedShiftArray (['A', 'B', 'C', 'D'], -7)    ->    ['B', 'C', 'D', 'A']
    function signedShiftArray ($aItems, $aOffset)
    {
      if (empty ($aItems))
        return [];
      else if (empty ($aOffset))
        return $aItems;
      else {
        $t= count ($aItems);
        $n= $aOffset % $t;
        $m= $aOffset > 0 ? $n : $t + $aOffset;
        return array_merge (array_slice ($aItems, $n), array_slice ($aItems, 0, $m));
      }
    }
    Sometimes instead of shuffling array you just need to rotate it. We can easily rotate left an array with such code:
    <?php
    $arr[] = array_shift($arr);
    ?>
    
    <?php
    //Be careful when using array_pop/shift/push/unshift with irregularly indexed arrays:
    $shifty = $poppy = array(
     2 => '(2)',
     1 => '(1)',
     0 => '(0)',
    );             print_r( $shifty );
    array_shift( $shifty );  print_r( $shifty );
    //   [0] => (1)
    //   [1] => (0)
    array_pop( $poppy );    print_r( $poppy );
    //   [2] => (2)
    //   [1] => (1)
    $shifty = $poppy = array(
     'a' => 'A',
     'b' => 'B',
     '(0)',
     '(1)',
     'c' => 'C',
     'd' => 'D',
    );                   print_r( $shifty );
    array_shift( $shifty );        print_r( $shifty );
    //   [b] => B
    //   [0] => (0)
    //   [1] => (1)
    //   [c] => C
    //   [d] => D
    array_unshift( $shifty, 'unshifted'); print_r( $shifty );
    //   [0] => unshifted
    //   [b] => B
    //   [1] => (0)
    //   [2] => (1)
    //   [c] => C
    //   [d] => D
    array_pop( $poppy );          print_r( $poppy );
    //   [a] => A
    //   [b] => B
    //   [0] => (0)
    //   [1] => (1)
    //   [c] => C
    array_push( $poppy, 'pushed');     print_r( $poppy );
    //   [a] => A
    //   [b] => B
    //   [0] => (0)
    //   [1] => (1)
    //   [c] => C
    //   [2] => pushed
    ?>
    
    To remove an element from the MIDDLE of an array (similar to array_shift, only instead of removing the first element, we want to remove an element in the middle, and shift all keys that follow down one position)
    Note that this only works on enumerated arrays.
    <?php
    $array = array('a', 'b', 'c', 'd', 'e', 'e');
    /*
    array(6) {
     [0]=>
     string(1) "a"
     [1]=>
     string(1) "b"
     [2]=>
     string(1) "c"
     [3]=>
     string(1) "d"
     [4]=>
     string(1) "e"
     [5]=>
     string(1) "e"
    }
    */
    $indexToRemove = 2;
    unset($array[$indexToRemove]);
    $array = array_slice($array, 0);
    /*
    array(5) {
     [0]=>
     string(1) "a"
     [1]=>
     string(1) "b"
     [2]=>
     string(1) "d"
     [3]=>
     string(1) "e"
     [4]=>
     string(1) "e"
    }
    */
    ?>
    I hope this helps someone!
    Here's a utility function to parse command line arguments.
    <?php
    /**
     * CommandLine class
     *
     * @package       Framework
     */
    /**
     * Command Line Interface (CLI) utility class.
     *
     * @author       Patrick Fisher <patrick@pwfisher.com>
     * @since        August 21, 2009
     * @package       Framework
     * @subpackage     Env
     */
    class CommandLine {
      /**
       * PARSE ARGUMENTS
       * 
       * [pfisher ~]$ echo "<?php
       * >   include('CommandLine.php');
       * >   \$args = CommandLine::parseArgs(\$_SERVER['argv']);
       * >   echo "\n", '\$out = '; var_dump(\$args); echo "\n";
       * > ?>" > test.php
       * 
       * [pfisher ~]$ php test.php plain-arg --foo --bar=baz --funny="spam=eggs" --alsofunny=spam=eggs \
       * > 'plain arg 2' -abc -k=value "plain arg 3" --s="original" --s='overwrite' --s
       * 
       * $out = array(12) {
       *  [0]        => string(9) "plain-arg"
       *  ["foo"]      => bool(true)
       *  ["bar"]      => string(3) "baz"
       *  ["funny"]     => string(9) "spam=eggs"
       *  ["alsofunny"]   => string(9) "spam=eggs"
       *  [1]        => string(11) "plain arg 2"
       *  ["a"]       => bool(true)
       *  ["b"]       => bool(true)
       *  ["c"]       => bool(true)
       *  ["k"]       => string(5) "value"
       *  [2]        => string(11) "plain arg 3"
       *  ["s"]       => string(9) "overwrite"
       * }
       *
       * @author       Patrick Fisher <patrick@pwfisher.com>
       * @since        August 21, 2009
       * @see         http://www.php.net/manual/en/features.commandline.php
       *           #81042 function arguments($argv) by technorati at gmail dot com, 12-Feb-2008
       *           #78651 function getArgs($args) by B Crawford, 22-Oct-2007
       * @usage        $args = CommandLine::parseArgs($_SERVER['argv']);
       */
      public static function parseArgs($argv){
      
        array_shift($argv);
        $out              = array();
        
        foreach ($argv as $arg){
        
          // --foo --bar=baz
          if (substr($arg,0,2) == '--'){
            $eqPos         = strpos($arg,'=');
            
            // --foo
            if ($eqPos === false){
              $key        = substr($arg,2);
              $value       = isset($out[$key]) ? $out[$key] : true;
              $out[$key]     = $value;
            }
            // --bar=baz
            else {
              $key        = substr($arg,2,$eqPos-2);
              $value       = substr($arg,$eqPos+1);
              $out[$key]     = $value;
            }
          }
          // -k=value -abc
          else if (substr($arg,0,1) == '-'){
          
            // -k=value
            if (substr($arg,2,1) == '='){
              $key        = substr($arg,1,1);
              $value       = substr($arg,3);
              $out[$key]     = $value;
            }
            // -abc
            else {
              $chars       = str_split(substr($arg,1));
              foreach ($chars as $char){
                $key      = $char;
                $value     = isset($out[$key]) ? $out[$key] : true;
                $out[$key]   = $value;
              }
            }
          }
          // plain-arg
          else {
            $value         = $arg;
            $out[]         = $value;
          }
        }
        return $out;
      }
    }
    ?>
    
    // To Change order of Array by Saurabh Goyal
      function change_array_order($table,$order)
      {
        //init the new table
        $new_table = array();
        foreach($order as $colname)
        {
         $new_table[$colname] = $table[$colname];
        }
        return $new_table;
      }
    if array value like:-
    $row = array('usr_id'=>'23','usr_name'=>'Saurabh', 'usr_surname'=>'Goyal','usr_firstname'=>'Saurabh');
    //you want change order & show only particular field
    change_array_order($row,array('usr_name','usr_firstname',
                          'usr_surname'));
    Regard's
    Saurabh Goyal
    http://sggoyal.blogspot.com
    baughmankr at appstate dot edu, I think this is more efficient.
    <?php
    function array_shorten($arr)
    {
     list($k) = array_keys($arr);
     unset($arr[$k]);
     return $arr;
    }
    ?>
    
    I needed to remove the first set of keys and values from an associative array. Had to write this function: 
    function shortenArray($_arr)
    {
      $i=1;
      $_shorter=array();
      foreach ($_arr as $k => $v)
      {
        if ($i != 1)
        {
          $_shorter[$k] = $v;
        }
        $i++;
      }
      return $_shorter;
    }
    If you need the first or last entry of an array, then this could help you.
    <?php
    function array_last_entry($arr){
      if(!is_array($arr))
        return;
      
      if(empty($arr))
        return;
        
      return end($arr);
    }
    function array_first_entry($arr){
      if(!is_array($arr))
        return;
        
      if(empty($arr))
        return;
        
      reset($arr);
      return current($arr);  
    }
    $arr = array( '5' => 'five', '3' => 'three', '8' => 'eight',);
    echo 'last entry: '.array_last_entry($arr).'<br>';
    echo 'first entry: '.array_first_entry($arr).'<br>';
    echo 'alternative output:<br>';
     
    echo 'last entry: '.$arr[count($arr)-1];
    echo '<br>first entry: '.$arr[0]; 
    ?>
    The output will look like:
    last entry: eight
    first entry: five
    alternative output:
    last entry:
    first entry: 
    As you can see, if you have to handle arrays with non-continuous indexes, these functions may be very helpful.
    I haven't really read into it, but if you're complaining about a change in PHP 5.0.5 that made it so you couldn't do:
    <?php
    $val = array_shift(preg_split());
    ?>
    or
    <?php
    $val = array_shit(function_that_returns_array);
    ?>
    Then you're not using this function correctly. This function's argument is supposed to be a pointer to a variable. It then modifies that variable and returns a value. When you specify a function, php CAN NOT modify the return value of that function. It should be common sense but apparently its not.
    Also, on a efficiency note, you might want to consider using another function such as reset or perhaps making your own function such as below:
    <?php
    function first_element($array) {
    return reset($array);
    }
    ?>
    Unless of course for some reason you need to save the microseconds this takes.
    }
    no, it demonstrates quite well that it removes the first element in the original array, updating the keys, and that it also returns the original first element.
    Assignment in line, does not remove the element.
    $first = array_shift( $arr = array( 0 => '1st', 2 => '2nd', 3 => '3rd') );
    print_r( $first );
    print_r( $arr );
    Output:
    1st
    Array
    (
      [0] => 1st
      [2] => 2nd
      [3] => 3rd
    )
    This doesn't work with a 2 dimensional array. With 2 dimensional array I do this:
    <?php
    $backup = $arr;
    $first = array_shift ( $backup );
    ?>
    
    If the array has non-numerical keys, array_shift extracts the first element, whichever is the key, and recompute the numerical keys, if there are any. Ie :
    $array = array("c" => "ccc", 0 => "aaa", "d" => "ddd", 5 => "bbb");
    $first = array_shift($array);
    echo '$first = ' . $first . ', $array = ' . var_export($array, true);
    will display :
    $first = ccc, $array = array ( 0 => 'aaa', 'd' => 'ddd', 1 => 'bbb', )
    It means that array_shift works with associative arrays too, and leaves the keys unchanged if they are non-numerical.
    If you want a version of array_shift() that works non-destructively (i.e., an easy function to grab the first element of the array without modifying the array), try reset().
    In response to nando_f at nothingsimple dot com
    The example is correct, array_shift do an unset to first element because the parameter is passed by reference

    上篇:array_search()

    下篇:array_slice()