- A+
前面介绍了 ThinkPHP5 文件上传类,下面我们利用 ThinkPHP5 文件类实现上传文件至 OSS。文件保存在OSS有以下好处:
1)实现服务器水平扩展(负载均衡)时,可以保证用户上传的文件保存在单独的服务器,避免服务器之间文件同步带来的延迟
2)降低项目文件磁盘占用量,提供服务器性能
3)如果项目发生迁移维护,可以加快迁移效率
3)对于大型项目,如果每个项目都有上传文件,可能带来项目之间图片访问的麻烦,这样可以完全避免跨域访问图片
4)图片单独保存,对于 CDN 也更加友好
首先,自定义 UploadOss 类,为了保护OSS的配置信息,我们采取单例模式
namespace app\common\tool; use think\Config; use think\File; use OSS\OssClient; class UploadOss extends Upload { private $oss; private $accessKeyId; private $accessKeySecret; private $endpoint; private $bucket; private $accessUrl; /** * 构造方法 * @param array $data OSS配置信息 * @access final private 为保护配置信息,构造函数不允许访问 且不可重载 * @return void */ final private function __construct($data) { $this->accessKeyId = $data["accessKeyId"]; $this->accessKeySecret = $data["accessKeySecret"]; $this->endpoint = $data["endpoint"]; $this->bucket = $data["bucket"]; $this->accessUrl = $data['url']; //引入oss扩展 vendor("aliyuncs.oss-sdk-php.vendor"); $this->oss = new OssClient($this->accessKeyId, $this->accessKeySecret, $this->endpoint); } }
类的实例方法并传入OSS配置信息
/** * 类的实例构造方法,自动传入配置信息 * @access static * @return object */ public static function instance() { if (empty(self::$instance)) { self::$instance = new self(Config::get("ali.OSS")); } return self::$instance; }
上传服务器图片至OSS
/** * 上传文件至阿里OSS * @param string $subject 保存至OSS的对象名称 * @param string $file 要保存在OSS的图片路径 * @access protected * @return string */ protected function uploadFileOss($subject, $file) { $subject = $this->formatPath($subject); try { $this->oss->uploadFile($this->bucket, $subject, $file); @unlink($file); return $subject; } catch (OssException $e) { $e->getErrorMessage(); } }
上传图片至OSS
/** * 上传图片 * @param object $file 上传的图片对象 * @param string $save_path 保存的路径 * @param array $validate 验证规则 * @access publice * @return array */ public function uploadPicture(File $file, $save_path = "", $validate = [], $rule = 'date') { $upload_info = $this->uploadPictures($file, $save_path, $validate, $rule); if ($upload_info['status'] == 0) { return $upload_info; } //同步至阿里OSS $subject = $this->uploadFileOss($upload_info['save_path'], $upload_info['absolute_path']); return ['status' => 1, "save_path" => $subject]; }
上传文件至OSS
/** * 上传文件 * @param object $file 上传的文件对象 * @param string $save_path 保存的路径 * @param array $validate 验证规则 * @access publice * @return array */ public function uploadFile(File $file, $save_path = "", $validate = [], $rule = 'date') { $upload_info = $this->uploadFiles($file, $save_path, $validate, $rule); if ($upload_info['status'] == 0) { return $upload_info; } //同步至阿里OSS $this->uploadFileOss($upload_info['save_path'], $upload_info['absolute_path']); return $upload_info; }
删除OSS文件
/** * 从OSs删除图片 * @param string $subject 保存至OSS的对象名称 * @access public * @return array */ public function deletePicture($subject) { try { $this->oss->deleteObject($this->bucket, $subject); } catch (OssException $e) { throw($e->getErrorMessage()); } return ['status' => 1, "msg" => "删除成功"]; }
调用实例
UploadOss::instance()->uploadPicture($this->request->file("file_name"), "/uploads/tmp");