通过cURL发送file_get_contents()数据

时间:2014-06-03 14:19:40

标签: php curl file-get-contents

我正在尝试将图像发送到Web服务API,要求将图像作为字节数据发送。在向他们澄清来自file_get_contents()的数据是他们正在寻找的内容之后,我编写了我的cURL脚本以将其发送给他们,这是我帖子的结尾。

我想知道的是,这是将file_get_contents()数据发送到网络服务的正确方法吗?奇怪的是'奇怪的' file_get_contents()生成的字符在传输中是否正常,或者我是否需要做一些事情来保护它们?

到目前为止,我的尝试都没有成功 - API始终返回以下错误消息。

我只是通过base64编码将图像传输到API上,非常感谢您提供的任何帮助。

我发送给API的编码:

// 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);

API返回的错误:

System.ArgumentException: Cannot convert ���� FExif  II*       ��  !           © Corbis.  All Rights Reserved.    ��  Ducky       d  �� �http://ns.adobe.com/xap/1.0/ <?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.5-c021 79.154911, 2013/10/29-11:47:16        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmpRights="http://ns.adobe.com/xap/1.0/rights/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmpRights:Marked="True" xmpRights:WebStatement="http://pro.corbis.com/search/searchresults.asp?txt=42-17167222&openImage=42-17167222" xmpMM:DocumentID="xmp.did:50BE9125E81E11E38F86E55FB7D795DA" xmpMM:InstanceID="xmp.iid:50BE9124E81E11E38F86E55FB7D795DA" xmp:CreatorTool="Adobe Photoshop CC Windows"> <xmpMM:DerivedFrom stRef:instanceID="8FBAF5153D10876B7ED66A56BC16FEE3" stRef:documentID=... to System.Byte.
Parameter name: type ---> System.FormatException: Input string was not in a correct format.
   at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& 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()

更新

事实证明,我应该发送给API byte array。我在PHP中对此并不熟悉,但this post帮助了我。所以我的工作代码现在是:

// 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);

1 个答案:

答案 0 :(得分:2)

你做错了。让CURL做一个标准的文件上传:

$fields = array(
    'username' => 'foo',
    'password' => 'bar',
    'image' => '@/path/to/your/image'
);

curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);

注意图像字段中的@ - 这是使用@之后指定的路径向CURL发送文件上载的信号。另请注意,http_build_query未被使用。 CURL会认识到你正在传入一个数组并为你完成所有工作。

如果您使用的是PHP 5.5+,则不推荐使用@选项,并且您有一个新的CURLFile类来执行此操作。