PR: https://github.com/php/php-src/pull/4797
- Standard:
- . Added str_contains($haystack, $needle) function, which checks whether
- $haystack contains $needle as a sub-string. It is equivalent to writing
- strpos($haystack, $needle) !== false.
+ . Added
+
+ str_contains(string $haystack, string $needle): bool
+ str_starts_with(string $haystack, string $needle): bool
+ str_ends_with(string $haystack, string $needle): bool
+
+ functions, which check whether $haystack contains, starts with or ends with
+ $needle.
+ RFC: https://wiki.php.net/rfc/str_contains
+ RFC: https://wiki.php.net/rfc/add_str_starts_with_and_ends_with_functions
. Added fdiv() function, which performs a floating-point division under
IEEE 754 semantics. Division by zero is considered well-defined and
will return one of Inf, -Inf or NaN.
function str_contains(string $haystack, string $needle): bool {}
+function str_starts_with(string $haystack, string $needle): bool {}
+
+function str_ends_with(string $haystack, string $needle): bool {}
+
function chunk_split(string $str, int $chunklen = 76, string $ending = "\r\n"): string {}
function substr(string $str, int $start, ?int $length = null): string|false {}
ZEND_ARG_TYPE_INFO(0, needle, IS_STRING, 0)
ZEND_END_ARG_INFO()
+#define arginfo_str_starts_with arginfo_str_contains
+
+#define arginfo_str_ends_with arginfo_str_contains
+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_chunk_split, 0, 1, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, str, IS_STRING, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, chunklen, IS_LONG, 0, "76")
ZEND_FUNCTION(strripos);
ZEND_FUNCTION(strrchr);
ZEND_FUNCTION(str_contains);
+ZEND_FUNCTION(str_starts_with);
+ZEND_FUNCTION(str_ends_with);
ZEND_FUNCTION(chunk_split);
ZEND_FUNCTION(substr);
ZEND_FUNCTION(substr_replace);
ZEND_FE(strripos, arginfo_strripos)
ZEND_FE(strrchr, arginfo_strrchr)
ZEND_FE(str_contains, arginfo_str_contains)
+ ZEND_FE(str_starts_with, arginfo_str_starts_with)
+ ZEND_FE(str_ends_with, arginfo_str_ends_with)
ZEND_FE(chunk_split, arginfo_chunk_split)
ZEND_FE(substr, arginfo_substr)
ZEND_FE(substr_replace, arginfo_substr_replace)
}
/* }}} */
+/* {{{ proto bool str_starts_with(string haystack, string needle)
+ Checks if haystack starts with needle */
+PHP_FUNCTION(str_starts_with)
+{
+ zend_string *haystack, *needle;
+
+ ZEND_PARSE_PARAMETERS_START(2, 2)
+ Z_PARAM_STR(haystack)
+ Z_PARAM_STR(needle)
+ ZEND_PARSE_PARAMETERS_END();
+
+ if (ZSTR_LEN(needle) > ZSTR_LEN(haystack)) {
+ RETURN_FALSE;
+ }
+
+ RETURN_BOOL(memcmp(ZSTR_VAL(haystack), ZSTR_VAL(needle), ZSTR_LEN(needle)) == 0);
+}
+
+/* {{{ proto bool str_ends_with(string haystack, string needle)
+ Checks if haystack ends with needle */
+PHP_FUNCTION(str_ends_with)
+{
+ zend_string *haystack, *needle;
+
+ ZEND_PARSE_PARAMETERS_START(2, 2)
+ Z_PARAM_STR(haystack)
+ Z_PARAM_STR(needle)
+ ZEND_PARSE_PARAMETERS_END();
+
+ if (ZSTR_LEN(needle) > ZSTR_LEN(haystack)) {
+ RETURN_FALSE;
+ }
+
+ RETURN_BOOL(memcmp(
+ ZSTR_VAL(haystack) + ZSTR_LEN(haystack) - ZSTR_LEN(needle),
+ ZSTR_VAL(needle), ZSTR_LEN(needle)) == 0);
+}
+
/* {{{ proto string strchr(string haystack, string needle)
An alias for strstr */
/* }}} */
--- /dev/null
+--TEST--
+str_ends_with() function - unit tests for str_ends_with()
+--FILE--
+<?php
+/* Prototype: bool str_ends_with (string $haystack, string $needle);
+ Description: Determine if $haystack ends with $needle
+*/
+$testStr = "beginningMiddleEnd";
+var_dump(str_ends_with($testStr, "End"));
+var_dump(str_ends_with($testStr, "end"));
+var_dump(str_ends_with($testStr, "en"));
+var_dump(str_ends_with($testStr, $testStr));
+var_dump(str_ends_with($testStr, $testStr.$testStr));
+var_dump(str_ends_with($testStr, ""));
+var_dump(str_ends_with("", ""));
+var_dump(str_ends_with("", " "));
+var_dump(str_ends_with($testStr, "\x00"));
+var_dump(str_ends_with("\x00", ""));
+var_dump(str_ends_with("\x00", "\x00"));
+var_dump(str_ends_with("a\x00", "\x00"));
+var_dump(str_ends_with("ab\x00c", "b\x00c"));
+var_dump(str_ends_with("a\x00b", "d\x00b"));
+var_dump(str_ends_with("a\x00b", "a\x00z"));
+var_dump(str_ends_with("a", "\x00a"));
+var_dump(str_ends_with("a", "a\x00"));
+?>
+--EXPECT--
+bool(true)
+bool(false)
+bool(false)
+bool(true)
+bool(false)
+bool(true)
+bool(true)
+bool(false)
+bool(false)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(false)
+bool(false)
+bool(false)
+bool(false)
--- /dev/null
+--TEST--
+str_starts_with() function - unit tests for str_starts_with()
+--FILE--
+<?php
+/* Prototype: bool str_starts_with (string $haystack, string $needle);
+ Description: Determine if $haystack begins with $needle
+*/
+$testStr = "beginningMiddleEnd";
+var_dump(str_starts_with($testStr, "beginning"));
+var_dump(str_starts_with($testStr, "Beginning"));
+var_dump(str_starts_with($testStr, "eginning"));
+var_dump(str_starts_with($testStr, $testStr));
+var_dump(str_starts_with($testStr, $testStr.$testStr));
+var_dump(str_starts_with($testStr, ""));
+var_dump(str_starts_with("", ""));
+var_dump(str_starts_with("", " "));
+var_dump(str_starts_with($testStr, "\x00"));
+var_dump(str_starts_with("\x00", ""));
+var_dump(str_starts_with("\x00", "\x00"));
+var_dump(str_starts_with("\x00a", "\x00"));
+var_dump(str_starts_with("a\x00bc", "a\x00b"));
+var_dump(str_starts_with("a\x00b", "a\x00d"));
+var_dump(str_starts_with("a\x00b", "z\x00b"));
+var_dump(str_starts_with("a", "a\x00"));
+var_dump(str_starts_with("a", "\x00a"));
+?>
+--EXPECT--
+bool(true)
+bool(false)
+bool(false)
+bool(true)
+bool(false)
+bool(true)
+bool(true)
+bool(false)
+bool(false)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(false)
+bool(false)
+bool(false)
+bool(false)