diff --git a/ext/standard/head.c b/ext/standard/head.c index 5bdae98dfce56..7d223c646f215 100644 --- a/ext/standard/head.c +++ b/ext/standard/head.c @@ -363,6 +363,18 @@ PHP_FUNCTION(http_response_code) if (response_code) { + if (SG(headers_sent) && !SG(request_info).no_headers) { + const char *output_start_filename = php_output_get_start_filename(); + int output_start_lineno = php_output_get_start_lineno(); + + if (output_start_filename) { + php_error_docref(NULL, E_WARNING, "Cannot set response code - headers already sent " + "(output started at %s:%d)", output_start_filename, output_start_lineno); + } else { + php_error_docref(NULL, E_WARNING, "Cannot set response code - headers already sent"); + } + RETURN_FALSE; + } zend_long old_response_code; old_response_code = SG(sapi_headers).http_response_code; diff --git a/ext/standard/tests/general_functions/http_response_code.phpt b/ext/standard/tests/general_functions/http_response_code.phpt index ab290c3cefe19..8f8b87511a3b9 100644 --- a/ext/standard/tests/general_functions/http_response_code.phpt +++ b/ext/standard/tests/general_functions/http_response_code.phpt @@ -21,8 +21,17 @@ var_dump( // Get the new response code http_response_code() ); +echo "Now we've sent the headers\n"; +var_dump( + // This should fail + http_response_code(500) +); ?> ---EXPECT-- +--EXPECTF-- bool(false) bool(true) int(201) +Now we've sent the headers + +Warning: http_response_code(): Cannot set response code - headers already sent (output started at %s:%d) in %s on line %d +bool(false) diff --git a/sapi/fpm/tests/log-suppress-output.phpt b/sapi/fpm/tests/log-suppress-output.phpt index 5a5e7bb9544ba..a507180e99227 100644 --- a/sapi/fpm/tests/log-suppress-output.phpt +++ b/sapi/fpm/tests/log-suppress-output.phpt @@ -38,7 +38,7 @@ function doTestCalls(FPM\Tester &$tester, bool $expectSuppressableEntries) $tester->request(query: 'test=output', uri: '/ping')->expectBody('pong', 'text/plain'); $tester->expectAccessLog("'GET /ping?test=output' 200", suppressable: false); - $tester->request(headers: ['X_ERROR' => 1])->expectBody('Not OK'); + $tester->request(headers: ['X_ERROR' => 1])->expectStatus('500 Internal Server Error')->expectBody('Not OK'); $tester->expectAccessLog("'GET /log-suppress-output.src.php' 500", suppressable: false); $tester->request()->expectBody('OK'); @@ -54,8 +54,8 @@ function doTestCalls(FPM\Tester &$tester, bool $expectSuppressableEntries) $src = <<