首页 Function Compute Function Compute FAQ Code development FAQ about PHP runtimes What do I do if the Cannot modify header information - headers already sent by (output started at ... message is reported when an HTTP trigger is used in a PHP environment?

What do I do if the Cannot modify header information - headers already sent by (output started at ... message is reported when an HTTP trigger is used in a PHP environment?

更新时间: 2026-04-01 00:04:34

This error occurs when your PHP code attempts to send an HTTP header after output has already started. In the Function Compute (FC) PHP runtime, the fix depends on which HTTP trigger mode your function uses.

For additional context, see the community article on this error.

HTTP trigger modes

The PHP runtime HTTP trigger supports two modes:

  • Without `fcPhpCgiProxy`: The function handler returns a Response object directly. This is the recommended mode for API-style functions.

  • With `fcPhpCgiProxy`: The function acts as an Apache/Nginx location block, forwarding requests to php-fpm. This mode supports traditional PHP web projects where header(), setcookie(), and similar functions work as expected.

Root cause

When PHP produces its first output (echo, print, or any whitespace outside PHP tags), it flushes all collected headers. After that point, any call to a function that modifies HTTP headers raises:

Cannot modify header information - headers already sent by (output started at ...)

The following PHP functions trigger this error when running without fcPhpCgiProxy:

  • header() and header_remove()

  • setcookie() and setrawcookie()

  • session_start() and session_regenerate_id()

Solution

Without fcPhpCgiProxy

Pass all response headers through the Response object constructor. Do not call header(), setcookie(), or similar functions separately.

<?php
use RingCentral\Psr7\Response;

function handler($request, $context): Response
{
    return new Response(
        200,
        array(
            "custom_header1" => "v1",
            "custom_header2" => ["v2", "v3"],
            "Set-Cookie" => urlencode("test php") . '=' . urlencode('test;more')
        ),
        "hello world"
    );
}

With fcPhpCgiProxy

The fcPhpCgiProxy mode runs PHP files through php-fpm, so header(), setcookie(), and session functions work normally. The entry function forwards the request to the proxy, and the target PHP file handles headers in the standard PHP way.

Entry function file:

<?php
function http_fc_func_cgi($request, $context): Response
{
    $proxy = $GLOBALS['fcPhpCgiProxy'];
    return $proxy->requestPhpCgi(
        $request,
        __DIR__ . '/www',
        "index.php",
        ['SERVER_NAME' => 'example.com']
    );
}

Target PHP file (inside www/):

<?php
http_response_code(200);
header('Content-Type: text/html');
echo "<html><body>Hello world</body></html>";
?>

Legacy code with ob_start()

If existing PHP code mixes header() calls with output and cannot be easily refactored, use output buffering as a temporary workaround. Call ob_start() at the start of your script to buffer all output, which allows header() calls to succeed even after echo statements.

<?php
ob_start();
echo "some output";
header('X-Custom-Header: value'); // works because output is buffered
$output = ob_get_clean();
Note: Output buffering is a workaround for legacy code. For new functions, use the Response object pattern (without fcPhpCgiProxy) or migrate to fcPhpCgiProxy mode.

Which mode should I use?

ScenarioRecommended mode
API functions returning JSON, XML, or simple responsesWithout fcPhpCgiProxy — use the Response object
Web applications or projects migrated from Apache/NginxWith fcPhpCgiProxy — standard PHP header functions work as expected
上一篇: What to do when Notices or Warnings in the PHP runtime cause a third-party library (aliyun-openapi-php-sdk) to fail? 下一篇: Change the session directory for an HTTP trigger in PHP
阿里云首页 函数计算 相关技术圈