This document describes the patches applied to PHP's main/main.c file for each PHP version.
The phan-demo uses PHP's embed SAPI to run PHP code in WebAssembly. By default, PHP's embed SAPI doesn't write errors to stderr when display_errors = "stderr" is set. The patch removes the SAPI name check to allow stderr output regardless of SAPI.
The patch modifies the error display logic in the php_error_cb function:
Original code:
/* Write CLI/CGI errors to stderr if display_errors = "stderr" */
if ((!strcmp(sapi_module.name, "cli") || !strcmp(sapi_module.name, "cgi") || !strcmp(sapi_module.name, "phpdbg")) &&
PG(display_errors) == PHP_DISPLAY_ERRORS_STDERR
) {
fprintf(stderr, "%s: ", error_type_str);
// ... error output ...
}Patched code:
/* Write errors to stderr if display_errors = "stderr" regardless of sapi (Phan Demo patch for "embed" sapi) */
if (
PG(display_errors) == PHP_DISPLAY_ERRORS_STDERR
) {
fprintf(stderr, "%s: ", error_type_str);
// ... error output ...
}- Removed SAPI name checks:
!strcmp(sapi_module.name, "cli"), etc. - Updated comment to reflect the change
- This allows the "embed" SAPI (used by WebAssembly) to write errors to stderr
- Source: PHP 8.1 branch from php-src
- Patch line: ~1345
- Additional notes: PHP 8.1 had some ini handler simplifications already applied
- Source: PHP 8.2 branch from php-src
- Patch line: ~1359
- Additional notes: Similar structure to 8.1
- Source: PHP 8.3 branch from php-src
- Patch line: ~1370
- Additional notes: Uses
fwrite()for message output (slightly different from other versions)
- Source: PHP 8.4 branch from php-src
- Patch line: ~1411
- Additional notes: This was the original version used
- Source: PHP 8.5 branch from php-src
- Patch line: ~1482
- Additional notes: Latest development version
PHP's internal API changes between versions. While the patch is conceptually the same, the exact line numbers and surrounding code differ. Using version-specific files ensures:
- Compatibility: Each PHP version gets the correct patch
- Maintainability: Easy to update patches when PHP versions change
- Reliability: No risk of applying patches to wrong line numbers
If you need to update or regenerate these patches:
-
Checkout the desired PHP version branch in php-src:
cd ~/php-src git checkout PHP-8.X
-
Copy the original main.c:
cp main/main.c /path/to/phan-demo/main-8.X.c
-
Apply the patch:
cd /path/to/phan-demo # Update comment sed -i 's|Write CLI/CGI errors to stderr|Write errors to stderr if display_errors = "stderr" regardless of sapi (Phan Demo patch for "embed" sapi)|' main-8.X.c # Remove SAPI check line=$(grep -n 'if ((!strcmp(sapi_module.name, "cli")' main-8.X.c | cut -d: -f1) sed -i "${line}s|.*if ((!strcmp.*|\t\t\t\t\tif (|" main-8.X.c
-
Verify the patch:
# Check the patched section sed -n "$((line-1)),$((line+6))p" main-8.X.c
After applying patches, verify by:
- Building the specific PHP version
- Running sample code with intentional errors
- Confirming errors appear in stderr output
- Testing with
display_errors = "stderr"in pib_eval.c
When new PHP versions are released:
- Create new main-8.X.c file using the process above
- Add version to
PHP_VERSIONSarray inbuild-multi.sh - Update
index.htmldropdown with new version - Update documentation
Instead of patching main.c, alternatives could include:
- Setting
display_errors = 1and capturing output differently - Modifying pib_eval.c to redirect output streams
- Using a custom error handler in PHP code
However, the main.c patch is the cleanest solution as it allows proper stderr output at the PHP level.