Skip to content

Commit f25474f

Browse files
HypeMCbukka
authored andcommitted
Add before_needle argument to strrchr()
Closes GH-11430
1 parent 9eb032b commit f25474f

File tree

6 files changed

+47
-9
lines changed

6 files changed

+47
-9
lines changed

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ PHP NEWS
77
. Introduced Zend guard recursion protection to fix __debugInfo issue.
88
(Jakub Zelenka)
99

10+
- Standard:
11+
. Added $before_needle argument to strrchr(). (HypeMC)
12+
1013
17 Aug 2023, PHP 8.3.0beta3
1114

1215
- Core:

UPGRADING

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,8 @@ PHP 8.3 UPGRADE NOTES
348348
means that when $decimals is negative, $num is rounded to $decimals
349349
significant digits before the decimal point. Previously negative $decimals
350350
got silently ignored and the number got rounded to zero decimal places.
351+
. The $before_needle argument added to strrchr() which works in the same way
352+
like its counterpart in strstr() or stristr().
351353

352354
========================================
353355
6. New Functions

ext/standard/basic_functions.stub.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2395,7 +2395,7 @@ function strripos(string $haystack, string $needle, int $offset = 0): int|false
23952395
* @compile-time-eval
23962396
* @refcount 1
23972397
*/
2398-
function strrchr(string $haystack, string $needle): string|false {}
2398+
function strrchr(string $haystack, string $needle, bool $before_needle = false): string|false {}
23992399

24002400
/** @compile-time-eval */
24012401
function str_contains(string $haystack, string $needle): bool {}

ext/standard/basic_functions_arginfo.h

Lines changed: 2 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/standard/string.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1656,7 +1656,7 @@ PHP_FUNCTION(stristr)
16561656
if (part) {
16571657
RETURN_STRINGL(ZSTR_VAL(haystack), found_offset);
16581658
}
1659-
RETURN_STRINGL(ZSTR_VAL(haystack) + found_offset, ZSTR_LEN(haystack) - found_offset);
1659+
RETURN_STRINGL(found, ZSTR_LEN(haystack) - found_offset);
16601660
}
16611661
/* }}} */
16621662

@@ -1684,7 +1684,7 @@ PHP_FUNCTION(strstr)
16841684
if (part) {
16851685
RETURN_STRINGL(ZSTR_VAL(haystack), found_offset);
16861686
}
1687-
RETURN_STRINGL(ZSTR_VAL(haystack) + found_offset, ZSTR_LEN(haystack) - found_offset);
1687+
RETURN_STRINGL(found, ZSTR_LEN(haystack) - found_offset);
16881688
}
16891689
/* }}} */
16901690

@@ -1934,17 +1934,23 @@ PHP_FUNCTION(strrchr)
19341934
zend_string *haystack, *needle;
19351935
const char *found = NULL;
19361936
zend_long found_offset;
1937+
bool part = 0;
19371938

1938-
ZEND_PARSE_PARAMETERS_START(2, 2)
1939+
ZEND_PARSE_PARAMETERS_START(2, 3)
19391940
Z_PARAM_STR(haystack)
19401941
Z_PARAM_STR(needle)
1942+
Z_PARAM_OPTIONAL
1943+
Z_PARAM_BOOL(part)
19411944
ZEND_PARSE_PARAMETERS_END();
19421945

19431946
found = zend_memrchr(ZSTR_VAL(haystack), *ZSTR_VAL(needle), ZSTR_LEN(haystack));
19441947
if (UNEXPECTED(!found)) {
19451948
RETURN_FALSE;
19461949
}
19471950
found_offset = found - ZSTR_VAL(haystack);
1951+
if (part) {
1952+
RETURN_STRINGL(ZSTR_VAL(haystack), found_offset);
1953+
}
19481954
RETURN_STRINGL(found, ZSTR_LEN(haystack) - found_offset);
19491955
}
19501956
/* }}} */

ext/standard/tests/strings/strrchr_basic.phpt

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,49 +4,79 @@ Test strrchr() function : basic functionality
44
<?php
55
echo "*** Testing strrchr() function: basic functionality ***\n";
66
var_dump( strrchr("Hello, World", "H") ); //needle as single char
7+
var_dump( strrchr("Hello, World", "H", true) ); //needle as single char
78
var_dump( strrchr("Hello, World", "Hello") ); //needle as a first word of haystack
9+
var_dump( strrchr("Hello, World", "Hello", true) ); //needle as a first word of haystack
810
var_dump( strrchr('Hello, World', 'H') );
11+
var_dump( strrchr('Hello, World', 'H', true) );
912
var_dump( strrchr('Hello, World', 'Hello') );
13+
var_dump( strrchr('Hello, World', 'Hello', true) );
1014

1115
//considering case
1216
var_dump( strrchr("Hello, World", "h") );
17+
var_dump( strrchr("Hello, World", "h", true) );
1318
var_dump( strrchr("Hello, World", "hello") );
19+
var_dump( strrchr("Hello, World", "hello", true) );
1420

1521
//needle as second word of haystack
1622
var_dump( strrchr("Hello, World", "World") );
23+
var_dump( strrchr("Hello, World", "World", true) );
1724
var_dump( strrchr('Hello, World', 'World') );
25+
var_dump( strrchr('Hello, World', 'World', true) );
1826

1927
//needle as special char
2028
var_dump( strrchr("Hello, World", ",") );
29+
var_dump( strrchr("Hello, World", ",", true) );
2130
var_dump( strrchr('Hello, World', ',') );
31+
var_dump( strrchr('Hello, World', ',', true) );
2232

2333
var_dump( strrchr("Hello, World", "Hello, World") ); //needle as haystack
34+
var_dump( strrchr("Hello, World", "Hello, World", true) ); //needle as haystack
2435

2536
//needle string containing one existing and one non-existing char
2637
var_dump( strrchr("Hello, World", "Hi") );
38+
var_dump( strrchr("Hello, World", "Hi", true) );
2739

2840
//multiple existence of needle in haystack
2941
var_dump( strrchr("Hello, World", "o") );
42+
var_dump( strrchr("Hello, World", "o", true) );
3043
var_dump( strrchr("Hello, World", "ooo") );
44+
var_dump( strrchr("Hello, World", "ooo", true) );
3145

3246
var_dump( strrchr("Hello, World", "Zzzz") ); //non-existent needle in haystack
47+
var_dump( strrchr("Hello, World", "Zzzz", true) ); //non-existent needle in haystack
3348
echo "*** Done ***";
3449
?>
3550
--EXPECT--
3651
*** Testing strrchr() function: basic functionality ***
3752
string(12) "Hello, World"
53+
string(0) ""
3854
string(12) "Hello, World"
55+
string(0) ""
3956
string(12) "Hello, World"
57+
string(0) ""
4058
string(12) "Hello, World"
59+
string(0) ""
60+
bool(false)
61+
bool(false)
4162
bool(false)
4263
bool(false)
4364
string(5) "World"
65+
string(7) "Hello, "
4466
string(5) "World"
67+
string(7) "Hello, "
4568
string(7) ", World"
69+
string(5) "Hello"
4670
string(7) ", World"
71+
string(5) "Hello"
4772
string(12) "Hello, World"
73+
string(0) ""
4874
string(12) "Hello, World"
75+
string(0) ""
4976
string(4) "orld"
77+
string(8) "Hello, W"
5078
string(4) "orld"
79+
string(8) "Hello, W"
80+
bool(false)
5181
bool(false)
5282
*** Done ***

0 commit comments

Comments
 (0)