| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584 |
- <?php
- /**
- * Created by PhpStorm.
- * User: ywl
- * Date: 2017/4/14
- * Time: 11:38
- */
- namespace App\Common\Services;
- use App\Exceptions\ApiException;
- use App\Models\BaseModel;
- use App\Services\CommonBaseService;
- use App\Common\Facades\OssFacade;
- use FFMpeg\Coordinate\TimeCode;
- use FFMpeg\FFMpeg;
- use Illuminate\Support\Facades\Log;
- use Illuminate\Support\Facades\Request;
- class UploadFileService extends CommonBaseService
- {
- /**
- * 文件mineType类型
- * @var array
- */
- private $mineTypeList = [];
- /**
- * 文件扩展名
- * @var array
- */
- private $fileExt = ['png', 'jpg', 'jpeg', 'gif', 'mp4', 'mp3', 'ico', '3gpp', 'ac3', '3gpp', 'ac3',
- 'asf', 'au', 'css', 'csv', 'doc', 'dot', 'dtd', 'dwg', 'dxf', 'gif', 'jp2', 'jpe',
- 'mp2', 'mp3', 'mp4', 'mpeg', 'mpg', 'mpp', 'ogg', 'pdf', 'pot', 'pps', 'ppt', 'rtf', 'svf',
- 'tif', 'tiff', 'txt', 'wdb', 'wps', 'xhtml', 'xlc', 'xlm', 'xls', 'xlt', 'xlw', 'xml',
- 'zip', 'xlsx','docx','webp'];
- /**
- * 文件扩展名
- * @var string
- */
- private $nowFileExt = '';
- /**
- * 文件限制大小,默认20M
- * @var int
- */
- private $limitSize = 1024 * 1024 * 100;
- /**
- * 保存的路径
- * @var string
- */
- private $basePath = './';
- /**
- * 设置文件路径
- * @var string
- */
- private $filePath = '/files';
- /**
- * 上传文件字段
- * @var string
- */
- private $fileField = 'file';
- public function __construct(BaseModel $model)
- {
- parent::__construct($model);
- if(config('app.upload_limit_size')) {
- $this->limitSize = 1024 * 1024 * config('app.upload_limit_size');
- }
- }
- /**
- * 获取本地路径
- * @param $file
- * @return string
- */
- public function getLocalPath($file = '')
- {
- $resourcesPath = 'upload';
- if(config('app.language_path')) {
- if(config('app.language_path') != 'zh-cn') {
- $resourcesPath = config('app.language_path').'/upload';
- }
- }
- return resource_path($resourcesPath) . $file;
- }
- /**
- * 上传图片文件
- * @param $request
- * @param string $fileField
- * @param array|string $fileExt
- * @param bool $isUploadOss
- * @return array
- */
- public function upload($request, $fileField = 'file', $fileExt = [], $isUploadOss = true,$isReName=false)
- {
- $this->fileField = $fileField;
- if (!empty($fileExt)) {
- $this->setFileExt($fileExt);
- }
- $this->validate($request);
- $result = $this->saveLocal($request,$isReName);
- $localPath=$this->getLocalPath().$result['path'];
- if (strpos($result['mimeType'], 'image') !== false) {
- list($width, $height) = getimagesize($localPath);
- $result['resolution'] = $width . '*' . $height;
- }
- $resourcesPath = '/resources';
- if(config('app.language_path')) {
- if(config('app.language_path') != 'zh-cn') {
- $resourcesPath = $resourcesPath.'/'.config('app.language_path');
- }
- }
- $result['url'] = $request->root() .$resourcesPath. $result['path'];
- $path = $this->getLocalPath() . $this->filePath;
- $useFfmpeg= config('app.USE_FFMPEG');
- if ($useFfmpeg&&!empty($result['mimeType'])&&strpos($result['mimeType'], 'video') !== false) {
- $ffmpeg=FFMpeg::create(array(
- 'ffmpeg.binaries' => config('app.ffmpeg.ffmpeg_binaries'),
- 'ffprobe.binaries' => config('app.ffmpeg.ffprobe_binaries'),
- 'timeout' =>config('app.ffmpeg.timeout'), // The timeout for the underlying process
- 'ffmpeg.threads' => config('app.ffmpeg.ffmpeg_threads'), // The number of threads that FFMpeg should use
- ));
- $picFilename = $this->getFilename($path,'jpg');
- $video = $ffmpeg->open($localPath);
- $fileSavePath=$path.'/'.$picFilename;
- $video->frame(TimeCode::fromSeconds(1))->save($fileSavePath);
- if(file_exists($fileSavePath)){
- $checkFileNameStr=str_replace('.'.$result['ext'],'',$picFilename);
- if (preg_match('/^.*[,\.#%\'\+\*\:;^`\{\}\(\)\[\]\s]/', $checkFileNameStr)) {
- $picFilename= preg_replace('/[,\.#%\'\+\*\:;^`\{\}\(\)\[\]\s]/','-', $checkFileNameStr).'.'.$result['ext'];
- }
- $coverOssUrl = OssFacade::uploadToOss($fileSavePath, $picFilename, md5_file($fileSavePath),'share_center',$isReName);
- $result['pic']=$coverOssUrl;//封面图
- }
- }
- if ($isUploadOss) {
- $filename = $result['original_filename'];
- $checkFileNameStr=str_replace('.'.$result['ext'],'',$filename);
- if (preg_match('/^.*[,\.#%\'\+\*\:;^`\{\}\(\)\[\]\s]/', $checkFileNameStr)) {
- $filename= preg_replace('/[,\.#%\'\+\*\:;^`\{\}\(\)\[\]\s]/','-', $checkFileNameStr).'.'.$result['ext'];
- }
- $ossUrl = OssFacade::uploadToOss($localPath, $filename, md5(file_get_contents($localPath)),'share_center',$isReName);
- $result['url'] = $ossUrl;
- //Log::info(json_encode($result));
- if (!empty($result['mimeType'])&&strpos($result['mimeType'], 'video') !== false) {
- // 视频截图
- $picFilename = $this->getFilename($path,'jpg');
- $fileSavePath = $path.'/'.$picFilename;
- downloadFile($ossUrl.'?x-oss-process=video/snapshot,t_1000,f_jpg,w_800,h_600,m_fast', $fileSavePath);
- if (file_exists($fileSavePath)) {
- $coverOssUrl = OssFacade::uploadToOss($fileSavePath, $picFilename, md5_file($fileSavePath),'share_center',$isReName);
- $result['pic']=$coverOssUrl;//封面图
- }
- }
- }
- return $result;
- }
- /**
- * 上传Base64图片
- * @param $request
- * @param string $fileField
- * @param array|string $fileExt
- * @param bool $isUploadOss
- * @return array
- */
- public function uploadImgBase64($data, $fileExt = 'jpg', $host='',$selectFileName='',$isUploadOss = true)
- {
- if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $data, $result)) {
- $type = $result[2];
- if (in_array($type, array('pjpeg', 'jpeg', 'jpg', 'gif', 'bmp', 'png'))) {
- $this->nowFileExt = strtolower($type);
- $path = $this->filePath;//$this->basePath.$this->filePath;
- $path.="/" .date('md') . "/".uniqid()."/";
- $localPath=$this->getLocalPath().$path;
- if(empty($selectFileName)){
- $filename = $this->getFilename($localPath);
- }else{
- $filename= $selectFileName.'.'.$this->nowFileExt;
- }
- $filepath = $localPath . '/' . $filename;
- if (!file_exists($localPath)) {
- mkdir($localPath, 0777, true);
- }
- if (file_put_contents($filepath, base64_decode(str_replace($result[1], '', $data)))) {
- $size = filesize($filepath);
- $s = getimagesize($filepath);
- $width = empty($s[0]) ? '' : $s[0];
- $height = empty($s[1]) ? '' : $s[1];
- $result = [
- 'path' => $path.$filename,
- 'size' => $size,
- 'filename' => $filename,
- 'original_filename' => $filename,
- 'ext' => $this->nowFileExt,
- 'resolution' => $width . '*' . $height,
- 'url' => $host.'/resources'.$path.$filename,
- 'mimeType' => 'image/' . $this->nowFileExt
- ];
- if ($isUploadOss) {
- $ossUrl = OssFacade::uploadToOss($filepath, $filename, md5(file_get_contents($filepath)));
- $result['url'] = $ossUrl;
- }
- return $result;
- // echo '图片上传成功</br><img src="' .$img_path. '">';
- } else {
- throw new ApiException(1101);
- }
- } else {
- //文件类型错误
- throw new ApiException(1101);
- }
- } else {
- //文件错误
- throw new ApiException(1101);
- }
- return false;
- }
- /**
- * 上传文本转为文件
- * @param $request
- * @param string $fileField
- * @param array|string $fileExt
- * @param bool $isUploadOss
- * @return array
- */
- public function uploadTextToFile($data, $fileExt = '', $isUploadOss = true)
- {
- if (!empty($fileExt)) {
- $this->nowFileExt = strtolower($fileExt);
- $path = $this->getLocalPath() . $this->filePath;
- $filename = $this->getFilename($path);
- $filepath = $path . '/' . $filename;
- if (!file_exists($path)) {
- mkdir($path, 0777, true);
- }
- if (file_put_contents($filepath, $data)) {
- $size = filesize($filepath);
- $s = getimagesize($filepath);
- $result = [
- 'path' => $filepath,
- 'size' => $size,
- 'filename' => $filename,
- 'original_filename' => $filename,
- 'ext' => $this->nowFileExt,
- 'url' => ''
- ];
- if ($isUploadOss) {
- $ossUrl = OssFacade::uploadToOss($filepath, $filename, md5(file_get_contents($filepath)));
- $result['url'] = $ossUrl;
- }
- return $result;
- }
- }
- return false;
- }
- /**
- * 设置扩展名
- * @param array $fileExt
- * @return $this
- */
- public function setFileExt($fileExt)
- {
- if (empty($fileExt)) {
- return;
- }
- if (!is_array($fileExt)) {
- $fileExt = explode(',', $fileExt);
- }
- $this->fileExt = $fileExt;
- return $this;
- }
- /**
- * 上传验证
- * @param $request
- * @return bool
- * @throws ApiException
- */
- private function validate($request)
- {
- $fileInfo = $request->file($this->fileField);
- // if (!$request->hasFile($this->fileField) || !$fileInfo->isValid()) {
- // throw new ApiException(30002);
- // }
- if (!$this->checkFileExt($fileInfo)) {
- throw new ApiException(1101);
- }
- if (!$this->checkLimitSize($fileInfo)) {
- $limit = floor($this->limitSize / (1024 * 1024)) . 'M';
- throw new ApiException(1102, ['limit' => $limit]);
- }
- $this->checkDirectory($this->filePath);
- return true;
- }
- /**
- * 检查文件扩展名
- * @param $fileInfo
- * @return bool
- */
- private function checkFileExt($fileInfo)
- {
- $fileType = strtolower($fileInfo->getClientOriginalExtension());
- if (!$fileType || !in_array($fileType, $this->fileExt)) {
- return false;
- }
- $this->nowFileExt = strtolower($fileType);
- return true;
- }
- /**
- * 验证文件大小
- * @param $fileInfo
- * @return bool
- */
- private function checkLimitSize($fileInfo)
- {
- $clientSize = $fileInfo->getSize();
- if ($clientSize > $this->limitSize) {
- return false;
- } else {
- return true;
- }
- }
- /**
- * 检验文件夹,不存在则创建
- * @param $path
- */
- private function checkDirectory($path)
- {
- $folders = explode('/', $path);
- $basePath = $this->getLocalPath();//$this->basePath;
- foreach ($folders as $item) {
- if (empty($item)) {
- continue;
- }
- if (strrpos($basePath, '/') !== strlen($basePath) - 1) {
- $basePath .= '/';
- }
- $basePath .= $item;
- $this->makeDir($basePath);
- }
- }
- /**
- * 新增文件目录
- * @param $path
- * @return mixed
- */
- private function makeDir($path)
- {
- if (is_dir($path)) {
- return $path;
- } else {
- mkdir($path, 0777, true);
- return $path;
- }
- }
- /**
- * 上传保存到本地
- * @param $request
- * @return array
- */
- private function saveLocal($request,$isReName=false)
- {
- $fileInfo = $request->file($this->fileField);
- $path = $this->filePath;//$this->basePath.$this->filePath;
- $path.="/" .date('md') . "/";
- $OldFilename = $fileInfo->getClientOriginalName();
- if($isReName){
- $localPath=$this->getLocalPath().$path;
- $filename = $this->getFilename($localPath);
- }else{
- $path.= uniqid()."/";
- $localPath=$this->getLocalPath().$path;
- $filename= $OldFilename;
- }
- $fileSize = $fileInfo->getSize();
- $mimeType = $fileInfo->getMimeType();
- $fileInfo->move($localPath, $filename);
- // Log::info($this->filePath.'/'.$filename);
- return [
- 'path' => $path.$filename,
- 'size' => $fileSize,
- 'filename' => $filename,
- 'original_filename' => $OldFilename,
- 'ext' => $this->nowFileExt,
- 'mimeType' => $mimeType
- ];
- }
- /**
- * 获取文件名
- * @param $path
- * @return string
- */
- private function getFilename($path,$ext='')
- {
- $suffix=empty($ext)? $this->nowFileExt:$ext;
- $fileName = date('YmdHis') . mt_rand(100, 999) . '.' . $suffix;
- if (file_exists($path .'/'. $fileName)) {
- return $this->getFileName($path,$ext);
- }
- return $fileName;
- }
- /**
- * 设置文件路径
- * @param string $path
- * @return $this
- */
- public function setFilePath($path)
- {
- $this->filePath = $path;
- return $this;
- }
- /**
- * 设置文件大小
- * @param string $maxSize
- * @return $this
- */
- public function setMaxSize($maxSize = '')
- {
- if ($maxSize && is_numeric($maxSize)) {
- $this->limitSize = $maxSize;
- }
- return $this;
- }
- /**
- * 设置文件mineType
- * @param array $mineType
- * @return $this
- */
- public function setMineType($mineType = [])
- {
- if ($mineType) {
- $this->mineTypeList = $mineType;
- }
- return $this;
- }
- /**
- * 上传远程文件
- * */
- public function uploadRemoteImg($remoteUrl, $isReName = false)
- {
- $ossUrl = '';
- $ext = getExtFromUrl($remoteUrl);
- if (!empty($remoteUrl) && in_array($ext, $this->fileExt)) {
- $path = $this->filePath;
- $path .= "/" . date('md') . "/";
- $OldFilename = basename($remoteUrl);
- //如果包含中文则重命名
- if(preg_match('/[\x{4e00}-\x{9fa5}]/u', $OldFilename)) {
- $py = app()->make(PinYinService::class);
- $newName = strtolower($py->getAllPY($OldFilename));
- if(!empty($newName)) {
- $OldFilename = preg_replace('/[^a-zA-Z0-9_u4e00-u9fa5]/', '-', $newName).'.'.$ext;
- } else {
- $isReName = true;
- }
- }
- if ($isReName) {
- $localPath = $this->getLocalPath().$this->filePath;
- $path .= uniqid() . "/";
- $filename = $this->getFilename($localPath, $ext);
- } else {
- $path .= uniqid() . "/";
- $filename = $OldFilename;
- }
- $realPath = $this->getLocalPath().$path;
- if (!file_exists($realPath)) {
- mkdir($realPath, 0777, true);
- }
- $saveToUrl = $realPath . $filename;
- if (str_contains($remoteUrl, 'data:image/png;')) {
- try {
- // 分离出数据
- list($type, $data) = explode(';', $remoteUrl);
- list(, $data) = explode(',', $data);
- // 将Base64字符串解码成二进制数据
- $image = base64_decode($data);
- // 指定文件名和保存路径
- // 保存文件
- file_put_contents($saveToUrl, $image);
- $ossUrl = $path.$filename;
- } catch (\Exception $e) {
- }
- } else {
- if ((strpos($remoteUrl, "http://") !== false || strpos($remoteUrl, "https://") !== false)) {
- $remoteUrl = preg_replace('/\?v=.*/', '', $remoteUrl);
- $saveToUrl = mb_convert_encoding($saveToUrl, "UTF-8");
- downloadRemoteFile($remoteUrl, $saveToUrl);
- $ossUrl = $path.$filename;
- }
- }
- }
- if ($ossUrl) {
- $ossUrl = Request::root() . '/resources' . $ossUrl;
- }
- return $ossUrl;
- }
- /**
- * 上传图片文件
- * @param $request
- * @param string $fileField
- * @param array|string $fileExt
- * @param bool $isUploadOss
- * @return array
- */
- public function uploadCustomImage($request, $fileField = 'file', $fileExt = [], $isUploadOss = true, $isReName = false)
- {
- $this->fileField = $fileField;
- if (!empty($fileExt)) {
- $this->setFileExt($fileExt);
- }
- $this->validateCustom($request);
- $result = $this->saveCustomLocal($request);
- $resourcesPath = '/resources';
- if(config('app.language_path')) {
- if(config('app.language_path') != 'zh-cn') {
- $resourcesPath = $resourcesPath.'/'.config('app.language_path');
- }
- }
- $result['url'] = $request->root() . $resourcesPath . $result['path'];
- return $result;
- }
- private function validateCustom($request)
- {
- $fileInfo = $request->file($this->fileField);
- if (!$this->checkFileExt($fileInfo)) {
- throw new ApiException(1101);
- }
- $clientSize = $fileInfo->getSize();
- $limitSize = 1024 * 1024 * 5;
- if ($clientSize > $limitSize) {
- throw new ApiException(1102, ['limit' => 5]);
- }
- $this->checkDirectory($this->filePath);
- return true;
- }
- private function saveCustomLocal($request)
- {
- $fileInfo = $request->file($this->fileField);
- $path = '/custom_files';//$this->basePath.$this->filePath;
- $path .= "/" . date('Ymd') . "/".strtolower(uniqid())."/";
- $OldFilename = $fileInfo->getClientOriginalName();
- $localPath = $this->getLocalPath() . $path;
- $filename = $this->getFilename($localPath);
- $fileSize = $fileInfo->getSize();
- $mimeType = $fileInfo->getMimeType();
- $fileInfo->move($localPath, $filename);
- return [
- 'path' => $path . $filename,
- 'size' => $fileSize,
- 'filename' => $filename,
- 'original_filename' => $OldFilename,
- 'ext' => $this->nowFileExt,
- 'mimeType' => $mimeType
- ];
- }
- }
|