PHP 8.4: Curl: New CURLOPT_DEBUGFUNCTION option

Version8.4
TypeNew Feature

When a Curl request is made, setting verbose output emits additional debug information throughout the lifetime of the request, which can be helpful to debug failing Curl requests or to log Curl requests.

Curl also provides an option called CURLOPT_DEBUGFUNCTION to set a custom callback function, that gets called instead of the standard verbose output function. When an application needs more control over how the verbose debug information is processed, this option can be useful.

PHP 8.4 Curl extension exposes this libcurl option as the CURLOPT_DEBUGFUNCTION option (for curl_setopt), which accepts a PHP callable value.

The callback gets called multiple times during the Curl request, and the callback can decide what to do with this information.

Curl uses the CURLOPT_DEBUGFUNCTION option in previous PHP versions as well, but with custom handling only to collect HTTP output headers and to expose them as CURLINFO_HEADER_OUT curl_getinfo option.

In PHP 8.4, these two options are not compatible with each other. See the using with CURLINFO_HEADER_OUT for more details.

New Constants

As part of this feature, the following new PHP constants are added:

Debug information types

The callable gets called with an int value of one of the following constants, which indicates what sort of data is passed to the next parameter.

Constant Indication
CURLINFO_TEXT Informational text
CURLINFO_HEADER_IN Header (or header-like) data received from the peer
CURLINFO_HEADER_OUT Header (or header-like) data sent to the peer
CURLINFO_DATA_IN Unprocessed protocol data received from the peer. Even if the data is encoded or compressed, it is not provided decoded nor decompressed to this callback
CURLINFO_DATA_OUT Protocol data sent to the peer
CURLINFO_SSL_DATA_IN SSL/TLS (binary) data received from the peer
CURLINFO_SSL_DATA_OUT SSL/TLS (binary) data sent to the peer

Note that the CURLINFO_HEADER_OUT constant already exists in previous PHP versions. See using with CURLINFO_HEADER_OUT for more details.

CURLOPT_DEBUGFUNCTION option

The CURLOPT_DEBUGFUNCTION Curl option accepts a callable value that gets called every time Curl emits debug information. For the callback to get called, the CURLOPT_VERBOSE option must be enabled as well.

If CURLOPT_VERBOSE is not enabled, the CURLOPT_DEBUGFUNCTION callback does not get called at all.

The CURLOPT_DEBUGFUNCTION callback can be in the following signature:

function foo(CurlHandle $curlHandle, int $type, string $data): void {}
  • CurlHandle $curlHandle: The CurlHandle object.
  • int $type: Indicates what kind of debug information is passed. See the debug information types section for explanations.
  • string $data: The actual debug information.

$ch = curl_init('http://example.com');
curl_setopt($ch, CURLOPT_DEBUGFUNCTION,
    static function(CurlHandle $ch, int $type, string $data): void {
        printf("Debug (%d): %s", $type, $data);
    }
);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_exec($ch);

Outputs:

Debug (0): Host example.com:80 was resolved.
Debug (0): IPv6: ...
Debug (0): IPv4: ...
Debug (0):   Trying ...:80...
Debug (0): Connected to example.com (...) port 80
Debug (0): using HTTP/1.x
Debug (2): GET / HTTP/1.1
Host: example.com
Accept: */*

Debug (0): Request completely sent off
...

Return values from the callable are ignored.

Using with CURLINFO_HEADER_OUT

Note that the PHP Curl extension provides a non-standard option named CURLINFO_HEADER_OUT that returns the output headers of a Curl request. This is not part of libcurl, but the Curl extension uses the CURLOPT_DEBUGFUNCTION libcurl option to capture the CURLINFO_HEADER_OUT data and return them with the curl_getinfo function.

This is a problematic behavior as well as a breakage of the pattern when it uses a CURLINFO_ constant being used as a Curl option. Further, enabling the CURLINFO_HEADER_OUT "option" implicitly enables CURLOPT_VERBOSE.

To ensure backward compatibility, it is not allowed to enable the CURLINFO_HEADER_OUT option after the CURLOPT_DEBUGFUNCTION option is set, and results in a ValueError exception:

$ch = curl_init();
curl_setopt($ch, CURLOPT_DEBUGFUNCTION,static function() {});
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
ValueError: CURLINFO_HEADER_OUT option must not be set when the CURLOPT_DEBUGFUNCTION option is set

Setting the CURLOPT_DEBUGFUNCTION option after CURLINFO_HEADER_OUT is allowed, and overrides the CURLINFO_HEADER_OUT option.

Backward Compatibility Impact

CURLOPT_DEBUGFUNCTION and the series of constants are new to PHP 8.4. The CURLOPT_DEBUGFUNCTION option is added to libcurl on libcurl 7.9.6, and because PHP 8.4 requires libcurl 7.61.0 or later, all PHP 8.4 Curl builds will have this feature available.


CURLOPT_DEBUGFUNCTION Implementation