From d85db34c216752ad4cdb07db13538817f2ec314f Mon Sep 17 00:00:00 2001 From: "Hans Krentel (hakre)" Date: Tue, 23 Jun 2026 17:36:29 +0200 Subject: [PATCH] More standard conform display of errors Rationale Users may execute the configure.php script within any SAPI their PHP program of choice allows them, and the configure PHP script makes very little judgment about that. In PHP 4.2 the experiment with a dedicated PHP CLI SAPI was begun, with general availability in the next minor version. It underwent more and more improvements, and since PHP 5.1 the CLI SAPI offers an interactive shell. This PHP CLI SAPI is specifically intended to execute PHP scripts *not* within a webserver environment, but on the command line; for example when the user is PHP-scripting in their shell. The 'PHP CLI SAPI' defines the 'STDERR' constant as a convenience feature (next to the 'STDIN' and 'STDOUT' constants), unless some environmental situation prevents that for the one or other standard stream. This feature is available only in the PHP CLI SAPI, therefore: Given the configure.php script is evaluated by PHP, when the 'STDERR' constant is defined, then upgrade the display of errors [1]. This change is lifting the diagnostic output to the standard error channel, 'standard error' (aka 'stderr', file-descriptor number two, value 2), and by that shifting all PHP diagnostic messages (aka 'errors'). These errors are now on their standard channel, that streams important diagnostics, aka errors, to the user of the script. The place where they belong on the command-line, not any longer interfering on the output channel. This is in the tradition to not print the error message on paper between some text on page x of n, but on the display where they are useful, e.g. the diagnostic channel where the printing has been invoked, or the display of the printer itself, if it has one. The traditional use of a (configure.)php script in a PHP SAPI that outputs on the users request via an HTTP client is reasonably unaffected. Implementation Subsumizes the change under the speaking function name 'errorsAll'. It returns the 'E_ALL' constant value for the standard error-reporting under the configure.php script invocation and improves setting the ini options by collecting errors, and given there are some, throws them under the PHP 7/8 Error protocol en-groupe. NOTE: Under an error during all ini_set() operations, configure.php now finally throws and exits in FAILURE (not as previously ignoring all those errors) - this is to *fail-fast* [2]. To give the full error picture, a small errorsWrap() helper function has been added that allows to collect errors over multiple operations, and 'wraps' one (or more) nicely into one Error message, as a Stringable Throwable, e.g. it can be shown, logged, or thrown. The errorsAll() function serves as a usage example. The implementation is maintaining in top-down direction, based on the first-time-bottom-up implementation (1st 'errors_are_bad', then 'errorbox') in the error diagnostics handling scope of the configuration. [1] For PHP startup-errors it might be too late, but we do it intentionally nevertheless to make the option values available via a 'php.ini' file or ini_get(), e.g. when configure.php delegates to other PHP scripts under the same configuration. It should go without writing that an improvement there certainly is possible as well, but unrelated and independent of this change. [2] 'fail-fast': If early configuration conditions are already failing, the configure script can do a better job by directly failing, as it has already seen that it is not able to configure itself for any kind of diagnostics that wouldn't even remotely match their names; see "Fail-Fast System" in the English Wikipedia to explore in a more technical context . --- configure.php | 41 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/configure.php b/configure.php index 4b9380c1ff..2902ca73f5 100755 --- a/configure.php +++ b/configure.php @@ -19,10 +19,7 @@ +----------------------------------------------------------------------+ */ -ini_set( 'display_errors' , 1 ); -ini_set( 'display_startup_errors' , 1 ); -error_reporting( E_ALL ); - +errorsAll(); ob_implicit_flush(); libxml_use_internal_errors(true); @@ -121,6 +118,42 @@ function realpain( string $path , bool $touch = false , bool $mkdir = false ) : return $path; } +function errorsAll(): void { + $ini = [ + 'display_errors' => 1 + defined('STDERR'), + 'display_startup_errors' => 1 + defined('STDERR'), + 'error_reporting' => E_ALL, + ]; + + foreach ($ini as $option => $value) { + $result = ini_set($option, $value); + if ($result === false) { + $errors[] = sprintf('ini setting "%s"', $option); + } + } + + if (isset($errors)) { + throw errorsWrap(sprintf('php.ini errors (%d)', count($errors)), ...$errors); + } + + error_reporting(E_ALL); +} + +function errorsWrap(string|null ...$err): Error|null { + $errors = null; + foreach ($err as $e) { + if (isset($e)) { + $errors[] = $e; + } + } + + if (empty($errors)) { + return null; + } + + return new Error(implode("\n ", $errors)); +} + function errbox($msg) { $len = strlen($msg)+4; $line = "+" . str_repeat("-", $len) . "+";