Nick Woodhams
Nick Woodhams

Reputation: 12677

How do I post query parameters with PHP?

I am trying to interface with the Clickbank API for support ticket creation (https://api.clickbank.com/rest/1.2/tickets/).

I can't seem to get it to work with CURL. I can get the API working fine using GET (fetching order information), but not POST (required for changes to orders).

Here's my code, which returns an error 404 from Clickbank.

<?php
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, "https://api.clickbank.com/rest/1.2/tickets/FNKBEP34?type=cncl&reason=ticket.type.cancel.7");
    curl_setopt($ch, CURLOPT_HEADER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_NOBODY, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array("Accept: application/xml", "Authorization: removed_dev_key:removed_api_key"));
    $result = curl_exec($ch);
    curl_close($ch);

    print $result;
?>

I've been able to POST successfully with RESTClient2.3. But I haven't been able to duplicate that with CURL.

Upvotes: 1

Views: 9931

Answers (3)

Mohammad Faisal Islam
Mohammad Faisal Islam

Reputation: 507

<?php
    function executeCurl($arrOptions) {

        $mixCH = curl_init();

        foreach ($arrOptions as $strCurlOpt => $mixCurlOptValue) {
            curl_setopt($mixCH, $strCurlOpt, $mixCurlOptValue);
        }

        $mixResponse = curl_exec($mixCH);

        curl_close($mixCH);

        return $mixResponse;
    }

    // If you need any HTTP authentication

    $username = 'http-auth-username';
    $password = 'http-auth-password';

    $requestType = 'POST'; // This can be PUT or POST

    // This can be $arrPostData = $_POST;
    $arrPostData = array(
        'key1' => 'value-1-for-k1y-1',
        'key2' => 'value-2-for-key-2',
        'key3' => array(
                      'key31'  => 'value-for-key-3-1',
                      'key32'  => array(
                          'key321' => 'value-for-key321'
                          )
        ),
        'key4' => array(
            'key' => 'value'
        )
    );

    // You can set your POST data
    $postData = http_build_query($arrPostData); // Raw PHP array

    $postData = json_encode($arrPostData); // Only USE this when requesting JSON data

    $arrResponse = executeCurl(array(
        CURLOPT_URL => 'http://whatever-your-request-url.com/xyz/yii',
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPGET => true,
        CURLOPT_VERBOSE => true,
        CURLOPT_AUTOREFERER => true,
        CURLOPT_CUSTOMREQUEST => $requestType,
        CURLOPT_POSTFIELDS  => $postData,
        CURLOPT_HTTPHEADER  => array(
            "X-HTTP-Method-Override: " . $requestType,
            'Content-Type: application/json', // Only USE this when requesting JSON data
        ),
        // If required HTTP authentication, use the below lines
        CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
        CURLOPT_USERPWD  => $username . ':' . $password
    ));

Upvotes: 0

Nick Woodhams
Nick Woodhams

Reputation: 12677

After about 10 and a half hours of trial and error... I figured it out.

The problem was two prong.

  1. I am running PHP 5.2.4 which has a bug accepting custom headers. I found this code, which worked perfectly.

     if(version_compare(PHP_VERSION, '5.3.0') == -1){
         ini_set('user_agent', 'PHP-SOAP/' . PHP_VERSION . "\r\n" . $options['header']);
     }
    
  2. Curl would not work. Period. I tried everything. I really have no idea why.

Here is the final code I ended up with, which works perfectly.

This interfaces with the Clickbank API via POST. I hope this helps a lot of people.

<?
    $options = array(
      'http' => array(
        'method' => "POST",
        'header' =>
          "Accept: application/xml\r\n" .
          "Authorization: DEV-key-here:API-key-here\r\n"
        )
    ));

    if(version_compare(PHP_VERSION, '5.3.0') == -1){
        ini_set('user_agent', 'PHP-SOAP/' . PHP_VERSION . "\r\n" . $options['header']);
    }

    $context = stream_context_create($options);

    $xml = file_get_contents('https://api.clickbank.com/rest/1.2/tickets/VZR9RYE3?reason=ticket.type.cancel.7&type=cncl', false, $context);
?>

Upvotes: 1

Ben
Ben

Reputation: 21249

My wild guess is that RestClient tries to be smart and actually transforms your get URL parameters to post variables on the fly (I could be wrong though).

Anyhow... POST, you're doing it wrong.

A curl POST request should be something like this:

<?php
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, "https://api.clickbank.com/rest/1.2/tickets/FNKBEP34");
    curl_setopt($ch, CURLOPT_HEADER, true);
    curl_setopt($ch, CURLOPT_POST, true);

    //Take this out: curl_setopt($ch, CURLOPT_NOBODY, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, "type=cncl&reason=ticket.type.cancel.7");
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array("Accept: application/xml", "Authorization: removed_dev_key:removed_api_key"));
    $result = curl_exec($ch);
    curl_close($ch);

    print $result;
?>

Upvotes: 1

Related Questions