270

I'd like to see what the post fields in the request are before I send it. (For debugging purposes).

The PHP library (class) I am using is already made (not by me), so I am trying to understand it.

As far as I can tell, it uses curl_setopt() to set different options like headers and such and then it uses curl_exec() to send the request.

Ideas on how to see what post fields are being sent?

1

9 Answers 9

492

You can enable the CURLOPT_VERBOSE option Curl, PHP and log that information to a (temporary) CURLOPT_STDERR:

// CURLOPT_VERBOSE: TRUE to output verbose information.
// Writes output to STDERR, 
// -or- the file specified using CURLOPT_STDERR.
curl_setopt($curlHandle, CURLOPT_VERBOSE, true);

$streamVerboseHandle = fopen('php://temp', 'w+');
curl_setopt($curlHandle, CURLOPT_STDERR, $streamVerboseHandle);

You can then read it after curl has done the request:

$result = curl_exec($curlHandle);
if ($result === FALSE) {
    printf("cUrl error (#%d): %s<br>\n",
           curl_errno($curlHandle),
           htmlspecialchars(curl_error($curlHandle)))
           ;
}

rewind($streamVerboseHandle);
$verboseLog = stream_get_contents($streamVerboseHandle);

echo "cUrl verbose information:\n", 
     "<pre>", htmlspecialchars($verboseLog), "</pre>\n";

(I originally answered similar but more extended in a related question.)

More information like metrics about the last request is available via curl_getinfo. This information can be useful for debugging curl requests, too. A usage example, I would normally wrap that into a function:

$version = curl_version();
extract(curl_getinfo($curlHandle));
$metrics = <<<EOD
URL....: $url
Code...: $http_code ($redirect_count redirect(s) in $redirect_time secs)
Content: $content_type Size: $download_content_length (Own: $size_download) Filetime: $filetime
Time...: $total_time Start @ $starttransfer_time (DNS: $namelookup_time Connect: $connect_time Request: $pretransfer_time)
Speed..: Down: $speed_download (avg.) Up: $speed_upload (avg.)
Curl...: v{$version['version']}
EOD;
Sign up to request clarification or add additional context in comments.

7 Comments

fopen option should be 'w+'
@iisisrael: You are right. Corrected. Thanks for the hint.
Before you jump into debugging, however: Try checking the apache log in case an error was tossed (like curl php not being installed, so the function failed!)
Thank you. Unluckily, it does not log all the content of the a POST, as curl -v does.
@MarcoSulla: This is perhaps a different curl version? Compare curl --version and php -i | grep -i curl.
|
198

You can enable the CURLOPT_VERBOSE option:

curl_setopt($curlhandle, CURLOPT_VERBOSE, true);

When CURLOPT_VERBOSE is set, output is written to STDERR or the file specified using CURLOPT_STDERR. The output is very informative.

You can also use tcpdump or wireshark to watch the network traffic.

3 Comments

It is worth noting that this will not work if you have set CURLINFO_HEADER_OUT to TRUE. So far as I can tell...
Than work $info = curl_getinfo($curlhandle); - This comment for myself)
tcpdump/wireshark ftw.
77

Here is a simpler code for the same:

   curl_setopt($ch, CURLOPT_VERBOSE, 1);
   curl_setopt($ch, CURLOPT_STDERR, $fp);

where $fp is a file handle to output errors. For example:

   $fp = fopen(dirname(__FILE__).'/errorlog.txt', 'w');

( Read on http://curl.haxx.se/mail/curlphp-2008-03/0064.html )

1 Comment

I would have liked to use the answer of @Michaël-R- but I didnt get verbose in the PHP log. Logging to a new file like this worked tho.
33

Here is an even simplier way, by writing directly to php error output

curl_setopt($curl, CURLOPT_VERBOSE, true);
curl_setopt($curl, CURLOPT_STDERR, fopen('php://stderr', 'w'));

Comments

33

To just get the info of a CURL request do this:

$response = curl_exec($ch);

$info = curl_getinfo($ch);
var_dump($info);

1 Comment

For "after" response the curl_getinfo its excelent but for malformed urls for example the getinfo returns non info, the opt CURLOPT_VERBOSE its a better for example
11

If you just want a very quick way to debug the result:

$ch = curl_init();
curl_exec($ch);
$curl_error = curl_error($ch);
echo "<script>console.log($curl_error);</script>"

Comments

6

Output debug info to STDERR:

$curlHandler = curl_init();

curl_setopt_array($curlHandler, [
    CURLOPT_URL => 'https://postman-echo.com/get?foo=bar',
    CURLOPT_RETURNTRANSFER => true,

    /**
     * Specify debug option
     */
    CURLOPT_VERBOSE => true,
]);

curl_exec($curlHandler);

curl_close($curlHandler);

Output debug info to file:

$curlHandler = curl_init();

curl_setopt_array($curlHandler, [
    CURLOPT_URL => 'https://postman-echo.com/get?foo=bar',
    CURLOPT_RETURNTRANSFER => true,

    /**
     * Specify debug option.
     */
    CURLOPT_VERBOSE => true,

    /**
     * Specify log file.
     * Make sure that the folder is writable.
     */
    CURLOPT_STDERR => fopen('./curl.log', 'w+'),
]);

curl_exec($curlHandler);

curl_close($curlHandler);

See https://github.com/andriichuk/php-curl-cookbook#debug-request

Comments

1

Another (crude) option is to utilize netcat for dumping the full request:

nc -l -p 8000 -w 3 | tee curldbg.txt

And of course sending the failing request to it:

curl_setup(CURLOPT_URL, "http://localhost/testytest");

Notably that will always hang+fail, since netcat won't ever construct a valid HTTP response. It's really just for inspecting what really got sent. The better option, of course, is using a http request debugging service.

Comments

1

For PHP 8.4+ you can use the option CURLOPT_DEBUGFUNCTION. See document here.

Example:

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://yourdomain');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);// this is not required.
curl_setopt($ch, CURLOPT_VERBOSE, true);


$verboseLog = '';

curl_setopt($ch, CURLOPT_DEBUGFUNCTION, 
    function($curlHandle, $type, $data) use (&$verboseLog)
    {
    switch ($type) {
        case CURLINFO_TEXT:
            $verboseLog .= '(informational text)';
            break;
        case CURLINFO_HEADER_IN:
            $verboseLog .= '(response headers)';
            break;
        case CURLINFO_HEADER_OUT:
            $verboseLog .= '(request headers)';
            break;
        case CURLINFO_DATA_IN:
            $verboseLog .= '(response data)';
            break;
        case CURLINFO_DATA_OUT:
            $verboseLog .= '(request data)';
            break;
        case CURLINFO_SSL_DATA_IN:
            $verboseLog .= '(response SSL data)';
            break;
        case CURLINFO_SSL_DATA_OUT:
            $verboseLog .= '(request SSL data)';
            break;
        default:
            $verboseLog .= '(unknown type ' . $type . ')';
            break;
    }
    $verboseLog .= ' ';
    $verboseLog .= var_export($data, true) . PHP_EOL;
});

$result = curl_exec($ch);

curl_close($ch);


var_dump($result);
var_dump($verboseLog);

You can format verbose message in the option CURLOPT_DEBUGFUNCTION. For more info about why verbose with fopen() show nothing, please read this answer.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.