php使用curl实现图片上传转发 # 前言 上一篇文章已经介绍过如何实现接口转发,在贴转发代码时也附录了一些涉及此文的代码 上篇文章传送门:http://chenls.me/blog/details.html?id=31 这边再抽出一个文章专门介绍使用curl转发图片。 > 网上大部分搜索到的资料都使用 $data = array('file' => '@' . realpath($path));//‘@' 符号告诉服务器为上传资源 这种方式上传,实测不行,该方法在php5.5以后被废弃,请不要做无谓的测试。 # 实现 正确方式,兼容所有版本 ```php $curl = curl_init(); if (class_exists('\CURLFile')) { curl_setopt($curl, CURLOPT_SAFE_UPLOAD, true); $data = array( 'file' => new \CURLFile(realpath($path)) ); } else { if (defined('CURLOPT_SAFE_UPLOAD')) { curl_setopt($curl, CURLOPT_SAFE_UPLOAD, false); } $data = array('file' => '@' . realpath($path)); //<=5.5 } ``` 贴代码 存储并转发实现: ```php //普通接口转发 $postData = ""; if (strtolower(Request::method()) == 'post') { $postData = Request::post(); } //临时存储文件 $file = Request::file('file'); $save_path = Env::get('runtime_path') . "http://static.chenls.me/chenls/uploads/"; $result = $file->move($save_path); $infoPath = str_replace('\\', '/', $result->getSaveName()); $postData['mypath'] = $save_path . $infoPath; $reback = curl_file_request($url, $postData, $header); //取得临时存储的文件路径,上传给其他业务接口 $reback = curl_file_request($url, $path, $header); ``` ```php /** * 文件上传 * 参数:url,参数(必带文件路径mypath),请求头 */ function curl_file_request($url, $post, $header) { $curl = curl_init(); if (class_exists('\CURLFile')) { curl_setopt($curl, CURLOPT_SAFE_UPLOAD, true); $post['file'] = new \CURLFile(realpath($post['mypath'])); } else { if (defined('CURLOPT_SAFE_UPLOAD')) { curl_setopt($curl, CURLOPT_SAFE_UPLOAD, false); } $post['file'] = '@' . realpath($post['mypath']); } unset($post['mypath']); if ($header) { curl_setopt($curl, CURLOPT_HTTPHEADER, $header); } curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_POST, 1); curl_setopt($curl, CURLOPT_POSTFIELDS, $post); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_HEADER, false); // 不返回头信息 $data = curl_exec($curl); if (curl_errno($curl)) { return ajaxReturn(-1, '系统错误:' . curl_error($curl)); } curl_close($curl); return $data; } ``` 请注意,当临时存储的文件越来越多,肯定非常占用我们本地的硬盘,建议一小时清除一次 ```php //每一小时清除临时文件存储位置 if (!Cache::has('app_delfile_flag')) { $this->delFile(Env::get('runtime_path') . "http://static.chenls.me/chenls/uploads/"); Cache::set('app_delfile_flag', Carbon::now(), 3600); } /** * 递归临时删除文件夹下所有存储的文件 */ protected function deLFile($path) { if (is_dir($path)) { $p = scandir($path); foreach ($p as $val) { if ($val != "." && $val != "..") { if (is_dir($path . $val)) { $this->deLFile($path . $val . '/'); @rmdir($path . $val . '/'); } else { unlink($path . $val); } } } } } ``` 至此,前端上传图片通过中转层转发到各业务平台的业务代码结束。