高级版 一种图片上传方式,后台处理图片请求 [ 2.0 版本 ]
advance 版分开backend 和 frontend后,前台后台共享上传图片出现了一个问题,怎样实现?
解决办法很多:
1、上传时候图片保存到前台的web目录下,此时前台应用可以直接访问,数据库仅存路径如'/upload/a.png',后台访问时候在请求前加上前台的host地址如'http://www.test.com/upload/a.png' ;这样就能实现前后台上传图片并同时指向同一个目录文件;参考源码 feehicms backend\widgets\ueditor\UeditorAction backend\widgets\ActiveField
;
2、上传时候图片保存到单独的web目录下,为这个目录配置一个应用,作为图片服务器,上传时候将在目录前加上该服务器的host;
3、上传到第三方,不再上传到本机;
当然上传到第三方服务器有一个成本的考虑,业务量不大当然还是希望上传到本机。这里我修改了一下第一种方式,由于后台是没有图片目录,图片请求最后会交给yii处理,则配置一下后台控制器处理一下请求即可,这样不用增加处理图片的链接方法。
开启url匹配规则,将所有图片请求传给上传控制器
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
'upload/<default:[\w\d]+(/[\w\d]+)*\.(png|jpg|jpeg)>'=>'upload/default/index',//配置了模块去处理
// '<upload:[\w\d]+(/[\w\d]+)*\.(png|jpg|jpeg)>'=>'upload/index',//直接使用控制器处理
控制器中,找到图片后发送,否则发404
public function actionIndex()
{
$pathImg='@frontend/web/';
try{
$url=\yii::$app->getRequest()->getUrl();
$path=parse_url($url);
if(isset($path['path']) && is_file( ($file=\Yii::getAlias($pathImg.$path['path'])))){
$response=\yii::$app->getResponse();
$img=pathinfo($path['path']);
$response->getHeaders()->set('Content-Type','image/'.(isset($img['extension'])?$img['extension']:'png'));
$response->format=Response::FORMAT_RAW;
$response->content=file_get_contents($file);
$response->send();
}
}catch (Exception $e){
}
throw new NotFoundHttpException();
}
这样的处理方式,实际上还可以获得一个启发,比如将用户的个人信息存放的前后台都不能直接访问的目录中,可以在添加权限,验证session只有登录用户才可以访问,也可以增加请求参数,通过判断参数,只有正确的参数才可以访问到图片,等等,该功能可以结合方法2,实现快速响应同时增加权限控制。
lbmzorx
注册时间:2017-10-20
最后登录:2024-01-29
在线时长:189小时41分
最后登录:2024-01-29
在线时长:189小时41分
- 粉丝6
- 金钱15240
- 威望100
- 积分18130
共 1 条评论
可以改进一下,url 规则
'upload/<path:[\w\d]+(/[\w\d]+)*>.<extension:(png|jpg|jpeg)>'=>'upload/index',
控制器中
public function actionIndex(){ $request=\yii::$app->request; $path=$request->get('path'); $extension=$request->get('extension'); if($path && in_array($extension,['png','jpg','jpeg'])){ try{ $file=\Yii::getAlias('@frontend/web/'.$path.'.'.$extension); if( file_exists($file )){ $response=\yii::$app->getResponse(); $response->getHeaders()->set('Content-Type','image/'.($extension)); $response->format=Response::FORMAT_RAW; $response->content=file_get_contents($file); $response->send(); return $response; } }catch (Exception $e){ } } throw new NotFoundHttpException(); }
不用再依赖pathinfo()函数,
如果nginx配置不成功,可以参考下面的配置
location ~/upload/.*\.(jpg|jpeg|png)$ { try_files $uri $uri/ /index.php$is_args$args; }