diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index 09f63860f1163..2fc5a0a9f3d4f 100644 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -2439,6 +2439,11 @@ function strrchr(string $haystack, string $needle, bool $before_needle = false): */ function str_contains(string $haystack, string $needle): bool {} +/** + * @compile-time-eval + */ +function str_icontains(string $haystack, string $needle): bool {} + /** * @compile-time-eval * @frameless-function {"arity": 2} diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index d221a221f4132..090a7d950782c 100644 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: dfd7d2cfd31312f7f6c5074c10cab54e9d1fbccc */ + * Stub hash: fa46a068353166de787b5c53dcb1077b2a8c20c3 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_set_time_limit, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, seconds, IS_LONG, 0) @@ -918,6 +918,8 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_str_contains, 0, 2, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, needle, IS_STRING, 0) ZEND_END_ARG_INFO() +#define arginfo_str_icontains arginfo_str_contains + #define arginfo_str_starts_with arginfo_str_contains #define arginfo_str_ends_with arginfo_str_contains @@ -2545,6 +2547,7 @@ ZEND_FUNCTION(strrpos); ZEND_FUNCTION(strripos); ZEND_FUNCTION(strrchr); ZEND_FUNCTION(str_contains); +ZEND_FUNCTION(str_icontains); ZEND_FUNCTION(str_starts_with); ZEND_FUNCTION(str_ends_with); ZEND_FUNCTION(chunk_split); @@ -3146,6 +3149,7 @@ static const zend_function_entry ext_functions[] = { ZEND_RAW_FENTRY("strripos", zif_strripos, arginfo_strripos, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) ZEND_RAW_FENTRY("strrchr", zif_strrchr, arginfo_strrchr, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) ZEND_RAW_FENTRY("str_contains", zif_str_contains, arginfo_str_contains, ZEND_ACC_COMPILE_TIME_EVAL, frameless_function_infos_str_contains, NULL) + ZEND_RAW_FENTRY("str_icontains", zif_str_icontains, arginfo_str_icontains, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) ZEND_RAW_FENTRY("str_starts_with", zif_str_starts_with, arginfo_str_starts_with, ZEND_ACC_COMPILE_TIME_EVAL, frameless_function_infos_str_starts_with, NULL) ZEND_RAW_FENTRY("str_ends_with", zif_str_ends_with, arginfo_str_ends_with, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) ZEND_RAW_FENTRY("chunk_split", zif_chunk_split, arginfo_chunk_split, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) diff --git a/ext/standard/string.c b/ext/standard/string.c index f21c9be8a7bd2..7d93e978004ba 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -1836,6 +1836,20 @@ ZEND_FRAMELESS_FUNCTION(str_contains, 2) Z_FLF_PARAM_FREE_STR(2, needle_tmp); } +/* {{{ Checks if a string contains another, case insensitive */ +PHP_FUNCTION(str_icontains) +{ + zend_string *haystack, *needle; + + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_STR(haystack) + Z_PARAM_STR(needle) + ZEND_PARSE_PARAMETERS_END(); + + RETURN_BOOL(php_memnistr(ZSTR_VAL(haystack), ZSTR_VAL(needle), ZSTR_LEN(needle), ZSTR_VAL(haystack) + ZSTR_LEN(haystack))); +} +/* }}} */ + /* {{{ Checks if haystack starts with needle */ PHP_FUNCTION(str_starts_with) { diff --git a/ext/standard/tests/strings/str_icontains.phpt b/ext/standard/tests/strings/str_icontains.phpt new file mode 100644 index 0000000000000..23f2d805c3207 --- /dev/null +++ b/ext/standard/tests/strings/str_icontains.phpt @@ -0,0 +1,36 @@ +--TEST-- +Test str_icontains() function +--FILE-- + +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(false) +bool(true) +bool(true) +bool(false) +bool(true)