Developers

Flat
CURL; sending post as array (CURLOPT_POSTFIELDS) or string
User: bkievitk
Date: 11/26/2014 7:56 pm
Views: 14592
Rating: 0

CURL; sending post as array (CURLOPT_POSTFIELDS) or string. I am interfacing with an API for gamecrafter and CURLOPT_POSTFIELDS is behaving strangely for arrays. I got the API working in javascript (see index.html) but now I need to hide the username/password so I am switching to PHP. The new interface works except for sending image files (files are generated in javascript and sent to my php page now instead of gamecrafter, but use the same code). The image makes it to the php file OK, but I have tried many permutations to send it on to the API with no success (see results below). Any help would be most appreciated.

--- setup ---

godaddy server
PHP version: 5.4.34

--- gamecrafter.php ---

    ...
    
    $filename  = $_FILES['file']['tmp_name'];
    $handle    = fopen($filename, "r");

    $data = array(
        'session_id' => $sessionID,
        'folder_id' => $rootFolderID,
        'name' => 'image.png',
    1) //    'file' => '@' . $filename . ';filename=name.txt' . ';type=image/png',
    );
    2) //$data = http_build_query($data);
    
    $ch = curl_init();
    
    3) //curl_setopt($ch, CURLOPT_INFILE, $handle);
    3) //curl_setopt($ch, CURLOPT_INFILESIZE, filesize($filename));
    3) //curl_setopt($ch, CURLOPT_PUT, true);
    4) //curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: multipart/form-data'));
    curl_setopt ($ch, CURLOUT_IGNORE_CONTENT_LENGTH, 0);
    curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_TIMEOUT, 600);
    curl_setopt($ch, CURLOPT_URL, 'https://www.thegamecrafter.com/api/file');
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch, CURLOPT_POST, 1);
    
    ...

--- index.html ---    
    
    ...
    
    <javascript>
    
    ...
    
    var data = new FormData();
            
    var imgBin = window.atob(canvas.toDataURL("image/png").split(',')[1]);
                
    var array = [];
    for (var i = 0; i < imgBin.length; i++) {
      array.push(imgBin.charCodeAt(i));
    }
    data.append("file", new Blob([new Uint8Array(array)], {type: 'image/png'}));
    data.append("name", "image.png");
    data.append("folder_id", user.root_folder_id);
    data.append("session_id", session.id);
    
    var request = new XMLHttpRequest();
    //request.open("POST", "https://www.thegamecrafter.com/api/file", false);
    request.open("POST", "gamecrafter.php", false);
    
    request.onreadystatechange = function() {
        if (request.readyState == 4) {
            fileResult = request.responseText;
        }
    }
    request.send(data);

    ...
    
--- results ---

    cases show what commenting or commenting labelled lines will result in. Thus ?tf? means line 1) can be commented or not, 2) is uncommented, 3) is commented and 4) can be either.
            
    case ftff - No file uploaded. You must specify a file to upload
    case ttff - 'file' is not a text field. You need to upload a file.
    case ?fff - No file uploaded. You must specify a file to upload
    case ??tf - Resource Not Found
    case ???t - Internal Server Error

Re: CURL; sending post as array (CURLOPT_POSTFIELDS) or string
JT
User: JT
Date: 11/26/2014 8:52 pm
Views: 0
Rating: 0

Using PHP with our web services is pretty straight forward. I've whipped up an example for you:

<?php

// reading in secret info via environment variables so I don't accidentally share it with anyone

$username = $_ENV['TGC_USER'];

$password = $_ENV['TGC_PASS'];

$apikey = $_ENV['TGC_API_KEY'];

// create a session

$session = post('session', array(

 'username' => $username,

 'password' => $password,

 'api_key_id' => $apikey,

));

$session_id = $session->{'result'}->{'id'};

// fetch info about the user

$user = get('user/'.$session->{'result'}->{'user_id'}, array(

 'session_id' => $session_id,

));

// upload a file to the filesystem

$file = post('file', array(

 'session_id' => $session_id,

 'file' => '@/Users/jt/Desktop/jt.jpg', // note the @ symbol at the start of the file path

 'name' => 'jt.jpg',

 'folder_id' => $user->{'result'}->{'root_folder_id'},

));

// dump what we know about the file

var_dump($file);

// execute a POST operation to TGC's web services and return an object

function post($url, $params) {

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL,'https://www.thegamecrafter.com/api/'.$url);

curl_setopt($ch, CURLOPT_POST,1);

curl_setopt($ch, CURLOPT_POSTFIELDS, $params);

        curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);

$result=curl_exec($ch);

if(curl_errno($ch)) {  //catch if curl error exists and show it

  echo 'Curl error: ' . curl_error($ch);

        curl_close ($ch);

        }

else {

        curl_close ($ch);

return json_decode($result);

        }

}

// execute a GET operation to TGC's web services and return an object

function get($url, $params) {

$query = '?';

        if ($params) {

  foreach($params as $key=>$value) {

$query .= $key.'='.$value.'&';

                }

        }

        $query = trim($query, '&');

$ch = curl_init();

$timeout = 5;

curl_setopt($ch, CURLOPT_URL, 'https://www.thegamecrafter.com/api/'.$url.$query);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);

$result = curl_exec($ch);

if (curl_errno($ch)) {  //catch if curl error exists and show it

  echo 'Curl error: ' . curl_error($ch);

        curl_close ($ch);

        }

else {

        curl_close ($ch);

return json_decode($result);

        }

}

?>

Re: CURL; sending post as array (CURLOPT_POSTFIELDS) or string
JT
User: JT
Date: 11/26/2014 8:54 pm
Views: 87
Rating: 0

I just realized that reading this through the forum is quite messy as it doesn't retain it's formatting. Here's a gist containing the code:

https://gist.github.com/rizen/b0749e9ef97cfc817e2d

Re: CURL; sending post as array (CURLOPT_POSTFIELDS) or string
User: bkievitk
Date: 11/27/2014 6:36 am
Views: 12327
Rating: 0

Thank you so much. It looks like it's ommiting some of the CURL option variables that I had used, I don't know which ones did it but it works!

PreviousNext