使用PHP cURL将文件上传到Google Signed URL [英] Uploading a file to Google Signed URL with PHP cURL

查看:69
本文介绍了使用PHP cURL将文件上传到Google Signed URL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用PHP中的cURL将文件上传到Google签名的URL.

I am trying to upload a file to a Google Signed URL with cURL in PHP.

我从表单中发布了文件,可以使用$ _FILES变量访问它.

I have the file being posted from a form and can access it with the $_FILES var.

但是实际上上传的文件不是正确的文件,我认为这与我处理tmp文件的方式有关.

However the file that actually gets uploaded is not the right file and I think it is to do with how I am handling the tmp file.

$file_name = $_FILES['file']['name'];
$temp_name = $_FILES['file']['tmp_name'];

// $file = fopen($temp_name, 'r');
// $file = realpath($temp_name);

$request = curl_init($request_url);

curl_setopt($request, CURLOPT_RETURNTRANSFER, true);
curl_setopt($request, CURLOPT_POSTFIELDS, $file);
curl_setopt($request, CURLOPT_HTTPHEADER, array('Content-Type:text/plain','Authorization:'.$token));
curl_setopt($request, CURLOPT_CUSTOMREQUEST, 'PUT');

$response = curl_exec($request);
$errors = curl_error($request);
curl_close($request);

var_dump($response);
var_dump($errors);

即使使用wav文件,以下内容也可以按预期方式与内容类型文本(而不是音频)一起工作.

The following works as expected with content-type text instead of audio even though its a wav file.

curl -v -X PUT --upload-file file.wav --header "Content-Type: text/plain" request_url

编辑

我已经尝试过了:

Edit

I have tried this:

$file = new CurlFile($temp_name,$mime_type,$file_name);

但这只会使我的页面完全崩溃.

but this just crashes my page altogether.

我认为可能与调用请求的方式有关,所以我想创建一个cURL函数,我可以将所有请求的URL和数据传递给它,如下所示:

I think it may be to do with how I am calling the request, so I wanted to create a cURL function that I can just pass the url and data to for all my requests like so:

$file = new CurlFile($temp_name,$mime_type,$file_name);
$result = curl_request($conn,$signed_url,$file,'text/plain','PUT');

然后我的功能是这样的:

Then my function is like this:

function curl_request($conn,$request_url,$request_data,$content_type,$request_type){
    $api_username = 'API username';
    $stmt = $conn->prepare("SELECT * FROM config WHERE setting=:setting");
    $stmt->bindParam(':setting', $api_username);
    $stmt->execute();
    $result = $stmt->setFetchMode(PDO::FETCH_ASSOC);
    foreach($stmt->fetchAll() as $key=>$row) {
        $username = $row['value'];
    }
    $api_key = 'API key';
    $stmt = $conn->prepare("SELECT * FROM config WHERE setting=:setting");
    $stmt->bindParam(':setting', $api_key);
    $stmt->execute();
    $result = $stmt->setFetchMode(PDO::FETCH_ASSOC);
    foreach($stmt->fetchAll() as $key=>$row) {
        $key = $row['value'];
    }
    
    $data = array(
        'username' => $username,
        'password' => $key
    );
    $payload = json_encode($data);

    $initial_request = curl_init('https://example.com/auth');
    curl_setopt($initial_request, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($initial_request, CURLOPT_POSTFIELDS, $payload);
    curl_setopt($initial_request, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));

    $initial_response = curl_exec($initial_request);
    $initial_errors = curl_error($initial_request);

    curl_close($initial_request);
    
    $decoded_response = (array)json_decode($initial_response);
    $token = $decoded_response['token'];
    
    $request = curl_init($request_url);
    
    curl_setopt($request, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($request, CURLOPT_POSTFIELDS, $request_data);
    curl_setopt($request, CURLOPT_HTTPHEADER, array('Content-Type:'.$content_type,'Authorization:'.$token));
    curl_setopt($request, CURLOPT_CUSTOMREQUEST, $request_type);
    
    $response = curl_exec($request);
    $errors = curl_error($request);
    curl_close($request);
    
    if(empty($errors)){
        return $response;
    }else{
        return $errors;
    }
}

当我有 $ file = fopen($ temp_name,'r'); 但上传的文件是一个奇怪的文件时,此方法有效.

This works when I had $file = fopen($temp_name, 'r'); but the file uploaded was a weird file.

这是当API另一端的人尝试打开该文件时的外观.

This is what the file looks like when the person at the other end of this API tries to open it.

推荐答案

这就是您想要的:完全删除CURLOPT_POSTFIELDS,然后将 CURLOPT_CUSTOMREQUEST =>'PUT'替换为 CURLOPT_UPLOAD =>; 1 并将'r'替换为'rb',并使用CURLOPT_INFILE(您应该使用INFILE而不是POSTFIELDS),

this is what you want: remove CURLOPT_POSTFIELDS altogether, and replace CURLOPT_CUSTOMREQUEST=>'PUT' with CURLOPT_UPLOAD=>1 and replace 'r' with 'rb', and use CURLOPT_INFILE (you're supposed to use INFILE instead of POSTFIELDS),

$fp = fopen($_FILES['file']['tmp_name'], "rb");
curl_setopt_array($ch,array(
CURLOPT_UPLOAD=>1,
CURLOPT_INFILE=>$fp,
CURLOPT_INFILESIZE=>$_FILES['file']['size']
));

当我有$ file = fopen($ temp_name,'r');时有效

This works when I had $file = fopen($temp_name, 'r');

永远不要使用 r 模式,总是使用 rb 模式(二进制模式"的缩写),如果您曾经使用 r模式(在Windows上), r 是文本模式"的缩写,-如果您确实希望使用文本模式,请使用 rt (除非您真的知道自己在做什么,否则就永远不需要文本模式,不幸的是,这是默认模式),

never use the r mode, always use the rb mode (short for "binary mode"), weird things happen if you ever use the r mode on Windows, r is short for "text mode" - if you actually want text mode, use rt (and unless you really know what you're doing, you don't want the text mode, ever, unfortunate that it's the default mode),

但是上传的文件是一个奇怪的文件.(...)这是该API另一端的人尝试打开该文件时的外观.

but the file uploaded was a weird file. (...) This is what the file looks like when the person at the other end of this API tries to open it.

好吧,您为CURLOPT_POSTFIELDS提供了资源.CURLOPT_POSTFIELDS接受2种参数,#1:数组(用于 multipart/form-data 请求),#2:字符串(用于当您要指定原始文章正文数据时)不接受资源.

well you gave CURLOPT_POSTFIELDS a resource. CURLOPT_POSTFIELDS accepts 2 kinds of arguments, #1: an array (for multipart/form-data requests), #2: a string (for when you want to specify the raw post body data), it does not accept resources.

如果php curl API的设计合理,则在为CURLOPT_POSTFIELDS提供资源时会收到InvalidArgumentException或TypeError.但是它的设计不是很好.相反,发生的事情是curl_setopt隐式将您的资源转换为字符串,因此 resource id #X ,与执行操作相同

if the php curl api was well designed, you would get an InvalidArgumentException, or a TypeError, when giving CURLOPT_POSTFIELDS a resource. but it's not well designed. instead, what happened is that curl_setopt implicitly casted your resource to a string, hence resource id #X , it's the same as doing

curl_setopt($request, CURLOPT_POSTFIELDS, (string) fopen(...));

这篇关于使用PHP cURL将文件上传到Google Signed URL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆