PHPのお勉強!

PHP TOP

array_shift

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

array_shift配列の先頭から要素を一つ取り出す

説明

array_shift(array &$array): mixed

array_shift() は、array の最初の値を取り出して返します。配列 array は、要素一つ分だけ短くなり、全ての要素は前にずれます。 数値添字の配列のキーはゼロから順に新たに振りなおされますが、 リテラルのキーには影響しません。

注意: この関数は、 入力配列のポインタを、使用した後にリセット (reset()) します。

パラメータ

array

入力の配列。

戻り値

取り出した値を返します。array が空の場合や配列でない場合は null を返します。

例1 array_shift() の例

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

上の例の出力は以下となります。

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

そして、$fruit には orange が代入されます。

参考

  • array_unshift() - 一つ以上の要素を配列の最初に加える
  • array_push() - 一つ以上の要素を配列の最後に追加する
  • array_pop() - 配列の末尾から要素を取り除く

add a note

User Contributed Notes 29 notes

up
111
regs at voidship dot net
16 years ago
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.
up
63
elad dot yosifon at gmail dot com
11 years ago
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.
up
25
nospam at dyce dot losethisbit dot com
16 years ago
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
)
up
6
biziclop at vipmail dot hu
6 years ago
<?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

?>
up
5
chris {at} w3style {dot} co {dot} uk
16 years ago
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');
}

}

?>
up
4
michaeljanikk at gmail dot com
10 years ago
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!
up
2
mah dot di at live dot com
8 years ago
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
up
5
Traps
17 years ago
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

?>
up
5
arturo {dot} ronchi {at} gmail {dot} com
19 years ago
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;
}
up
3
Anonymous
19 years ago
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;
}

?>
up
1
patrick at pwfisher dot com
15 years ago
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;
}
}
?>
up
2
hmztsc at gmail dot com
4 years ago
// i wanted to remove first array inside to array
// but doesn't work for me : array_shift();

$cargo_file =
Array
(
[0] => Array
(
[0] => Country
[1] => CountryCode
[2] => City
[3] => CityOtherLanguage
[4] => PostCode
[5] => Days
)

[1] => Array
(
[0] => Turkey
[1] => TR
[2] => Istanbul
[3] => Istanbul
[4] => 34930
[5] => 9
)

)

$cargo_file = array_shift($cargo_file);

echo "<pre>";
print_r($cargo_file);
echo "</pre>";

// result after :

/*
Array
(
[0] => Country
[1] => CountryCode
[2] => City
[3] => CityOtherLanguage
[4] => PostCode
[5] => Days
)
*/

i developed a solution

function removeFirstArray($array){

$new_array = [];
foreach ($array as $key => $value) {
if($key > 0){
$new_array[] = $value;
}
}

return $new_array;
}

$cargo_file= removeFirstArray($cargo_file);

echo "<pre>";
print_r($cargo_file);
echo "</pre>";

Array
(
[0] => Array
(
[0] => Turkey
[1] => TR
[2] => Istanbul
[3] => Istanbul
[4] => 34930
[5] => 9
)

)
up
1
Anonymous
19 years ago
<?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));
up
0
malima
2 years ago
A simple benchmark (PHP 8.1.9 + macOS 12.4)

<?php

ini_set
('memory_limit', -1);

$times = 25_000;
$length = 256;
$arr = [];

$random = random_bytes(($times + $length) / 2);
$random = bin2hex($random);

// benchmark array_shift()
for ($i = 0; $i < $times; $i++) {
$arr[$i] = substr($random, $i, $length);
}

$shiftTimer = -hrtime(true);
for (
$i = 0; $i < $times; $i++) {
$value = array_shift($arr);
}
$shiftTimer += hrtime(true);

// benchmark array_reverse() + array_pop() + array_reverse()
for ($i = 0; $i < $times; $i++) {
$arr[$i] = substr($random, $i, $length);
}

$reverseTimer = -hrtime(true);
for (
$i = 0; $i < $times; $i++) {
$arr = array_reverse($arr);
$value = array_pop($arr);
$arr = array_reverse($arr);
}
$reverseTimer += hrtime(true);

// benchmark array_reverse() + array_pop()
for ($i = 0; $i < $times; $i++) {
$arr[$i] = substr($random, $i, $length);
}

$popTimer = -hrtime(true);
$arr = array_reverse($arr);
for (
$i = 0; $i < $times; $i++) {
$value = array_pop($arr);
}
$popTimer += hrtime(true);

// benchmark $arr[key()]+ unset(key())
for ($i = 0; $i < $times; $i++) {
$arr[$i] = substr($random, $i, $length);
}

$keyTimer = -hrtime(true);
reset($arr);
for (
$i = 0; $i < $times; $i++) {
$key = key($arr);
$val = $arr[$key];
unset(
$arr[$key]);
}
$keyTimer += hrtime(true);

print_r([
'shift' => $shiftTimer / (10 ** 9),
'reverse' => $reverseTimer / (10 ** 9),
'pop' => $popTimer / (10 ** 9),
'key' => $keyTimer / (10 ** 9),
]);

?>

Results interpretation:

On an array of 25,000 unique items, each item a string of 256 byte:

and key() + unset() is very fast.

array_shift() is ~400 times slower

array_reverse() + array_pop() + array_reverse() is ~5,000 times slower.

p.s. I'm implementing a queue, so I need to add another array_reverse() after array_pop() which makes it extremely slow inside a loop. array_reverse() + array_pop() has no use for me, I just added for sake of checking it's performance. It is as fast as key() + unset().
up
1
Anonymous
4 years ago
"$stack" in the example should be called "$queue".
up
1
wheberson dot com dot br at gmail dot com
5 years ago
// 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));
}
}
up
0
vasiliauskas dot agnius at gmail dot com
5 years ago
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);
?>
up
0
drum_inc at yahoo dot com
11 years ago
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
)
up
0
sggoyal at gmail dot com
16 years ago
// 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
up
0
Ben
17 years ago
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;
}
?>