title: CURL in PHP; sending post as array (CURLOPT_POSTFIELDS) or string
body: <p>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.</p>
  
  <p>--- setup ---</p>
  
  <p>godaddy server
  PHP version: 5.4.34</p>
  
  <p>--- gamecrafter.php ---</p>
  
  <pre><code>...
  
  $filename  = $_FILES['file']['tmp_name'];
  $handle    = fopen($filename, "r");
  
  $data = array(
      'session_id' =&gt; $sessionID,
      'folder_id' =&gt; $rootFolderID,
      'name' =&gt; 'image.png',
  1) //   'file' =&gt; '@' . $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); 
  
  ...
  </code></pre>
  
  <p>--- index.html ---  </p>
  
  <pre><code>...
  
  &lt;javascript&gt;
  
  ...
  
  var data = new FormData(); 
  
  var imgBin = window.atob(canvas.toDataURL("image/png").split(',')[1]);
  
  var array = [];
  for (var i = 0; i &lt; 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);
  
  ...
  </code></pre>
  
  <p>--- results ---</p>
  
  <pre><code>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
  </code></pre>