Commit 3c6b25cca51 for php.net
commit 3c6b25cca5142b12a2ce440a9e965ac795a24ee6
Author: Tim Düsterhus <tim@bastelstu.be>
Date: Sun Jun 14 12:48:06 2026 +0200
zend_string: Add `zend_string_equals_cstr_ci()` (#22296)
This function was missing for consistency with the other functions which all
have a `cstr` variant. Adding this function also made it easy to convert some
more copy-and-pasted logic.
diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS
index f89123116c7..bb2f6227475 100644
--- a/UPGRADING.INTERNALS
+++ b/UPGRADING.INTERNALS
@@ -17,6 +17,7 @@ PHP 8.6 INTERNALS UPGRADE NOTES
. ZSTR_INIT_LITERAL(), zend_string_starts_with_literal(), and
zend_string_starts_with_literal_ci() now support strings containing NUL
bytes. Passing non-literal char* is no longer supported.
+ . Added zend_string_equals_cstr_ci().
. The misnamed ZVAL_IS_NULL() has been removed. Use Z_ISNULL() instead.
. New zend_class_entry.ce_flags2 and zend_function.fn_flags2 fields were
added, given the primary flags were running out of bits.
diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h
index b6e1923b3bf..27aa4fdb048 100644
--- a/Zend/zend_operators.h
+++ b/Zend/zend_operators.h
@@ -46,7 +46,6 @@
#include "zend_portability.h"
#include "zend_strtod.h"
#include "zend_multiply.h"
-#include "zend_object_handlers.h"
#define LONG_SIGN_MASK ZEND_LONG_MIN
diff --git a/Zend/zend_string.h b/Zend/zend_string.h
index 3f0c9abd259..930d733307f 100644
--- a/Zend/zend_string.h
+++ b/Zend/zend_string.h
@@ -397,11 +397,22 @@ static zend_always_inline bool zend_string_equals(const zend_string *s1, const z
return s1 == s2 || zend_string_equal_content(s1, s2);
}
-#define zend_string_equals_ci(s1, s2) \
- (ZSTR_LEN(s1) == ZSTR_LEN(s2) && !zend_binary_strcasecmp(ZSTR_VAL(s1), ZSTR_LEN(s1), ZSTR_VAL(s2), ZSTR_LEN(s2)))
+BEGIN_EXTERN_C()
+ZEND_API int ZEND_FASTCALL zend_binary_strcasecmp(const char *s1, size_t len1, const char *s2, size_t len2);
+END_EXTERN_C()
+
+static zend_always_inline bool zend_string_equals_cstr_ci(const zend_string *s1, const char *s2, size_t s2_length)
+{
+ return ZSTR_LEN(s1) == s2_length && !zend_binary_strcasecmp(ZSTR_VAL(s1), ZSTR_LEN(s1), s2, s2_length);
+}
+
+#define zend_string_equals_literal_ci(str, literal) \
+ zend_string_equals_cstr_ci(str, "" literal, sizeof(literal) - 1)
-#define zend_string_equals_literal_ci(str, c) \
- (ZSTR_LEN(str) == sizeof("" c) - 1 && !zend_binary_strcasecmp(ZSTR_VAL(str), ZSTR_LEN(str), (c), sizeof(c) - 1))
+static zend_always_inline bool zend_string_equals_ci(const zend_string *s1, const zend_string *s2)
+{
+ return zend_string_equals_cstr_ci(s1, ZSTR_VAL(s2), ZSTR_LEN(s2));
+}
#define zend_string_equals_literal(str, literal) \
zend_string_equals_cstr(str, "" literal, sizeof(literal) - 1)