148

I have written this simple piece of code :

$ch = curl_init();

//Set options
curl_setopt($ch, CURLOPT_URL, "http://www.php.net");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$website_content = curl_exec ($ch);

In my case $website_content comes as false. Can anyone suggest/advice something what could be going wrong?

hakre
  • 193,403
  • 52
  • 435
  • 836
Adithya
  • 2,923
  • 5
  • 33
  • 47

3 Answers3

300

Error checking and handling is the programmer's friend. Check the return values of the initializing and executing cURL functions. curl_error() and curl_errno() will contain further information in case of failure:

try {
    $ch = curl_init();

    // Check if initialization had gone wrong*    
    if ($ch === false) {
        throw new Exception('failed to initialize');
    }

    // Better to explicitly set URL
    curl_setopt($ch, CURLOPT_URL, 'http://example.com/');
    // That needs to be set; content will spill to STDOUT otherwise
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    // Set more options
    curl_setopt(/* ... */);
    
    $content = curl_exec($ch);

    // Check the return value of curl_exec(), too
    if ($content === false) {
        throw new Exception(curl_error($ch), curl_errno($ch));
    }

    // Check HTTP return code, too; might be something else than 200
    $httpReturnCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

    /* Process $content here */

} catch(Exception $e) {

    trigger_error(sprintf(
        'Curl failed with error #%d: %s',
        $e->getCode(), $e->getMessage()),
        E_USER_ERROR);

} finally {
    // Close curl handle unless it failed to initialize
    if (is_resource($ch)) {
        curl_close($ch);
    }
}

* The curl_init() manual states:

Returns a cURL handle on success, FALSE on errors.

I've observed the function to return FALSE when you're using its $url parameter and the domain could not be resolved. If the parameter is unused, the function might never return FALSE. Always check it anyways, though, since the manual doesn't clearly state what "errors" actually are.

Linus Kleen
  • 33,871
  • 11
  • 91
  • 99
  • 10
    +1: Simple and straight trouble-shooting for curl in PHP on `curl_exec` FALSE return. - [Curl Verbose Mode in PHP example](http://stackoverflow.com/a/9571305/367456) – hakre Nov 09 '12 at 20:10
  • and do not forget curl_close($ch); – Rafik Bari Apr 27 '18 at 16:31
  • It's implicitly closed when the variable goes out of scope, but sure. I made it a complete example. Thanks, @RafikBari. – Linus Kleen Apr 28 '18 at 10:30
  • And make sure to call `curl_close` after `curl_error` and `curl_errno`, otherwise you'll get a `false` here, too. Happened to me. True story. – Wu Wei Jan 31 '20 at 10:07
  • In my case I had called curl_close() before calling curl_exec(). This answer set me straight after pulling my code apart several times. – Valkay Mar 15 '21 at 16:44
  • @Valkay Close before exec? Are you running that code in a loop? – Linus Kleen Mar 29 '21 at 16:19
  • 1
    +1 In my case the error was related to HTTP 2.0 - `HTTP/2 stream 0 was not closed cleanly: PROTOCOL_ERROR (err 1)`. cURL stopped working suddenly, and I had no idea why - nothing was changed on my end, nor on the remote end. Using `curl_error($ch)` helped debug it. – FiddlingAway Sep 01 '22 at 13:30
42

In my case I need to set VERIFYHOST and VERIFYPEER to false, like this:

curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);

before the call to curl_exec($ch).

Because i am working between two development environments with self-assigned certificates. With valid certificates there is no need to set VERIFYHOST and VERIFYPEER to false because the curl_exec($ch) method will work and return the response you expect.

DanielaG
  • 539
  • 4
  • 3
3

This happened to me yesterday and in my case was because I was following a PDF manual to develop some module to communicate with an API and while copying the link directly from the manual, for some odd reason, the hyphen from the copied link was in a different encoding and hence the curl_exec() was always returning false because it was unable to communicate with the server.

It took me a couple hours to finally understand the diference in the characters bellow:

https://www.e‐example.com/api
https://www.e-example.com/api

Every time I tried to access the link directly from a browser it converted to something likehttps://www.xn--eexample-0m3d.com/api.

It may seem to you that they are equal but if you check the encoding of the hyphens here you'll see that the first hyphen is a unicode characters U+2010 and the other is a U+002D.

Hope this helps someone.

CIRCLE
  • 4,501
  • 5
  • 37
  • 56