问题描述
我有一个网站可以从我们的CRM(SugarCRM)中提取客户案例,案例和案例注释可以包含存储在CRM中的附件。 Sugar有一个内置的API端点,用于获取文件数据并使用以下命令通过curl请求将其返回:
// ::记录/文件/:字段作为GET请求
我的curl脚本
public static function getAttachment($url,$encode = false)
{
self::connect_sugarcrm();
$curl = curl_init(self::$SUGARENDPOINTURI.self::$API.$url);
curl_setopt($curl,CURLOPT_HTTP_VERSION,CURL_HTTP_VERSION_1_0);
curl_setopt($curl,CURLOPT_HEADER,true);
curl_setopt($curl,CURLOPT_SSL_VERIFYPEER,0);
curl_setopt($curl,CURLOPT_RETURNTRANSFER,CURLOPT_FOLLOWLOCATION,CURLOPT_HTTPHEADER,array(
"Authorization: Bearer","OAuth-Token: ".self::$tokens->access_token,)
);
$response = curl_exec($curl);
$header_size = curl_getinfo($curl,CURLINFO_HEADER_SIZE);
$headers = substr($response,$header_size);
$file = substr($response,$header_size);
curl_close($curl);
if ($encode) {
return base64_encode($file);
}
return $file;
我没有将编码设置为true,所以只是返回原始文件,而不是将其编码为Base64。如文档所述,我从CRM中得到了正确的答复。
HTTP/1.1 200 OK
Date: Fri,16 Oct 2020 14:01:10 GMT
Server: Apache/2.4.29 (Ubuntu)
Expires:
Cache-Control: max-age=0,private
Pragma:
Content-disposition: attachment; filename="copy of Countries by region.xlsx"
X-Content-Type-Options: nosniff
ETag: d41d8cd98f00b204e9800998ecf8427e
Content-Length: 59349
Connection: close
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
我现在正试图弄清楚如何使浏览器下载此文件。在初始化下载之前,我需要在本地保存此文件吗?还是有一种方法可以下载它?
我的标题脚本
header("Content-Description: File Transfer");
header('Content-disposition: attachment; filename="copy of Countries by region.xlsx"');
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: 59349');
// echo base64_decode($data);
echo $file;
exit();
这将下载一个56KB的excel文件,但无法打开,所以我想看看标题做错了什么
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header("Content-disposition: attachment; filename=\"{$file->name}\"");
header('Expires: 0');
header('Cache-Control: must-revalidate,post-check=0,pre-check=0');
header('Pragma: public');
header("Content-Length: ".$file->{'content-length'}."");
ob_clean();
flush();
echo $data;
exit;
但是,这会导致某些文件类型(例如psd xslx)出错,但适用于jpg,png,gif,pdf,docx,csv
解决方法
进一步阅读PHP标头后,我获得了download.php,可以使用以下代码成功下载存储在CRM中的文件
ref:https://www.media-division.com/the-right-way-to-handle-file-downloads-in-php/
卷曲脚本以从CRM提取文件
public static function download($url)
{
self::connect_sugarcrm();
$curl = curl_init(self::$SUGARENDPOINTURI.$url);
curl_setopt($curl,CURLOPT_HTTP_VERSION,CURL_HTTP_VERSION_1_0);
curl_setopt($curl,CURLOPT_HEADER,true);
curl_setopt($curl,CURLOPT_SSL_VERIFYPEER,0);
curl_setopt($curl,CURLOPT_RETURNTRANSFER,CURLOPT_FOLLOWLOCATION,CURLOPT_HTTPHEADER,array(
"OAuth-Token: ".self::$tokens->access_token,)
);
$response = curl_exec($curl);
$header_size = curl_getinfo($curl,CURLINFO_HEADER_SIZE);
$headers = substr($response,$header_size);
$file = substr($response,$header_size);
curl_close($curl);
return $file;
}
Download.php
$module = get_query_var('module');
$id = get_query_var('id');
$url = "{$module}/{$id}/file";
$fileinfo = MagiConnect_SugarCRM::getSugar('',$url);
foreach ($fileinfo as $file) {
$data = MagiConnect_SugarCRM::download($file->uri);
ob_end_clean();
header("Content-Description: File Transfer");
header("Content-Type: ".$file->{'content-type'});
header("Content-Transfer-Encoding: Binary");
header("Content-Disposition: attachment; filename=\"{$file->name}\"");
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate,post-check=0,pre-check=0');
header('Pragma: public');
header("Content-Length: ".$file->{'content-length'}."");
echo $data;
exit;
}