Link to home
Start Free TrialLog in
Avatar of Dave Baldwin
Dave BaldwinFlag for United States of America

asked on

PHP curl issue VERBOSE output

I have a PHP curl program that works fine.  However, on PHP 5.3.28, I get the expected 'VERBOSE' output with lots of info.  On PHP 5.4, 5.6, and 7.1 I do not get it from the same identical program.  Does anyone know how to get it on these versions?
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

I have not seen this personally but there is this bug report that might have some bearing

https://bugs.php.net/bug.php?id=65348

Basically says that CURLOPT_VERBOSE does not work with CURLOPT_HEADER_OUT - and they are not going to fix it.
Avatar of Dave Baldwin

ASKER

That's not it.  None of my scripts use CURLOPT_HEADER_OUT.
Can you post some code so I can test here.
Dave: This works well enough for me.  I'm testing on PHP 5.5+   See if you're able to get what you need from it.

<?php // demo/curl_get_example.php
/**
 * Demonstrate the basics of cURL GET-method request
 *
 * http://php.net/manual/en/function.curl-setopt.php
 * http://curl.haxx.se/libcurl/c/libcurl-errors.html
 */
error_reporting(E_ALL);


// USAGE EXAMPLE: BECAUSE IT IS ON MY SERVER, I HAVE HARD-CODED THIS
$url = 'https://twitter.com/RayPaseur';

// TRY THE REMOTE WEB SERVICE
$response = new GET_Response_Object($url);

// SHOW THE WORK PRODUCT
echo "<pre>";
if (!$response->document) var_dump($response); //   ON FAILURE SHOW ERROR INFORMATION
echo htmlentities($response->document);        //   ON SUCCESS SHOW RETURNED DOCUMENT

// OPTIONAL -- SHOW THE COOKIES, IF ANY
echo PHP_EOL;
echo file_get_contents('cookie.txt');


Class GET_Response_Object
{
    public $href, $title, $http_code, $errno, $info, $document;

    public function __construct($href, $user=NULL, $pass=NULL, $get_array=[], $title=NULL)
    {
        // ACTIVATE THIS TO AVOID TIMEOUT FOR LONG RUNNING SCRIPT
        // set_time_limit(10);

        // STORE THE CALL INFORMATION
        $this->href  = $href;
        $this->title = $title;

        // PREPARE THE GET STRING
        $get_string = http_build_query($get_array);
        if ($get_string) $get_string = '?' . $get_string;

        // MAKE THE REQUEST
        if (!$response = $this->my_curl($href, $user, $pass, $get_string))
        {
            // ACTIVATE THIS TO SEE THE ERRORS AS THEY OCCUR
            trigger_error("Errno: $this->errno; HTTP: $this->http_code; URL: $this->href", E_USER_WARNING);
        }
        else
        {
            return $response;
        }
    }

    protected function my_curl($url, $user, $pass, $get_string, $timeout=3)
    {
        // PREPARE THE CURL CALL
        $curl = curl_init();

        // HEADERS AND OPTIONS APPEAR TO BE A FIREFOX BROWSER REFERRED BY GOOGLE
        $header[] = "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5";
        $header[] = "Cache-Control: max-age=0";
        $header[] = "Connection: keep-alive";
        $header[] = "Keep-Alive: 300";
        $header[] = "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7";
        $header[] = "Accept-Language: en-us,en;q=0.5";
        $header[] = "Pragma: "; // BROWSERS USUALLY LEAVE THIS BLANK

        // SET THE CURL OPTIONS - SEE http://php.net/manual/en/function.curl-setopt.php
        curl_setopt( $curl, CURLOPT_URL,            $url . $get_string  );
        curl_setopt( $curl, CURLOPT_USERAGENT,      'Mozilla/5.0 (Windows NT 6.1; rv:49.0) Gecko/20100101 Firefox/49.0'  );
        curl_setopt( $curl, CURLOPT_HTTPHEADER,     $header  );
        curl_setopt( $curl, CURLOPT_REFERER,        'https://www.google.com'  );
        curl_setopt( $curl, CURLOPT_ENCODING,       'gzip,deflate'  );
        curl_setopt( $curl, CURLOPT_AUTOREFERER,    TRUE  );
        curl_setopt( $curl, CURLOPT_RETURNTRANSFER, TRUE  );
        curl_setopt( $curl, CURLOPT_FOLLOWLOCATION, TRUE  );
        curl_setopt( $curl, CURLOPT_TIMEOUT,        $timeout  );
        curl_setopt( $curl, CURLOPT_HTTPAUTH,       CURLAUTH_ANY );
        curl_setopt( $curl, CURLOPT_USERPWD,        "$user:$pass" );

        // GET GOOD ERROR MESSAGES
        curl_setopt( $curl, CURLOPT_VERBOSE,        TRUE   );
        curl_setopt( $curl, CURLOPT_FAILONERROR,    TRUE   );

        // IF USING SSL, THIS INFORMATION MAY BE IMPORTANT -- UNDERSTAND THE SECURITY RISK!
        // http://php.net/manual/en/function.curl-setopt.php#110457
        // http://php.net/manual/en/function.curl-setopt.php#115993
        // REDACTED IN 2015 curl_setopt( $curl, CURLOPT_SSLVERSION, 3 );
        curl_setopt( $curl, CURLOPT_SSL_VERIFYHOST, FALSE  );
        curl_setopt( $curl, CURLOPT_SSL_VERIFYPEER, FALSE  );

        // SET THE LOCATION OF THE COOKIE JAR (THIS FILE WILL BE OVERWRITTEN)
        curl_setopt( $curl, CURLOPT_COOKIEFILE,     'cookie.txt' );
        curl_setopt( $curl, CURLOPT_COOKIEJAR,      'cookie.txt' );

        // RUN THE CURL REQUEST AND GET THE RESULTS
        $this->document  = curl_exec($curl);
        $this->errno     = curl_errno($curl);
        $this->info      = curl_getinfo($curl);
        $this->http_code = $this->info['http_code'];
        curl_close($curl);

        return $this;
    }
}

Open in new window

No, that doesn't come close.  While I can 'get' your twitter page, I'm not looking for the page but the info that curl can return.  Two examples below.

curl-ssl-connect.php PHP 5.3.28 on Windows XP
Error # 0 : Error message

Array
(
    [url] => https://www.tanthrough.com/
    [content_type] => text/html
    [http_code] => 200
    [header_size] => 326
    [request_size] => 201
    [filetime] => -1
    [ssl_verify_result] => 0
    [redirect_count] => 0
    [total_time] => 1.719
    [namelookup_time] => 0.016
    [connect_time] => 0.094
    [pretransfer_time] => 1.625
    [size_upload] => 17
    [size_download] => 8805
    [speed_download] => 5122
    [speed_upload] => 9
    [download_content_length] => 8805
    [upload_content_length] => 17
    [starttransfer_time] => 1.703
    [redirect_time] => 0
    [certinfo] => Array
        (
        )

    [redirect_url] => 
)
* Adding handle: conn: 0x1fcecd0
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 0 (0x1fcecd0) send_pipe: 1, recv_pipe: 0
* About to connect() to www.tanthrough.com port 443 (#0)
*   Trying 69.65.27.153...
* Connected to www.tanthrough.com (69.65.27.153) port 443 (#0)
* successfully set certificate verify locations:
*   CAfile: cacert.pem
  CApath: none
* SSL connection using DHE-RSA-AES128-SHA
* Server certificate:
* 	 subject: CN=www.tanthrough.com
* 	 start date: 2016-08-04 00:00:00 GMT
* 	 expire date: 2019-11-03 23:59:59 GMT
* 	 subjectAltName: www.tanthrough.com matched
* 	 issuer: C=US; O=GeoTrust Inc.; CN=RapidSSL SHA256 CA
* 	 SSL certificate verify ok.
> POST / HTTP/1.1
User-Agent: Mozilla/5.0
Host: www.tanthrough.com
Accept: */*
Accept-Encoding: deflate, gzip
Content-Length: 17
Content-Type: application/x-www-form-urlencoded

* upload completely sent off: 17 out of 17 bytes
< HTTP/1.1 200 OK
< Date: Mon, 06 Feb 2017 16:11:44 GMT
* Server Apache/2.4.23 (Unix) OpenSSL/1.0.1e-fips mod_bwlimited/1.4 is not blacklisted
< Server: Apache/2.4.23 (Unix) OpenSSL/1.0.1e-fips mod_bwlimited/1.4
< Last-Modified: Fri, 03 Feb 2017 20:30:15 GMT
< ETag: "543769-7092-547a62647a0e4-gzip"
< Accept-Ranges: bytes
< Vary: Accept-Encoding
< Content-Encoding: gzip
< Content-Length: 8805
< Content-Type: text/html
< 
* Connection #0 to host www.tanthrough.com left intact

Open in new window


curl-ssl-connect.php PHP 5.6.28 on davidibaldwin.org
Error # 0 : Error message

Array
(
    [url] => https://www.tanthrough.com/
    [content_type] => text/html
    [http_code] => 200
    [header_size] => 326
    [request_size] => 201
    [filetime] => -1
    [ssl_verify_result] => 0
    [redirect_count] => 0
    [total_time] => 0.747376
    [namelookup_time] => 0.510508
    [connect_time] => 0.528259
    [pretransfer_time] => 0.72524
    [size_upload] => 17
    [size_download] => 8805
    [speed_download] => 11781
    [speed_upload] => 22
    [download_content_length] => 8805
    [upload_content_length] => 17
    [starttransfer_time] => 0.746329
    [redirect_time] => 0
    [redirect_url] => 
    [primary_ip] => 69.65.27.153
    [certinfo] => Array
        (
        )

    [primary_port] => 443
    [local_ip] => 198.71.231.57
    [local_port] => 59329
)

Open in new window


And the code.  It is oddly formatted but if I take either section out, it works differently.  I can get other programs to output some of the 'info' but this is the only version that returns all of it.
<?php

function get_web_page( $url,$curl_data )
{
    $options = array(
				CURLOPT_CAINFO => 'cacert.pem',
        CURLOPT_RETURNTRANSFER => true,         // return web page
        CURLOPT_HEADER         => false,        // don't return headers
        CURLOPT_FOLLOWLOCATION => true,         // follow redirects
        CURLOPT_ENCODING       => "",           // handle all encodings
        CURLOPT_USERAGENT      => "Mozilla/5.0",     // who am i
        CURLOPT_AUTOREFERER    => true,         // set referer on redirect
        CURLOPT_CONNECTTIMEOUT => 60,          // timeout on connect
        CURLOPT_TIMEOUT        => 60,          // timeout on response
        CURLOPT_MAXREDIRS      => 10,           // stop after 10 redirects
        CURLOPT_POST           => 1,            // i am sending post data
        CURLOPT_POSTFIELDS     => $curl_data,    // this are my post vars
				CURLOPT_SSLVERSION     => 3,
        CURLOPT_SSL_VERIFYHOST => 2,            // don't verify ssl
        CURLOPT_SSL_VERIFYPEER => true,        //
        CURLOPT_VERBOSE        => 1                //
    );

    $ch      = curl_init($url);
    //curl_setopt_array($ch,$options); only for PHP 5
		curl_setopt($ch,CURLOPT_CAINFO,'cacert.pem');
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_HEADER, false);
		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
		curl_setopt($ch, CURLOPT_ENCODING, "");
		curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0");
		curl_setopt($ch, CURLOPT_AUTOREFERER, true);
		curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);
		curl_setopt($ch, CURLOPT_TIMEOUT, 60);
		curl_setopt($ch, CURLOPT_MAXREDIRS, 10);
		curl_setopt($ch, CURLOPT_POST, 1);
		curl_setopt($ch, CURLOPT_POSTFIELDS, $curl_data);
		curl_setopt($ch, CURLOPT_SSLVERSION, 6);
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
		curl_setopt($ch, CURLOPT_VERBOSE, 1);
    $content = curl_exec($ch);
    $err     = curl_errno($ch);
    $errmsg  = curl_error($ch) ;
    $header  = curl_getinfo($ch);
    curl_close($ch);
		echo "Error # $err : Error message $errmsg";

  //  $header['errno']   = $err;
  //  $header['errmsg']  = $errmsg;
  //  $header['content'] = $content;
    return $header;
}

$curl_data = "var1=60&var2=test";
$url = "https://www.tanthrough.com/";
$response = get_web_page($url,$curl_data);

//print '<pre>';
echo '<pre>';
print_r($response);

?>

Open in new window

What I'm getting looks a lot like your PHP 5.6 result.

Here's what I'm using for the experiment.  It's running on a LAMP server, not Windows.
<?php // demo/temp_dave.php
/**
 * Demonstrate the basics of cURL GET-method request
 *
 * http://php.net/manual/en/function.curl-setopt.php
 * http://curl.haxx.se/libcurl/c/libcurl-errors.html
 */
error_reporting(E_ALL);


// USAGE EXAMPLE: BECAUSE IT IS ON MY SERVER, I HAVE HARD-CODED THIS
$url = 'https://www.tanthrough.com/';

// TRY THE REMOTE WEB SERVICE
$response = new GET_Response_Object($url);

// DISCARD THE DOCUMENT, IF ANY
unset($response->document);

// SHOW EVERYTHING ELSE WE GOT
echo '<pre>';
print_r($response);


Class GET_Response_Object
{
    public $href, $title, $http_code, $errno, $info, $document;

    public function __construct($href, $user=NULL, $pass=NULL, $get_array=[], $title=NULL)
    {
        // ACTIVATE THIS TO AVOID TIMEOUT FOR LONG RUNNING SCRIPT
        // set_time_limit(10);

        // STORE THE CALL INFORMATION
        $this->href  = $href;
        $this->title = $title;

        // PREPARE THE GET STRING
        $get_string = http_build_query($get_array);
        if ($get_string) $get_string = '?' . $get_string;

        // MAKE THE REQUEST
        if (!$response = $this->my_curl($href, $user, $pass, $get_string))
        {
            // ACTIVATE THIS TO SEE THE ERRORS AS THEY OCCUR
            trigger_error("Errno: $this->errno; HTTP: $this->http_code; URL: $this->href", E_USER_WARNING);
        }
        else
        {
            return $response;
        }
    }

    protected function my_curl($url, $user, $pass, $get_string, $timeout=3)
    {
        // PREPARE THE CURL CALL
        $curl = curl_init();

        // HEADERS AND OPTIONS APPEAR TO BE A FIREFOX BROWSER REFERRED BY GOOGLE
        $header[] = "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5";
        $header[] = "Cache-Control: max-age=0";
        $header[] = "Connection: keep-alive";
        $header[] = "Keep-Alive: 300";
        $header[] = "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7";
        $header[] = "Accept-Language: en-us,en;q=0.5";
        $header[] = "Pragma: "; // BROWSERS USUALLY LEAVE THIS BLANK

        // SET THE CURL OPTIONS - SEE http://php.net/manual/en/function.curl-setopt.php
        curl_setopt( $curl, CURLOPT_URL,            $url . $get_string  );
        curl_setopt( $curl, CURLOPT_USERAGENT,      'Mozilla/5.0 (Windows NT 6.1; rv:49.0) Gecko/20100101 Firefox/49.0'  );
        curl_setopt( $curl, CURLOPT_HTTPHEADER,     $header  );
        curl_setopt( $curl, CURLOPT_REFERER,        'https://www.google.com'  );
        curl_setopt( $curl, CURLOPT_ENCODING,       'gzip,deflate'  );
        curl_setopt( $curl, CURLOPT_AUTOREFERER,    TRUE  );
        curl_setopt( $curl, CURLOPT_RETURNTRANSFER, TRUE  );
        curl_setopt( $curl, CURLOPT_FOLLOWLOCATION, TRUE  );
        curl_setopt( $curl, CURLOPT_TIMEOUT,        $timeout  );
        curl_setopt( $curl, CURLOPT_HTTPAUTH,       CURLAUTH_ANY );
        curl_setopt( $curl, CURLOPT_USERPWD,        "$user:$pass" );

        // GET GOOD ERROR MESSAGES
        curl_setopt( $curl, CURLOPT_VERBOSE,        TRUE   );
        curl_setopt( $curl, CURLOPT_FAILONERROR,    TRUE   );

        // IF USING SSL, THIS INFORMATION MAY BE IMPORTANT -- UNDERSTAND THE SECURITY RISK!
        // http://php.net/manual/en/function.curl-setopt.php#110457
        // http://php.net/manual/en/function.curl-setopt.php#115993
        // REDACTED IN 2015 curl_setopt( $curl, CURLOPT_SSLVERSION, 3 );
        curl_setopt( $curl, CURLOPT_SSL_VERIFYHOST, FALSE  );
        curl_setopt( $curl, CURLOPT_SSL_VERIFYPEER, FALSE  );

        // SET THE LOCATION OF THE COOKIE JAR (THIS FILE WILL BE OVERWRITTEN)
        curl_setopt( $curl, CURLOPT_COOKIEFILE,     'cookie.txt' );
        curl_setopt( $curl, CURLOPT_COOKIEJAR,      'cookie.txt' );

        // RUN THE CURL REQUEST AND GET THE RESULTS
        $this->document  = curl_exec($curl);
        $this->errno     = curl_errno($curl);
        $this->info      = curl_getinfo($curl);
        $this->http_code = $this->info['http_code'];
        curl_close($curl);

        return $this;
    }
}

Open in new window

And here's what I'm seeing in the cURL object:
GET_Response_Object Object
(
    [href] => https://www.tanthrough.com/
    [title] => 
    [http_code] => 200
    [errno] => 0
    [info] => Array
        (
            [url] => https://www.tanthrough.com/
            [content_type] => text/html
            [http_code] => 200
            [header_size] => 382
            [request_size] => 444
            [filetime] => -1
            [ssl_verify_result] => 0
            [redirect_count] => 0
            [total_time] => 0.068576
            [namelookup_time] => 0.039308
            [connect_time] => 0.039431
            [pretransfer_time] => 0.065824
            [size_upload] => 0
            [size_download] => 8805
            [speed_download] => 128397
            [speed_upload] => 0
            [download_content_length] => 8805
            [upload_content_length] => -1
            [starttransfer_time] => 0.068032
            [redirect_time] => 0
            [redirect_url] => 
            [primary_ip] => 69.65.27.153
            [certinfo] => Array
                (
                )

            [primary_port] => 443
            [local_ip] => 69.65.27.153
            [local_port] => 53230
        )

)

Open in new window

Switched it to POST and got about the same thing...
POST_Response_Object Object
(
    [href] => https://www.tanthrough.com/
    [title] => 
    [http_code] => 200
    [errno] => 0
    [info] => Array
        (
            [url] => https://www.tanthrough.com/
            [content_type] => text/html
            [http_code] => 200
            [header_size] => 326
            [request_size] => 157
            [filetime] => -1
            [ssl_verify_result] => 0
            [redirect_count] => 0
            [total_time] => 0.044974
            [namelookup_time] => 0.012968
            [connect_time] => 0.01313
            [pretransfer_time] => 0.041971
            [size_upload] => 0
            [size_download] => 8805
            [speed_download] => 195779
            [speed_upload] => 0
            [download_content_length] => 8805
            [upload_content_length] => 0
            [starttransfer_time] => 0.044446
            [redirect_time] => 0
            [redirect_url] => 
            [primary_ip] => 69.65.27.153
            [certinfo] => Array
                (
                )

            [primary_port] => 443
            [local_ip] => 69.65.27.153
            [local_port] => 55768
        )

)

Open in new window

If you look at the bottom of the PHP 5.3 results, you can see that there is much more available.  I just don't know how to get it on any other system.
Yeah, I was looking at that.  Wonder if it has anything to do with Windows?  I have never seen it in a cURL response when running on a LAMP stack.  It looks a bit like step-by-step trace data.  But I don't know how it's getting produced, sorry.
What I am suspecting but don't know how to check, is the the output to STDERR on XP actually goes to STDOUT but not on the other systems.  ??  See CURLOPT_VERBOSE on http://php.net/manual/en/function.curl-setopt.php
>> What I am suspecting but don't know how to check...See CURLOPT_VERBOSE
CURLOPT_VERBOSE      TRUE to output verbose information. Writes output to STDERR, or the file specified using CURLOPT_STDERR.
The description you referred to is telling you how you can check it.  Just include a CURLOPT_STDERR in your options array, or call curl_setopt() providing a file that will hold "messages" destined for stderr:
curl_setopt($ch, CURLOPT_STDERR, 'C:\\path\\to\\your\\curl_error.log');

Open in new window

That doesn't appear to work.  I get...

PHP Warning:  curl_setopt(): supplied argument is not a valid File-Handle resource in C:\Inetpub\wwwroot\dibtest\curl-ssl-connect.php on line 28

I can read the file but it's not writing the 'verbose' output to it.  cURL is great for a lot of things but the documentation just really sucks.  You might have to read the source code to find out what error codes mean.
ASKER CERTIFIED SOLUTION
Avatar of hielo
hielo
Flag of Wallis and Futuna image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Ok, it's finally working.  First the response with curl-ssl-connect.php PHP 5.6.28 on davidibaldwin.org .  As you can see, there is a lot of info available.
Error # 0 : Error message

Array
(
    [url] => https://www.tanthrough.com/
    [content_type] => text/html
    [http_code] => 200
    [header_size] => 326
    [request_size] => 201
    [filetime] => -1
    [ssl_verify_result] => 0
    [redirect_count] => 0
    [total_time] => 0.098809
    [namelookup_time] => 3.1E-5
    [connect_time] => 0.017548
    [pretransfer_time] => 0.077084
    [size_upload] => 17
    [size_download] => 8805
    [speed_download] => 89111
    [speed_upload] => 172
    [download_content_length] => 8805
    [upload_content_length] => 17
    [starttransfer_time] => 0.098285
    [redirect_time] => 0
    [redirect_url] => 
    [primary_ip] => 69.65.27.153
    [certinfo] => Array
        (
        )

    [primary_port] => 443
    [local_ip] => 198.71.231.57
    [local_port] => 51043
)
* Hostname was found in DNS cache
*   Trying 69.65.27.153...
* Connected to www.tanthrough.com (69.65.27.153) port 443 (#4)
* successfully set certificate verify locations:
*   CAfile: cacert.pem
  CApath: none
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* Server certificate:
* 	 subject: CN=www.tanthrough.com
* 	 start date: 2016-08-04 00:00:00 GMT
* 	 expire date: 2019-11-03 23:59:59 GMT
* 	 subjectAltName: www.tanthrough.com matched
* 	 issuer: C=US; O=GeoTrust Inc.; CN=RapidSSL SHA256 CA
* 	 SSL certificate verify ok.
> POST / HTTP/1.1
User-Agent: Mozilla/5.0
Host: www.tanthrough.com
Accept: */*
Accept-Encoding: deflate, gzip
Content-Length: 17
Content-Type: application/x-www-form-urlencoded

* upload completely sent off: 17 out of 17 bytes
< HTTP/1.1 200 OK
< Date: Mon, 06 Feb 2017 23:09:04 GMT
* Server Apache/2.4.23 (Unix) OpenSSL/1.0.1e-fips mod_bwlimited/1.4 is not blacklisted
< Server: Apache/2.4.23 (Unix) OpenSSL/1.0.1e-fips mod_bwlimited/1.4
< Last-Modified: Fri, 03 Feb 2017 20:30:15 GMT
< ETag: "543769-7092-547a62647a0e4-gzip"
< Accept-Ranges: bytes
< Vary: Accept-Encoding
< Content-Encoding: gzip
< Content-Length: 8805
< Content-Type: text/html
< 
* Connection #4 to host www.tanthrough.com left intact

Open in new window


And the code for curl-ssl-connect.php .  For some reason, file_get_contents didn't work and I didn't want to investigate it.
<?php
error_reporting(E_ALL);

function get_web_page( $url,$curl_data )
{
$log = fopen("curl_verbose.log", 'w');
if( !$log ) die("Unable to open curl log file");

    $options = array(
				CURLOPT_CAINFO => 'cacert.pem',
        CURLOPT_RETURNTRANSFER => true,         // return web page
        CURLOPT_HEADER         => false,        // don't return headers
        CURLOPT_FOLLOWLOCATION => true,         // follow redirects
        CURLOPT_ENCODING       => "",           // handle all encodings
        CURLOPT_USERAGENT      => "Mozilla/5.0",     // who am i
        CURLOPT_AUTOREFERER    => true,         // set referer on redirect
        CURLOPT_CONNECTTIMEOUT => 60,          // timeout on connect
        CURLOPT_TIMEOUT        => 60,          // timeout on response
        CURLOPT_MAXREDIRS      => 10,           // stop after 10 redirects
        CURLOPT_POST           => 1,            // i am sending post data
        CURLOPT_POSTFIELDS     => $curl_data,    // this are my post vars
				CURLOPT_SSLVERSION     => 3,
        CURLOPT_SSL_VERIFYHOST => 2,            // don't verify ssl
        CURLOPT_SSL_VERIFYPEER => true,        //
        CURLOPT_VERBOSE        => 1                //
    );

    $ch      = curl_init($url);
    //curl_setopt_array($ch,$options); only for PHP 5
		curl_setopt($ch, CURLOPT_CAINFO,'cacert.pem');
		curl_setopt($ch, CURLOPT_STDERR, $log);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_HEADER, false);
		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
		curl_setopt($ch, CURLOPT_ENCODING, "");
		curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0");
		curl_setopt($ch, CURLOPT_AUTOREFERER, true);
		curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);
		curl_setopt($ch, CURLOPT_TIMEOUT, 60);
		curl_setopt($ch, CURLOPT_MAXREDIRS, 10);
		curl_setopt($ch, CURLOPT_POST, 1);
		curl_setopt($ch, CURLOPT_POSTFIELDS, $curl_data);
		curl_setopt($ch, CURLOPT_SSLVERSION, 6);
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
		curl_setopt($ch, CURLOPT_VERBOSE, 1);
    $content = curl_exec($ch);
    $err     = curl_errno($ch);
    $errmsg  = curl_error($ch) ;
    $header  = curl_getinfo($ch);
    curl_close($ch);
		echo "Error # $err : Error message $errmsg";
fclose($log);
  //  $header['errno']   = $err;
  //  $header['errmsg']  = $errmsg;
  //  $header['content'] = $content;
    return $header;
}


$curl_data = "var1=60&var2=test";
$url = "https://www.tanthrough.com/";
$response = get_web_page($url,$curl_data);

//print '<pre>';
echo '<pre>';
print_r($response);
$filename = "curl_verbose.log";
$handle = fopen($filename, 'r');
if( !$handle ) die("Unable to open curl log file");
$verbose = fread($handle, filesize($filename));
echo $verbose;

?>

Open in new window

The origin for this code is the need to check to make sure TLS1.2 is being used by curl on some sites.  Paypal, Braintree, and other gateways are requiring TLS1.2.  That means also that I need to change "CURLOPT_SSLVERSION     => 3" to '6' for TLS1.2.
cURL has this: CURL_SSLVERSION_DEFAULT

Since it appears that communications security is something that evolves, that constant might be helpful in future-proofing the script.   The docs seem to indicate that it will represent the highest level of SSL/TLS available.  In my tests it meant the same as "6" meant.
I know that TLSv1.3 is already in the works.  As far as I can tell, no version of cURL supports it yet.

And as far as help from the phone answerers aka 'customer support'...  When I asked for a URL to test against, the response was to open a Sandbox account because they are already requiring TLSv1.2.  I think I'm just going to do a simple check with my program against their API URL.  Every site I'm responsible for seems to have a different version of PHP.  I know that PHP 5.3 doesn't support all of the ciphers that are currently used so it will fail.  I'm hoping that PHP 5,4 and newer will support the Braintree and Paypal API calls.
One additional note.  Some of the hosts I have access to do not report which version of TLS is being used to connect, just the cipher.