Skip to content

Commit 50516a6

Browse files
Enno Woortmanncmb69
authored andcommitted
Add implementation and tests for new methods - array_key_first(array $a) Returns the key of the first element or null - array_key_last(array $a) Returns the key of the last element or null
1 parent 79a27cc commit 50516a6

10 files changed

+693
-0
lines changed

UPGRADING

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,9 @@ Standard:
363363
. Added is_countable() function, to check whether a value may be passed to
364364
count().
365365
(RFC: https://wiki.php.net/rfc/is-countable)
366+
. Added array_key_first() and array_key_last() which retrieve the first and
367+
last key of an array, respectively.
368+
(RFC: <https://wiki.php.net/rfc/array_key_first_last>)
366369

367370
========================================
368371
7. New Classes and Interfaces

ext/standard/array.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3963,6 +3963,39 @@ PHP_FUNCTION(array_keys)
39633963
}
39643964
/* }}} */
39653965

3966+
/* {{{ proto mixed array_key_first(array stack)
3967+
Get the key of the first element of the array */
3968+
PHP_FUNCTION(array_key_first)
3969+
{
3970+
zval *stack; /* Input stack */
3971+
3972+
ZEND_PARSE_PARAMETERS_START(1, 1)
3973+
Z_PARAM_ARRAY_EX(stack, 0, 1)
3974+
ZEND_PARSE_PARAMETERS_END();
3975+
3976+
HashTable *target_hash = HASH_OF(stack);
3977+
HashPosition pos = 0;
3978+
zend_hash_get_current_key_zval_ex(target_hash, return_value, &pos);
3979+
}
3980+
/* }}} */
3981+
3982+
/* {{{ proto mixed array_key_last(array stack)
3983+
Get the key of the last element of the array */
3984+
PHP_FUNCTION(array_key_last)
3985+
{
3986+
zval *stack; /* Input stack */
3987+
HashPosition pos;
3988+
3989+
ZEND_PARSE_PARAMETERS_START(1, 1)
3990+
Z_PARAM_ARRAY_EX(stack, 0, 1)
3991+
ZEND_PARSE_PARAMETERS_END();
3992+
3993+
HashTable *target_hash = HASH_OF(stack);
3994+
zend_hash_internal_pointer_end_ex(target_hash, &pos);
3995+
zend_hash_get_current_key_zval_ex(target_hash, return_value, &pos);
3996+
}
3997+
/* }}} */
3998+
39663999
/* {{{ proto array array_values(array input)
39674000
Return just the values from the input array */
39684001
PHP_FUNCTION(array_values)

ext/standard/basic_functions.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,15 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_array_keys, 0, 0, 1)
418418
ZEND_ARG_INFO(0, strict)
419419
ZEND_END_ARG_INFO()
420420

421+
ZEND_BEGIN_ARG_INFO(arginfo_array_key_first, 0)
422+
ZEND_ARG_INFO(0, arg) /* ARRAY_INFO(0, arg, 0) */
423+
ZEND_END_ARG_INFO()
424+
425+
ZEND_BEGIN_ARG_INFO(arginfo_array_key_last, 0)
426+
ZEND_ARG_INFO(0, arg) /* ARRAY_INFO(0, arg, 0) */
427+
ZEND_END_ARG_INFO()
428+
429+
421430
ZEND_BEGIN_ARG_INFO(arginfo_array_values, 0)
422431
ZEND_ARG_INFO(0, arg) /* ARRAY_INFO(0, arg, 0) */
423432
ZEND_END_ARG_INFO()
@@ -3362,6 +3371,8 @@ static const zend_function_entry basic_functions[] = { /* {{{ */
33623371
PHP_FE(array_replace, arginfo_array_replace)
33633372
PHP_FE(array_replace_recursive, arginfo_array_replace_recursive)
33643373
PHP_FE(array_keys, arginfo_array_keys)
3374+
PHP_FE(array_key_first, arginfo_array_key_first)
3375+
PHP_FE(array_key_last, arginfo_array_key_last)
33653376
PHP_FE(array_values, arginfo_array_values)
33663377
PHP_FE(array_count_values, arginfo_array_count_values)
33673378
PHP_FE(array_column, arginfo_array_column)

ext/standard/php_array.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ PHP_FUNCTION(array_merge_recursive);
6969
PHP_FUNCTION(array_replace);
7070
PHP_FUNCTION(array_replace_recursive);
7171
PHP_FUNCTION(array_keys);
72+
PHP_FUNCTION(array_key_first);
73+
PHP_FUNCTION(array_key_last);
7274
PHP_FUNCTION(array_values);
7375
PHP_FUNCTION(array_count_values);
7476
PHP_FUNCTION(array_column);
Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
--TEST--
2+
Test array_key_first() function
3+
--FILE--
4+
<?php
5+
6+
array_key_first($GLOBALS);
7+
8+
/* Various combinations of arrays to be used for the test */
9+
$mixed_array = array(
10+
array(),
11+
array( 1,2,3,4,5,6,7,8,9 ),
12+
array( "One", "_Two", "Three", "Four", "Five" ),
13+
array( 6, "six", 7, "seven", 8, "eight", 9, "nine" ),
14+
array( "a" => "aaa", "A" => "AAA", "c" => "ccc", "d" => "ddd", "e" => "eee" ),
15+
array( "1" => "one", "2" => "two", "3" => "three", "4" => "four", "5" => "five" ),
16+
array( 1 => "one", 2 => "two", 3 => 7, 4 => "four", 5 => "five" ),
17+
array( "f" => "fff", "1" => "one", 4 => 6, "" => "blank", 2.4 => "float", "F" => "FFF",
18+
"blank" => "", 3.7 => 3.7, 5.4 => 7, 6 => 8.6, '5' => "Five", "4name" => "jonny", "a" => NULL, NULL => 3 ),
19+
array( 12, "name", 'age', '45' ),
20+
array( array("oNe", "tWo", 4), array(10, 20, 30, 40, 50), array() ),
21+
array( "one" => 1, "one" => 2, "three" => 3, 3, 4, 3 => 33, 4 => 44, 5, 6,
22+
5.4 => 54, 5.7 => 57, "5.4" => 554, "5.7" => 557 ),
23+
array( "foo" ),
24+
array( 1 => "42" )
25+
);
26+
27+
/* Loop to test normal functionality with different arrays inputs */
28+
echo "\n*** Normal testing with various array inputs ***\n";
29+
30+
$counter = 1;
31+
foreach( $mixed_array as $sub_array )
32+
{
33+
echo "\n-- Input Array for Iteration $counter is --\n";
34+
print_r( $sub_array );
35+
echo "\nFirst key is :\n";
36+
var_dump( array_key_first($sub_array) );
37+
$counter++;
38+
}
39+
40+
echo"\nDone";
41+
?>
42+
--EXPECT--
43+
*** Normal testing with various array inputs ***
44+
45+
-- Input Array for Iteration 1 is --
46+
Array
47+
(
48+
)
49+
50+
First key is :
51+
NULL
52+
53+
-- Input Array for Iteration 2 is --
54+
Array
55+
(
56+
[0] => 1
57+
[1] => 2
58+
[2] => 3
59+
[3] => 4
60+
[4] => 5
61+
[5] => 6
62+
[6] => 7
63+
[7] => 8
64+
[8] => 9
65+
)
66+
67+
First key is :
68+
int(0)
69+
70+
-- Input Array for Iteration 3 is --
71+
Array
72+
(
73+
[0] => One
74+
[1] => _Two
75+
[2] => Three
76+
[3] => Four
77+
[4] => Five
78+
)
79+
80+
First key is :
81+
int(0)
82+
83+
-- Input Array for Iteration 4 is --
84+
Array
85+
(
86+
[0] => 6
87+
[1] => six
88+
[2] => 7
89+
[3] => seven
90+
[4] => 8
91+
[5] => eight
92+
[6] => 9
93+
[7] => nine
94+
)
95+
96+
First key is :
97+
int(0)
98+
99+
-- Input Array for Iteration 5 is --
100+
Array
101+
(
102+
[a] => aaa
103+
[A] => AAA
104+
[c] => ccc
105+
[d] => ddd
106+
[e] => eee
107+
)
108+
109+
First key is :
110+
string(1) "a"
111+
112+
-- Input Array for Iteration 6 is --
113+
Array
114+
(
115+
[1] => one
116+
[2] => two
117+
[3] => three
118+
[4] => four
119+
[5] => five
120+
)
121+
122+
First key is :
123+
int(1)
124+
125+
-- Input Array for Iteration 7 is --
126+
Array
127+
(
128+
[1] => one
129+
[2] => two
130+
[3] => 7
131+
[4] => four
132+
[5] => five
133+
)
134+
135+
First key is :
136+
int(1)
137+
138+
-- Input Array for Iteration 8 is --
139+
Array
140+
(
141+
[f] => fff
142+
[1] => one
143+
[4] => 6
144+
[] => 3
145+
[2] => float
146+
[F] => FFF
147+
[blank] =>
148+
[3] => 3.7
149+
[5] => Five
150+
[6] => 8.6
151+
[4name] => jonny
152+
[a] =>
153+
)
154+
155+
First key is :
156+
string(1) "f"
157+
158+
-- Input Array for Iteration 9 is --
159+
Array
160+
(
161+
[0] => 12
162+
[1] => name
163+
[2] => age
164+
[3] => 45
165+
)
166+
167+
First key is :
168+
int(0)
169+
170+
-- Input Array for Iteration 10 is --
171+
Array
172+
(
173+
[0] => Array
174+
(
175+
[0] => oNe
176+
[1] => tWo
177+
[2] => 4
178+
)
179+
180+
[1] => Array
181+
(
182+
[0] => 10
183+
[1] => 20
184+
[2] => 30
185+
[3] => 40
186+
[4] => 50
187+
)
188+
189+
[2] => Array
190+
(
191+
)
192+
193+
)
194+
195+
First key is :
196+
int(0)
197+
198+
-- Input Array for Iteration 11 is --
199+
Array
200+
(
201+
[one] => 2
202+
[three] => 3
203+
[0] => 3
204+
[1] => 4
205+
[3] => 33
206+
[4] => 44
207+
[5] => 57
208+
[6] => 6
209+
[5.4] => 554
210+
[5.7] => 557
211+
)
212+
213+
First key is :
214+
string(3) "one"
215+
216+
-- Input Array for Iteration 12 is --
217+
Array
218+
(
219+
[0] => foo
220+
)
221+
222+
First key is :
223+
int(0)
224+
225+
-- Input Array for Iteration 13 is --
226+
Array
227+
(
228+
[1] => 42
229+
)
230+
231+
First key is :
232+
int(1)
233+
234+
Done
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
--TEST--
2+
Test array_key_first() function (errors)
3+
--FILE--
4+
<?php
5+
6+
$empty_array = array();
7+
$number = 5;
8+
$str = "abc";
9+
10+
/* Various combinations of arrays to be used for the test */
11+
$mixed_array = array(
12+
array( 1,2,3,4,5,6,7,8,9 ),
13+
array( "One", "_Two", "Three", "Four", "Five" )
14+
);
15+
16+
/* Testing Error Conditions */
17+
echo "\n*** Testing Error Conditions ***\n";
18+
19+
/* Zero argument */
20+
var_dump( array_key_first() );
21+
22+
/* Scalar argument */
23+
var_dump( array_key_first($number) );
24+
25+
/* String argument */
26+
var_dump( array_key_first($str) );
27+
28+
/* Invalid Number of arguments */
29+
var_dump( array_key_first($mixed_array[0],$mixed_array[1]) );
30+
31+
/* Empty Array as argument */
32+
var_dump( array_key_first($empty_array) );
33+
34+
echo"\nDone";
35+
?>
36+
--EXPECTF--
37+
*** Testing Error Conditions ***
38+
39+
Warning: array_key_first() expects exactly 1 parameter, 0 given in %s on line %d
40+
NULL
41+
42+
Warning: array_key_first() expects parameter 1 to be array, int given in %s on line %d
43+
NULL
44+
45+
Warning: array_key_first() expects parameter 1 to be array, string given in %s on line %d
46+
NULL
47+
48+
Warning: array_key_first() expects exactly 1 parameter, 2 given in %s on line %d
49+
NULL
50+
NULL
51+
52+
Done

0 commit comments

Comments
 (0)