From bf6e6534f60a9578d0d84552eab5a52b8232c235 Mon Sep 17 00:00:00 2001 From: Alexander Stecher <45872305+AlliBalliBaba@users.noreply.github.com> Date: Tue, 28 Oct 2025 10:57:50 +0100 Subject: [PATCH] fix: exit() and dd() support in worker mode (#1946) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Verifies exit behavior. * formatting * Checks for actual exit. * Fixes test. * Fixes test. * Update testdata/dd.php Co-authored-by: Kévin Dunglas --------- Co-authored-by: Kévin Dunglas --- caddy/caddy_test.go | 24 ++++++++++++++++++++++++ frankenphp.c | 14 +++++++++----- testdata/dd.php | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 5 deletions(-) create mode 100644 testdata/dd.php diff --git a/caddy/caddy_test.go b/caddy/caddy_test.go index efd9e30a..91738568 100644 --- a/caddy/caddy_test.go +++ b/caddy/caddy_test.go @@ -1423,3 +1423,27 @@ func TestWorkerMatchDirectiveWithoutFileServer(t *testing.T) { // the request should completely fall through the php_server module tester.AssertGetResponse("http://localhost:"+testPort+"/static.txt", http.StatusNotFound, "Request falls through") } + +func TestDd(t *testing.T) { + tester := caddytest.NewTester(t) + tester.InitServer(` + { + skip_install_trust + admin localhost:2999 + } + + http://localhost:`+testPort+` { + php { + worker ../testdata/dd.php 1 { + match * + } + } + `, "caddyfile") + + // simulate Symfony's dd() + tester.AssertGetResponse( + "http://localhost:"+testPort+"/some-path?output=dump123", + http.StatusInternalServerError, + "dump123", + ) +} diff --git a/frankenphp.c b/frankenphp.c index 69e29ed9..3d124ece 100644 --- a/frankenphp.c +++ b/frankenphp.c @@ -464,12 +464,16 @@ PHP_FUNCTION(frankenphp_handle_request) { /* * If an exception occurred, print the message to the client before - * closing the connection and bailout. + * closing the connection. */ - if (EG(exception) && !zend_is_unwind_exit(EG(exception)) && - !zend_is_graceful_exit(EG(exception))) { - zend_exception_error(EG(exception), E_ERROR); - zend_bailout(); + if (EG(exception)) { + if (!zend_is_unwind_exit(EG(exception)) && + !zend_is_graceful_exit(EG(exception))) { + zend_exception_error(EG(exception), E_ERROR); + } else { + /* exit() will jump directly to after php_execute_script */ + zend_bailout(); + } } frankenphp_worker_request_shutdown(); diff --git a/testdata/dd.php b/testdata/dd.php new file mode 100644 index 00000000..14bafc3e --- /dev/null +++ b/testdata/dd.php @@ -0,0 +1,32 @@ +message = $message; + } + + public function __destruct() + { + if (isset($this->message)) { + echo $this->message; + } + } +} + +$dumper = new Dumper(); + +while (frankenphp_handle_request(function () use ($dumper) { + $dumper->dump($_GET['output'] ?? ''); + exit(1); +})) { + // keep handling requests +} + +echo "we should never reach here\n";