Commit edde16948a8 for php.net

commit edde16948a8729886b9cab0de1f69a189823bac2
Author: LamentXU123 <108666168+LamentXU123@users.noreply.github.com>
Date:   Wed Jun 10 21:09:01 2026 +0800

    ext/intl: Guard Spoofchecker restriction-level APIs at ICU 53

    PHP-8.4 still supports ICU 50.1+, but GH-22055 removed the version guard around the Spoofchecker restriction-level API and made builds fail on ICU 50.x. Restore the guard at ICU 53 so the API remains available where supported without breaking older supported ICU versions.

    Closes GH-22248.

diff --git a/NEWS b/NEWS
index 5dac2613a0e..2698420c7a5 100644
--- a/NEWS
+++ b/NEWS
@@ -20,6 +20,8 @@ PHP                                                                        NEWS
   . Fix incorrect argument positions for uninitialized calendar arguments in
     IntlCalendar::equals(), ::before(), ::after(), and ::isEquivalentTo().
     (Weilin Du)
+  . Fixed Spoofchecker restriction-level APIs to only be exposed with ICU 53
+    and later. (Graham Campbell)

 - mysqli:
   . Fix stmt->query leak in mysqli_execute_query() validation errors.
diff --git a/ext/intl/spoofchecker/spoofchecker.stub.php b/ext/intl/spoofchecker/spoofchecker.stub.php
index 51a9c7d3907..34b8b3f368a 100644
--- a/ext/intl/spoofchecker/spoofchecker.stub.php
+++ b/ext/intl/spoofchecker/spoofchecker.stub.php
@@ -19,6 +19,7 @@ class Spoofchecker
     public const int INVISIBLE = UNKNOWN;
     /** @cvalue USPOOF_CHAR_LIMIT */
     public const int CHAR_LIMIT = UNKNOWN;
+#if U_ICU_VERSION_MAJOR_NUM >= 53
     /** @cvalue USPOOF_ASCII */
     public const int ASCII = UNKNOWN;
     /** @cvalue USPOOF_HIGHLY_RESTRICTIVE */
@@ -33,6 +34,7 @@ class Spoofchecker
     public const int SINGLE_SCRIPT_RESTRICTIVE = UNKNOWN;
     /** @cvalue USPOOF_MIXED_NUMBERS */
     public const int MIXED_NUMBERS = UNKNOWN;
+#endif
 #if U_ICU_VERSION_MAJOR_NUM >= 62
     /** @cvalue USPOOF_HIDDEN_OVERLAY */
     public const int HIDDEN_OVERLAY = UNKNOWN;
@@ -69,7 +71,9 @@ public function setAllowedLocales(string $locales): void {}
     /** @tentative-return-type */
     public function setChecks(int $checks): void {}

+#if U_ICU_VERSION_MAJOR_NUM >= 53
     /** @tentative-return-type */
     public function setRestrictionLevel(int $level): void {}
+#endif
     public function setAllowedChars(string $pattern, int $patternOptions = 0): void {}
 }
diff --git a/ext/intl/spoofchecker/spoofchecker_arginfo.h b/ext/intl/spoofchecker/spoofchecker_arginfo.h
index 99a211b260d..e6b53829081 100644
Binary files a/ext/intl/spoofchecker/spoofchecker_arginfo.h and b/ext/intl/spoofchecker/spoofchecker_arginfo.h differ
diff --git a/ext/intl/spoofchecker/spoofchecker_main.c b/ext/intl/spoofchecker/spoofchecker_main.c
index 13ac6739264..b03f73103b3 100644
--- a/ext/intl/spoofchecker/spoofchecker_main.c
+++ b/ext/intl/spoofchecker/spoofchecker_main.c
@@ -135,6 +135,7 @@ PHP_METHOD(Spoofchecker, setChecks)
 }
 /* }}} */

+#if U_ICU_VERSION_MAJOR_NUM >= 53
 /* TODO Document this method on PHP.net */
 /* {{{ Set the loosest restriction level allowed for strings. */
 PHP_METHOD(Spoofchecker, setRestrictionLevel)
@@ -163,6 +164,7 @@ PHP_METHOD(Spoofchecker, setRestrictionLevel)
 	uspoof_setRestrictionLevel(co->uspoof, (URestrictionLevel)level);
 }
 /* }}} */
+#endif

 PHP_METHOD(Spoofchecker, setAllowedChars)
 {
diff --git a/ext/intl/tests/spoofchecker_007.phpt b/ext/intl/tests/spoofchecker_007.phpt
index 5f3dbb47f19..07bdec2cf6f 100644
--- a/ext/intl/tests/spoofchecker_007.phpt
+++ b/ext/intl/tests/spoofchecker_007.phpt
@@ -4,6 +4,12 @@
 intl
 --SKIPIF--
 <?php if(!class_exists("Spoofchecker")) print 'skip'; ?>
+<?php
+    $r = new ReflectionClass("SpoofChecker");
+    if (false === $r->getConstant("SINGLE_SCRIPT_RESTRICTIVE")) {
+        die("skip for ICU version < 53");
+    }
+?>
 --FILE--
 <?php

diff --git a/ext/intl/tests/spoofchecker_supported_icu57_apis.phpt b/ext/intl/tests/spoofchecker_supported_icu57_apis.phpt
index 56cc194991e..136a56fb00f 100644
--- a/ext/intl/tests/spoofchecker_supported_icu57_apis.phpt
+++ b/ext/intl/tests/spoofchecker_supported_icu57_apis.phpt
@@ -4,6 +4,12 @@
 intl
 --SKIPIF--
 <?php if (!class_exists("Spoofchecker")) print 'skip'; ?>
+<?php
+    $r = new ReflectionClass("Spoofchecker");
+    if (false === $r->getConstant("SINGLE_SCRIPT_RESTRICTIVE")) {
+        die("skip for ICU version < 53");
+    }
+?>
 --FILE--
 <?php
 $r = new ReflectionClass("Spoofchecker");
diff --git a/ext/intl/tests/spoofchecker_unknown_restriction_level.phpt b/ext/intl/tests/spoofchecker_unknown_restriction_level.phpt
index 187be350f59..0d823540f37 100644
--- a/ext/intl/tests/spoofchecker_unknown_restriction_level.phpt
+++ b/ext/intl/tests/spoofchecker_unknown_restriction_level.phpt
@@ -5,6 +5,8 @@
 --SKIPIF--
 <?php
 if (!class_exists("Spoofchecker")) print 'skip';
+
+if (!method_exists(new Spoofchecker(), 'setRestrictionLevel')) print 'skip for ICU version < 53';
 ?>
 --FILE--
 <?php