Content Type not being set in cURL in PHP

2019-09-09 20:17发布

问题:

I'm trying to send a request to an API (Xero, to be specific) using cURL but I was apparently sending empty requests. I checked the cURL info and it looks like I don't have a Content-Type set, even though I've been setting it in the code.

Here's my code:

    $content = $this->getContent();
    $headers = [
        "Content-Type: application/x-www-form-urlencoded",
        "Content-Length: " . strlen($content),
        "Connection: close"
    ];

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $this->getUrl());
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_TIMEOUT, 10);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_HEADER, true);

    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $content);

    de($headers, curl_getinfo($ch));

de() is a a "dump and exit" function, and it outputs this:

 array(3) {
  [0] =>
      string(47) "Content-Type: application/x-www-form-urlencoded"
  [1] =>
      string(20) "Content-Length: 1003"
  [2] =>
      string(17) "Connection: close"
}

array(26) {
  'url' =>
  string(41) "https://api.xero.com/api.xro/2.0/Invoices"
  'content_type' =>
  NULL
  'http_code' =>
  int(0)
  'header_size' =>
  int(0)
  'request_size' =>
  int(0)
  'filetime' =>
  int(0)
  'ssl_verify_result' =>
  int(0)
  'redirect_count' =>
  int(0)
  'total_time' =>
  double(0)
  'namelookup_time' =>
  double(0)
  'connect_time' =>
  double(0)
  'pretransfer_time' =>
  double(0)
  'size_upload' =>
  double(0)
  'size_download' =>
  double(0)
  'speed_download' =>
  double(0)
  'speed_upload' =>
  double(0)
  'download_content_length' =>
  double(-1)
  'upload_content_length' =>
  double(-1)
  'starttransfer_time' =>
  double(0)
  'redirect_time' =>
  double(0)
  'certinfo' =>
  array(0) {
    }
  'primary_ip' =>
  string(0) ""
  'primary_port' =>
  int(0)
  'local_ip' =>
  string(0) ""
  'local_port' =>
  int(0)
  'redirect_url' =>
  string(0) ""
}

As far as I can see I am setting the headers correctly (the constant is spelled correctly and I haven't set them multiple times). What am I doing wrong?

回答1:

First check with curl_error function click me for detail!!

since your url is https. so ssl verifying process is followed.

Informal fix:

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

Formal fix:

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_CAINFO, getcwd() . "/CAcerts/your_certificate.crt");

Where is certificate?

  1. Browse url in firefox browser

  1. Click lock pad at left of address bar

  2. Then click more information

  3. Now click the view certificate button

  4. In opened pop up you will see two tab in that click details tab (shortcut ALT + D).

  5. Then click export button and save the certificate

  1. That is the path you have to give here

    curl_setopt($ch, CURLOPT_CAINFO, getcwd() . "/CAcerts/your_certificate.crt")