使用二进制数据构造PHP POST请求

时间:2011-07-05 17:31:32

标签: php html api file-upload

我正在尝试构建一个包含一些二进制数据的PHP POST请求,继续a previous StackOverflow question。数据正在提交给此API调用:http://www.cyclestreets.net/api/#addphoto

这是我的PHP代码:

$file = $_FILES['mediaupload'];
$file_field="@$file[tmp_name]";
$fields = array(
    'mediaupload'=>$file_field,
    'username'=>urlencode($_POST["username"]),
    'password'=>urlencode($_POST["password"]),
    'latitude'=>urlencode($_POST["latitude"]),
    'longitude'=>urlencode($_POST["longitude"]),
    'datetime'=>urlencode($_POST["datetime"]),
    'category'=>urlencode($_POST["category"]),
    'metacategory'=>urlencode($_POST["metacategory"]),
    'caption'=>urlencode($_POST["description"])
);
$fields_string = http_build_query($fields);
echo 'FIELDS STRING: ' . $fields_string;
$url = 'https://www.cyclestreets.net/api/addphoto.json?key=$key';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POST,count($fields));
curl_setopt($ch,CURLOPT_POSTFIELDS,$fields_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec ($ch);

这是我的PHP文件输出:

FIELDS STRING: mediaupload=%40%2Fprivate%2Fvar%2Ftmp%2FphpHjfkRP&username=testing&password=testing&latitude=auto&longitude=auto&datetime=auto&category=cycleparking&metacategory=good&caption=
API RESPONSE: {"request":{"datetime":"1309886656"},"error":{"code":"unknown","message":"The photo was received successfully, but an error occurred while processing it."},"result":{}}

我相信这意味着除了二进制数据的格式之外,关于请求的所有其他内容都可以。谁能告诉我我做错了什么?

2 个答案:

答案 0 :(得分:2)

CURL可以接受POST字段的key =>值对的原始数组。没有必要做urlencode()和http_build_query()的所有事情。很可能数组中的@被绑定到%40,因此CURL不会将其视为文件上载尝试。

$fields = array(
    'mediaupload'=>$file_field,
    'username'=> $_POST["username"),
    etc...

curl_setopt($ch,CURLOPT_POSTFIELDS,$fields);

答案 1 :(得分:1)

http_build_query函数生成一个URL编码的查询字符串,这意味着“@ file.ext”在输出中以字符串形式编码,而cURL不知道您正在尝试上传文件

我的建议是不要在http_build_query来电中包含要上传的文件,并将其手动包含在CURLOPT_POSTFIELDS中。

$file = $_FILES['mediaupload'];
$file_field="@$file[tmp_name]";
$fields = array(
    'username'=>urlencode($_POST["username"]),
    'password'=>urlencode($_POST["password"]),
    'latitude'=>urlencode($_POST["latitude"]),
    'longitude'=>urlencode($_POST["longitude"]),
    'datetime'=>urlencode($_POST["datetime"]),
    'category'=>urlencode($_POST["category"]),
    'metacategory'=>urlencode($_POST["metacategory"]),
    'caption'=>urlencode($_POST["description"])
);
$fields_string = http_build_query($fields);
echo 'FIELDS STRING: ' . $fields_string;
$url = 'https://www.cyclestreets.net/api/addphoto.json?key=$key';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POST, 1);
curl_setopt($ch,CURLOPT_POSTFIELDS, 'mediaupload=' . $file_field . '&' . $fields_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec ($ch);