Commit f58b95ef595 for php.net

commit f58b95ef5958ae5f18d62874e5419bc2810508cb
Author: Sebastian Bergmann <sb@sebastian-bergmann.de>
Date:   Sun May 24 23:21:07 2026 +0200

    ini_get_all(): Add `builtin_default_value` column (#22134)

    Closes GH-22133.

    Co-authored-by: Tim Düsterhus <tim@bastelstu.be>

diff --git a/NEWS b/NEWS
index d5e3f6d71b9..4caae2db920 100644
--- a/NEWS
+++ b/NEWS
@@ -224,6 +224,8 @@ PHP                                                                        NEWS
     null bytes. (Weilin Du)
   . proc_open() now raises a ValueError when the $cwd argument contains
     null bytes. (Weilin Du)
+  . ini_get_all() now includes the built-in default value in the details.
+    (sebastian)

 - Streams:
   . Added so_keepalive, tcp_keepidle, tcp_keepintvl and tcp_keepcnt stream
diff --git a/UPGRADING b/UPGRADING
index 7f805496db7..f2b6303a923 100644
--- a/UPGRADING
+++ b/UPGRADING
@@ -270,6 +270,12 @@ PHP 8.6 UPGRADE NOTES
     when not null, and on failure, gives the error code (one of the EAI_*
     constants).

+- Standard:
+  . ini_get_all() now includes a "builtin_default_value" element for each
+    directive when $details is true. It holds the built-in default value of
+    the directive (or null if it has none), independent of values set in
+    php.ini, on the command line, or at runtime.
+
 ========================================
 6. New Functions
 ========================================
diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c
index 29ed6ddf14e..2a0e7a78673 100644
--- a/ext/standard/basic_functions.c
+++ b/ext/standard/basic_functions.c
@@ -1955,6 +1955,12 @@ PHP_FUNCTION(ini_get_all)
 					add_assoc_null(&option, "local_value");
 				}

+				if (ini_entry->def->value) {
+					add_assoc_stringl(&option, "builtin_default_value", ini_entry->def->value, ini_entry->def->value_length);
+				} else {
+					add_assoc_null(&option, "builtin_default_value");
+				}
+
 				add_assoc_long(&option, "access", ini_entry->modifiable);

 				zend_symtable_update(Z_ARRVAL_P(return_value), ini_entry->name, &option);
diff --git a/ext/standard/tests/general_functions/ini_get_all.phpt b/ext/standard/tests/general_functions/ini_get_all.phpt
index 2b71b474a01..c54b39ac332 100644
--- a/ext/standard/tests/general_functions/ini_get_all.phpt
+++ b/ext/standard/tests/general_functions/ini_get_all.phpt
@@ -33,29 +33,35 @@
 }
 array(3) {
   ["pcre.backtrack_limit"]=>
-  array(3) {
+  array(4) {
     ["global_value"]=>
     string(7) "1000000"
     ["local_value"]=>
     string(7) "1000000"
+    ["builtin_default_value"]=>
+    string(7) "1000000"
     ["access"]=>
     int(7)
   }
   ["pcre.jit"]=>
-  array(3) {
+  array(4) {
     ["global_value"]=>
     string(1) "1"
     ["local_value"]=>
     string(1) "1"
+    ["builtin_default_value"]=>
+    string(1) "1"
     ["access"]=>
     int(7)
   }
   ["pcre.recursion_limit"]=>
-  array(3) {
+  array(4) {
     ["global_value"]=>
     string(6) "100000"
     ["local_value"]=>
     string(6) "100000"
+    ["builtin_default_value"]=>
+    string(6) "100000"
     ["access"]=>
     int(7)
   }
diff --git a/ext/standard/tests/general_functions/ini_get_all_builtin_default_value.phpt b/ext/standard/tests/general_functions/ini_get_all_builtin_default_value.phpt
new file mode 100644
index 00000000000..82de8781caa
--- /dev/null
+++ b/ext/standard/tests/general_functions/ini_get_all_builtin_default_value.phpt
@@ -0,0 +1,33 @@
+--TEST--
+ini_get_all() exposes the built-in default value independent of configuration and runtime changes
+--INI--
+precision=8
+--FILE--
+<?php
+
+// precision is configured to 8 above, but its compiled-in default is 14.
+$all = ini_get_all(null, true);
+
+var_dump($all["precision"]["global_value"]);
+var_dump($all["precision"]["local_value"]);
+var_dump($all["precision"]["builtin_default_value"]);
+
+// A runtime change must not affect builtin_default_value.
+ini_set("precision", "3");
+
+$all = ini_get_all(null, true);
+
+var_dump($all["precision"]["global_value"]);
+var_dump($all["precision"]["local_value"]);
+var_dump($all["precision"]["builtin_default_value"]);
+
+echo "Done\n";
+?>
+--EXPECT--
+string(1) "8"
+string(1) "8"
+string(2) "14"
+string(1) "8"
+string(1) "3"
+string(2) "14"
+Done
diff --git a/ext/standard/tests/general_functions/ini_get_all_builtin_default_value_null.phpt b/ext/standard/tests/general_functions/ini_get_all_builtin_default_value_null.phpt
new file mode 100644
index 00000000000..efd86eb947e
--- /dev/null
+++ b/ext/standard/tests/general_functions/ini_get_all_builtin_default_value_null.phpt
@@ -0,0 +1,33 @@
+--TEST--
+ini_get_all() reports a null built-in default value for a directive that has no compiled-in default
+--INI--
+error_append_string=FOO
+--FILE--
+<?php
+
+// error_append_string is configured above, but it has no compiled-in default,
+// so builtin_default_value must be null regardless of configuration or runtime changes.
+$all = ini_get_all(null, true);
+
+var_dump($all["error_append_string"]["global_value"]);
+var_dump($all["error_append_string"]["local_value"]);
+var_dump($all["error_append_string"]["builtin_default_value"]);
+
+ini_set("error_append_string", "BAR");
+
+$all = ini_get_all(null, true);
+
+var_dump($all["error_append_string"]["global_value"]);
+var_dump($all["error_append_string"]["local_value"]);
+var_dump($all["error_append_string"]["builtin_default_value"]);
+
+echo "Done\n";
+?>
+--EXPECT--
+string(3) "FOO"
+string(3) "FOO"
+NULL
+string(3) "FOO"
+string(3) "BAR"
+NULL
+Done