centos用php上传文件,WBB - Centos下PHP无法Curl模拟Post上传文件的问题
有个产品需要上传图片到贴图库。为此还开了个贴图库的会员。
用的方案是ueditor+贴图库插件,自己加了个从dz拉过来的前端上传控件,然后禁用了Ueditor的上传按钮,毕竟数据先过一次后端再到贴图库是很蛋疼的事情。
决定禁用的关键是,贴图库给出的插件还是远程拉图模式,也就是说,产品有CDN,图片先从用户手里到达服务器tmp目录,Ueditor保存到upload目录,贴图库再访问cdn抓图,图片还得从Cdn过一遍,而Cdn有时不及时抓取,则导致贴图库抓不到文件,心累。
禁用后,发现Ueditor本地上传目录还是老是有文件出现,很是奇怪,今天下午干脆研究一下,试了多种方式最后猜测到是直接拖动图片到编辑器会导致上传行为。
本想直接改前端,把前端上传行为转向贴图库,后来放弃,还是先从后台着手解决。
发现贴图库sdk里明明有post上传的函数,却不用,改了一下,发现硬是传不上去。
原来Curl的Post发送文件,在Centos下会有问题,国外的大神给出了解决方案,竟然是自写Curl的Body部份,心疼
关键函数: 这里$assoc是正常post数据数组,$files是文件数据数组(文件地址值不要再加@了,里面有file_get_contents)
function curl_custom_postfields($ch, $assoc = array(), $files = array()) {
// invalid characters for "name" and "filename"
static $disallow = array("\0", "\"", "\r", "\n");
// build normal parameters
foreach ($assoc as $k => $v) {
$k = str_replace($disallow, "_", $k);
$body[] = implode("\r\n", array(
"Content-Disposition: form-data; name=\"{$k}\"",
"",
filter_var($v),
));
}
// build file parameters
foreach ($files as $k => $v) {
switch (true) {
case false === $v = realpath(filter_var($v)):
case !is_file($v):
case !is_readable($v):
continue; // or return false, throw new InvalidArgumentException
}
$data = file_get_contents($v);
$v = call_user_func("end", explode(DIRECTORY_SEPARATOR, $v));
$k = str_replace($disallow, "_", $k);
$v = str_replace($disallow, "_", $v);
$body[] = implode("\r\n", array(
"Content-Disposition: form-data; name=\"{$k}\"; filename=\"{$v}\"",
"Content-Type: image/jpeg", //这里根据我自己需求修改的,貌似随便改别的也并不影响,起码贴图库不管
"",
$data,
));
}
// generate safe boundary
do {
$boundary = "---------------------" . md5(mt_rand() . microtime());
} while (preg_grep("/{$boundary}/", $body));
// add boundary for each parameters
array_walk($body, function (&$part) use ($boundary) {
$part = "--{$boundary}\r\n{$part}";
});
// add final boundary
$body[] = "--{$boundary}--";
$body[] = "";
// set options
return @curl_setopt_array($ch, array(
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => implode("\r\n", $body),
CURLOPT_HTTPHEADER => array(
"Expect: 100-continue",
"Content-Type: multipart/form-data; boundary={$boundary}", // change Content-Type
),
));
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
functioncurl_custom_postfields($ch,$assoc=array(),$files=array()){
// invalid characters for "name" and "filename"
static$disallow=array("\0","\"","\r","\n");
// build normal parameters
foreach($assocas$k=>$v){
$k=str_replace($disallow,"_",$k);
$body[]=implode("\r\n",array(
"Content-Disposition: form-data; name=\"{$k}\"",
"",
filter_var($v),
));
}
// build file parameters
foreach($filesas$k=>$v){
switch(true){
casefalse===$v=realpath(filter_var($v)):
case!is_file($v):
case!is_readable($v):
continue;// or return false, throw new InvalidArgumentException
}
$data=file_get_contents($v);
$v=call_user_func("end",explode(DIRECTORY_SEPARATOR,$v));
$k=str_replace($disallow,"_",$k);
$v=str_replace($disallow,"_",$v);
$body[]=implode("\r\n",array(
"Content-Disposition: form-data; name=\"{$k}\"; filename=\"{$v}\"",
"Content-Type: image/jpeg",//这里根据我自己需求修改的,貌似随便改别的也并不影响,起码贴图库不管
"",
$data,
));
}
// generate safe boundary
do{
$boundary="---------------------".md5(mt_rand().microtime());
}while(preg_grep("/{$boundary}/",$body));
// add boundary for each parameters
array_walk($body,function(&$part)use($boundary){
$part="--{$boundary}\r\n{$part}";
});
// add final boundary
$body[]="--{$boundary}--";
$body[]="";
// set options
return@curl_setopt_array($ch,array(
CURLOPT_POST=>true,
CURLOPT_POSTFIELDS=>implode("\r\n",$body),
CURLOPT_HTTPHEADER=>array(
"Expect: 100-continue",
"Content-Type: multipart/form-data; boundary={$boundary}",// change Content-Type
),
));
}
方法怎么调用: 贴图库sdk的是post,我加了个postPlus
function postPlus($url,$postA,$postB){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER,true);
curl_setopt($ch, CURLOPT_TIMEOUT,30);
$this->curl_custom_postfields($ch, $postA, $postB); //这里是关键
$output = curl_exec($ch);
curl_close($ch);
return $output;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
functionpostPlus($url,$postA,$postB){
$ch=curl_init();
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch,CURLOPT_BINARYTRANSFER,true);
curl_setopt($ch,CURLOPT_TIMEOUT,30);
$this->curl_custom_postfields($ch,$postA,$postB);//这里是关键
$output=curl_exec($ch);
curl_close($ch);
return$output;
}
还需要修改贴图库sdk的上传方法
function uploadFile($aid,$file=null){
$url = $this->upload_host;
$param['deadline'] = time()+$this->timeout;
$param['aid'] = $aid;
$Token=$this->op_Token->dealParam($param)->createToken();
$data['Token']=$Token;
$data1['file']=$file; //这里区分开来,文件数组
return empty($file)?$Token:$this->postPlus($url,$data,$data1);
}
1
2
3
4
5
6
7
8
9
functionuploadFile($aid,$file=null){
$url=$this->upload_host;
$param['deadline']=time()+$this->timeout;
$param['aid']=$aid;
$Token=$this->op_Token->dealParam($param)->createToken();
$data['Token']=$Token;
$data1['file']=$file;//这里区分开来,文件数组
returnempty($file)?$Token:$this->postPlus($url,$data,$data1);
}
最后修改Ueditor+贴图库的 Uploader.class.php,原本的uploadFromWeb改为uploadFile,直接丢临时文件$this->file[“tmp_name”]进去,再把Ueditor的move_uploaded_file处理注释掉,返回的stateInfo强制改为SUCCESS,完工!
喜欢 (21)or分享 (0)
centos用php上传文件,WBB - Centos下PHP无法Curl模拟Post上传文件的问题相关推荐
- linux上连接ftp服务器,linux下lftp连接ftp服务器进行上传与下载的方法详解
摘要 腾兴网为您分享:linux下lftp连接ftp服务器进行上传与下载的方法详解,中英翻译,中建在线,掌上看家,银行帮等软件知识,以及微信一键转发工具,小学英语冀教版,正是在下表情包,易问电信,万能 ...
- 服务器不知道循环生成文件,Windows服务器下PowerShell命令往服务器共享文件夹进行文件拷贝、循环文件重命名...
由于项目需要,接触到了PowerShell命令,但是苦于以前没有接触过,几句话的代码百度搜索了很长时间. 主要功能是Windows服务器下利用PowerShell命令实现文件拷贝.文件重命名(去掉文件 ...
- 服务器启动缺失文件,麻烦请问下,本地win运行没问题 , 上传到服务器后 , 报错,说是缺少文件...
这个文件肯定是存在的 ``` [think\exception\ThrowableError] Fatal error: Class 'GatewayWorker\Register' not foun ...
- linux unzip 多个文件夹,Linux下使用unzip命令解压多个文件
Linux下直接使用unzip *.zip解压多个文件会报错 可以使用unzip '*.zip'或者 unzip "*.zip"或者unzip \*.zip命令 或者使用for z ...
- linux解压rar文件权限,linux下使用unrar命令解压*.rar格式文件
使用帮助 [user@localhost ~]$ unrar UNRAR 5.40 freeware Copyright (c) 1993-2016 Alexander Roshal Usa ...
- c语言bnd文件,Unix环境下嵌入式C程序编译
A.预编译部分 1.预编译DB2篇 1.1 什么是DB2预编译 在我们用C语言编写访问DB2的程序过程中,需要用到嵌入式SQL,其作用是将DB2 SQL混入一般C程序中, DB2预编译器可以将SQL语 ...
- ListView上拉加载和下拉刷新多种实现方式
ListView上拉加载和下拉刷新多种实现方式 该篇为ListView下拉刷新和上拉加载实现的各种方法大合集.可能在具体的细节逻辑上处理不太到位,但基本上完成逻辑的实现.细节方面,个人可以根据自己的需 ...
- centos把文件传到服务器,如何将文件传到远程centos服务器上
如何将文件传到远程centos服务器上 内容精选 换一换 本章节介绍如何将下载的证书安装到IIS服务器上.安装好证书后,您的Web服务器将能支持SSL通信,从而保证您Web服务器的通信安全.如果证书安 ...
- centos nfs java_CentOS下安装配置NFS并通过Java进行文件上传下载
1:安装NFS (1)安装 yum install nfs-utils rpcbind (2)启动rpcbind服务 systemctl restart rpcbind.service 查看服务状态 ...
最新文章
- efishell无法开机shell_电脑出现EFIshellversion解决方法W1048/海尔青春小蓝
- 关于几种排序算法的时间性能比较
- [机器学习]总结特征工程干货
- 从0到1写RT-Thread内核——空闲线程与阻塞延时的实现
- java面向对象程序课本,Java面向对象程序设计
- 丹佛斯变频器型号说明_台达变频器VFD-CH2000型号说明及功能介绍
- 华硕笔记本之secure boot
- 【原创】PSP开机只是绿灯亮,黑屏
- NOI训练行动路线图
- 基于Android的人事管理系统 开发与设计
- 异常排查_Python-日志模块.NoSectionError: No section: '*' 错误?
- ubuntu 13 sogou input method install
- css+javascript模拟OneNote2007Tab标签
- oracle 函数索引
- 用Acrobat pro DC 自动生成pdf目录——知网硕博论文为例(附带如何下载只有caj的pdf)
- 如何使用计算机远程关闭手机软件,如何用手机远程控制电脑关机
- FIL、XCH、BZZ哪个更好?
- Jmeter 录制手机脚本
- which must be escaped when used within the value
- Google analytics是什么,有什么作用
热门文章
- Linux操作系统的8个经典技巧
- 自己闲来无事做的工作日志WEB程序(VB.NET)
- android按钮周围阴影,Android 上的按钮填充和阴影
- 编程道场_编码道场教给我有关敏捷的知识
- devops java使用_谁会在使用DevOps时最大程度地退缩?
- devops 三十六计_DevOps从业人员应遵循的16个博客和新闻通讯
- 2017 开源软件排行_2017年开源大会精选
- android开源2016_开源多样性努力在2016年获得动力
- ES5常用的组合继承及原型链理解
- HTML div元素