title: Sending file_get_contents() data over cURL
body: <p>I am trying to send an image to a web service API that asks for images to be sent as byte data.  After clarifying with them that the data from <code>file_get_contents()</code> is what they are looking for, I wrote my cURL script to send it to them, which is at the end of my post.</p>
  
  <p>What I would like to know is if this is the correct way of sending <code>file_get_contents()</code> data to a web service?  Will the 'odd' characters that <code>file_get_contents()</code> produces be OK in transit or do I need to do something to protect them?</p>
  
  <p>So far, none of my attempts have been successful - the API always returns the below error message.</p>
  
  <p>I've only ever transferred images over APIs by base64 encoding them, so many thanks for any assistance you can offer.</p>
  
  <p><strong>My coding to send to the API:</strong></p>
  
  <pre><code>// get the byte data
  $image = file_get_contents("/path/to/my/image.jpg");
  
  // url of api to post to
  $url = "http://api.web.address";
  
  // data to pass to api
  $fields["username"] = "myusername";
  $fields["password"] = "mypassword";
  $fields["image"] = $image;
  
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); 
  curl_setopt($ch, CURLOPT_TIMEOUT,        10);
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_HEADER, 0);
  curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($fields));
  $data = curl_exec($ch);
  </code></pre>
  
  <p><strong>The error returned from the API:</strong></p>
  
  <pre><code>System.ArgumentException: Cannot convert ï¿½ï¿½ï¿½ï¿½ FExif  II*       ï¿½ï¿½  !           &amp;#169; Corbis.  All Rights Reserved.    ï¿½ï¿½  Ducky       d  ï¿½ï¿½ ï¿½http://ns.adobe.com/xap/1.0/ &amp;lt;?xpacket begin=&amp;quot;ï»¿&amp;quot; id=&amp;quot;W5M0MpCehiHzreSzNTczkc9d&amp;quot;?&amp;gt; &amp;lt;x:xmpmeta xmlns:x=&amp;quot;adobe:ns:meta/&amp;quot; x:xmptk=&amp;quot;Adobe XMP Core 5.5-c021 79.154911, 2013/10/29-11:47:16        &amp;quot;&amp;gt; &amp;lt;rdf:RDF xmlns:rdf=&amp;quot;http://www.w3.org/1999/02/22-rdf-syntax-ns#&amp;quot;&amp;gt; &amp;lt;rdf:Description rdf:about=&amp;quot;&amp;quot; xmlns:xmpRights=&amp;quot;http://ns.adobe.com/xap/1.0/rights/&amp;quot; xmlns:xmpMM=&amp;quot;http://ns.adobe.com/xap/1.0/mm/&amp;quot; xmlns:stRef=&amp;quot;http://ns.adobe.com/xap/1.0/sType/ResourceRef#&amp;quot; xmlns:dc=&amp;quot;http://purl.org/dc/elements/1.1/&amp;quot; xmlns:xmp=&amp;quot;http://ns.adobe.com/xap/1.0/&amp;quot; xmpRights:Marked=&amp;quot;True&amp;quot; xmpRights:WebStatement=&amp;quot;http://pro.corbis.com/search/searchresults.asp?txt=42-17167222&amp;amp;amp;openImage=42-17167222&amp;quot; xmpMM:DocumentID=&amp;quot;xmp.did:50BE9125E81E11E38F86E55FB7D795DA&amp;quot; xmpMM:InstanceID=&amp;quot;xmp.iid:50BE9124E81E11E38F86E55FB7D795DA&amp;quot; xmp:CreatorTool=&amp;quot;Adobe Photoshop CC Windows&amp;quot;&amp;gt; &amp;lt;xmpMM:DerivedFrom stRef:instanceID=&amp;quot;8FBAF5153D10876B7ED66A56BC16FEE3&amp;quot; stRef:documentID=... to System.Byte.
  Parameter name: type ---&gt; System.FormatException: Input string was not in a correct format.
     at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer&amp; number, NumberFormatInfo info, Boolean parseDecimal)
     at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
     at System.Byte.Parse(String s, NumberStyles style, NumberFormatInfo info)
     at System.String.System.IConvertible.ToByte(IFormatProvider provider)
     at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
     at System.Web.Services.Protocols.ScalarFormatter.FromString(String value, Type type)
     --- End of inner exception stack trace ---
     at System.Web.Services.Protocols.ScalarFormatter.FromString(String value, Type type)
     at System.Web.Services.Protocols.ValueCollectionParameterReader.Read(NameValueCollection collection)
     at System.Web.Services.Protocols.HttpServerProtocol.ReadParameters()
     at System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()
  </code></pre>
  
  <p><strong>UPDATE</strong></p>
  
  <p>It turns out that it was a <code>byte array</code> that I should have been sending to the API.  I wasn't familiar with this in PHP, but <a href="https://stackoverflow.com/questions/885597/string-to-byte-array-in-php">this post</a> helped me.  So my working code is now:</p>
  
  <pre><code>// get the byte data
  $image = file_get_contents("/path/to/my/image.jpg");
  
  // url of api to post to
  $url = "http://api.web.address";
  
  // data to pass to api
  $fields["username"] = "myusername";
  $fields["password"] = "mypassword";
  $fields["image"] = unpack('C*', $image);
  
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); 
  curl_setopt($ch, CURLOPT_TIMEOUT,        10);
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_HEADER, 0);
  curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($fields));
  $data = curl_exec($ch);
  </code></pre>