PHP中之框架众多,我自己虽点了少数单。大学那会吗吧非知情吗啊无见面,拿了一个ThinkPHP学了。也许有不少口吐槽TP,但是个人感觉不克说谁框架好,哪个框架不好,再不好的框架而会管源码读上亦然所有,框架的规划思想理解了吧能效仿到许多事物。况且有无数物好还免晓得,所以认真上一个框架这还是足以效仿多事物的。

  还是事先说说Laravel吧,现在早已到5.2了。就我好吧之前未曾碰过laravel,但是上了laravel之后感觉这个框架确实是,并且一直外用的欣喜若狂。他的开社区还好,文档比较齐全,但是官网文档不咋地,从地方读不发生多少东西(自己觉得),好多事物还得看源码,对于自己这种英语不好的口尚更爱中文文档(以后得改变)。Laravel是运Composer(https://getcomposer.org)来管理依赖,确实比较方便,但是因为镜像被墙的原因在访问或者更新的时候比较慢(几乎失败),这里有解决办法:http://pkg.phpcomposer.com/\#tip1。

  最近以做事亟待种如重构(重构原因并非多说,大家领略),需要迁移至新的框架达成。Laravel是一个毋庸置疑的框架,强大的路由,便捷的配置,高可用之模块依赖,确实也开发省了众力。考虑到我们是路根本是接口部分,对性能有必然的渴求(但是非是苛刻),并且路由于未可知转,要配合老的逻辑,所以Laravel是首选,但是生一个题目便是咱们是描摹接口,那么要乘的事物就是掉杀多,比如view层几乎用无交,还有即使是测试模块,上传模块(有图床),本地化模块文件系统等为用非交,所以采取Laravel还是于浪费的,说白了外比较还。所以我们就考虑了基于laravel的一个框架Lumen,相比Laravel这个全栈框架而言Lumen精简了累累,并且Lumen是面向Api的,所以最后就分选Lumen了。

  laravel也不是万能的产生可取也产生瑕疵,比如他的借助太多,可以看一下安装好的laravel框架默认的靠源包就起30M左右,确实来硌老。直到今天以采用过程中发现Lumen也是发硌无法,随着事情逻辑更是复杂,访问速度各地方为下来了,我们有时候考虑
slim
等重轻量级的,其实吧新浪这边不少人口是小鸟哥粉,不少人推崇yaf,yaf确实牛逼,实践证明快之穿梭一点个别沾,估计下还得迁移到yaf。这段时光PHP7不是发了也,但是测试结果表明Bug不丢掉,把接口迁移至7齐应当生出好多底特性提升,据说是增高100%,还并未敢品尝,等稳定了再说吧!

  说了很多废话,下面我哪怕介绍一下Laravel中之日志与上传,慢慢来,这首稿子先勾勒一些,因为Laravel东西比多,其他的我会慢慢写出来。我虽说说好在利用过程遭到碰到的题材,遇到的坑,帮助大家学习。

一、日志

1、说明:

日记重要性不言而喻,我们当即边的日志是人为推荐,兴趣爱好,推荐位的负。做推荐的同窗比写接口的还要多,日志出了问题,推荐就见面不规范甚至束手无策推荐,可见日志的最主要。

Laravel框架初始化好了之后错误与深处理既默认配置好了,他的日志是冲一款很好用之日记管理工具Monolog,

  首先说一下Monolog,是php下比较全而容易扩展的记录日志组件。其中Symfony

CakePHP等知名php框架还放置了Monolog,有趣味之可扣押一下。每个Logger实例都起一个坦途及日志处理器栈。每当你加加同久日志记录,它见面吃发送至日志处理器栈。
你得创建很多Logger每个Logger定义一个通道(db,请求,路由于),每个Logger有那么些日志处理器。这些通道会过滤日志。每个日志处理器都有一个Formatter(内置的日记显示格式处理器)。你还足以设定日志级别。(官网解释)

  日志配置:Laravel目前支持四种植日志处理器,

1 Single(将日志记录到单个文件中。该日志处理器对应,对应StreamHandler),
2 
3 Daily (以日期为单位将进行日志记录对应RotatingFileHandler)
4 
5 Syslog(将日志记录到Syslog中。对应SysLogHandler)
6 
7 Errorlog(将日志记录到PHP的error_log中。对应ErrorLogHandler)

解了日志的处理方式我们尽管足以安装好要的方,在
config/app.php中的附和项设置(默认的):

1 'log' => 'single',

2、使用Log记录日志

Laravel提供了Log方法记录日志,Log其实采取的
Illuminate\Log\Writer,应为当中间
Writer的构造函数中注入了Monolog\Logger。生成的日记文件存放于storage/logs目录下。

如下:

1 Log::emergency($error); //紧急,如系统挂掉
2 Log::alert($error);     //需要立即采取行动,如数据库异常等
3 Log::critical($error);  //严重问题,如异常
4 Log::error($error);     //运行时错误,不需要立即处理但需要被记录和监控
5 Log::warning($error);   //警告但不是错误,比如使用了被废弃的API
6 Log::notice($error);    //普通但值得注意的事件
7 Log::info($error);      //感兴趣的事件,比如登录、退出
8 Log::debug($error);     //详细的调试信息

3、按照好之求记录日志

Laravel中如果按照原先的布置一般不能够按好之需求记录日志,我不怕以好的要求写了一个,供大家参考,当然你可过了他提供的日记处理办法Log,在容器被拿
Monolog对象写副容器,可以描绘成单例的样式,这样于加载的时偏偏实例化一涂鸦
,然后以monolog来配置好想只要之笔录日志的主意。

 1 class Save_log
 2 {
 3     //存放每个级别实例
 4     private static $obj_log = [];
 5 
 6     //日志类型映射
 7     private static $classify_arr = ['default', 'debug_log','error_log'];
 8 
 9     /**
10      * 单利初始化以及调取对象
11      * @param $classify 日志的的频道,对应不同的目录
12      * @param $max_num  日志记录的最大数量
13      */
14     public static function get_log_instance($classify = 'default', $max_num = 0)
15     {
16         if(empty(self::$obj_log[$classify])) {
17             self::$obj_log[$classify] = new Writer(new Logger($classify));
18             self::$obj_log[$classify]->useDailyFiles(self::get_path($classify), $max_num);
19         }
20         return self::$obj_log[$classify];
21     }
22 
23     /**
24      * 映射对应的目录
25      * @param $classify 日志的不同的频道
26      */
27     private static function get_path($classify)
28     {
29         $root_path = public_path();
30         $path = $root_path . '/../../logs/'; //可以是自己的任意路径
31         $log_arr = self::$classify_arr;
32         if(!empty($log_arr) && !empty($classify)) {
33             if(in_array($classify, $log_arr)) {
34                 return $path . $classify. '/' . $classify . '.log';
35             }
36         }
37         return $path . 'default/default.log';
38     }
39 
40     /**
41      * 映射对应的目录
42      * @param $func 调用的方法
43      * @param $arguments 参数,包括数据和日志等级
44      */
45     public static function __callStatic($func, $arguments)
46     {
47         $get_obj = self::get_log_instance($func);
48         if(empty($get_obj)) {
49             log::error('Save Log Error!');
50         }
51         if(empty($arguments) || !is_array($arguments) || !isset($arguments[0])) {
52             $get_obj->info('No Data Save!');
53         } else if(!isset($arguments[1])) {
54             $get_obj->info($arguments[0]);
55         } else {
56             $get_obj->{$arguments[1]}($arguments[0]);
57         }
58     }
59 }

利用的时候可指定,如下:

1 Save_log::error_log($info, 'error');
2 Save_log::debug_log($info);

日记内容如下:

图片 1

图片 2

其次、上传文件。

Laravel中之上传文件是基于Flysystem提供的文件系统来兑现上传,删除,移动。他支持多令,还有一个值得看的讲话存储,在SAE上需为此到。

文件系统配置在Config/filesystems.php,我用的小试牛刀本地驱动。Laravel中的上传目录有星星点点个:public和Storage两单,有人说立刻片单同,其实是起分的,应该算得各发裨益,如果在public中,服务器可以直接决定访问,方便效率高,放在Storage中得以长用户控制以权限等。

上传需要之函数如下:

判断是否进行了上传,是否存在文件:

1 $request->hasFile('file')

判定上传是否出错:

1 $file = $request->file('file');
2 //判断文件上传过程中是否出错
3 if(!$file->isValid()) {
4      exit('文件上传出错!');
5 }

规定上传:

1 $bytes = Storage::put(
2       $savePath,
3       file_get_contents($file->getRealPath())
4 );

乃也可采取:

$path = $file -> move('storage/uploads');

别缩略图

Laravel木有供函数生成缩略图,但是我们可以依赖强大的Composer来引入图片处理库
Integration/Image

以档次根本目录中的composer.json中的require中添加:”intervention/image”:
“dev-master”,如下图:

图片 3

然后以config/app.php中providers数组中长:

1 Intervention\Image\ImageServiceProvider::class

以aliases数组中补充加别名:

1 'Image'     => Intervention\Image\Facades\Image::class,

这般虽可采取了,在近似公事被增长:

1 use Image;

下面是丰富水印并且转变缩略图:

$Image->text('@ u/'. $user_id, $news_width - 40 - $length * 10, $news_height - 24, function($font) {
       $font->file('public/foos.ttf');
       $font->size(14);
       $font->color('#ffffff');
 });

最终附上整个源码,其中变化缩略图有好抽象出来,因为起一些独地方还亟需以,并且水印还有看图片大小等等。

  1 /**
  2  * 上传文件
  3  * @param  Object Request
  4  * @return Json result
  5  */
  6 public function upload_file(Request $request)
  7 {
  8     $user_id = $request->get('user_id');
  9     $width = $request->get('width');
 10     $height = $request->get('height');
 11     $upload_type = $request->get('upload_type');
 12     $watermark = $request->get('watermark');
 13 
 14     //参数检查
 15     if(empty($user_id)) {
 16         return response()->json(['code' => 1001, 'msg' => '参数错误']);
 17     }
 18 
 19     //得到上传文件名
 20     if(!empty($_FILES)) {
 21         $key_arr =  array_keys($_FILES);
 22         $file_key = $key_arr[0];
 23     }
 24     
 25     $file_key = !isset($file_key) || empty($file_key) ? 'fileselect' : $file_key;
 26 
 27     if(!$request->hasFile($file_key)) {
 28         return response()->json(['code' => 1002, 'msg' => '上传文件为空']);
 29     }
 30 
 31     $upload_files = $request->file();
 32     if(empty($upload_files) || !is_array($upload_files)) {
 33         return response()->json(['code' => 1003, 'msg' => '上传失败']);
 34     }
 35 
 36     //兼容单文件上传
 37     if(Utils::arrayLevel($upload_files) < 2) {
 38         $files[$file_key][0] = $upload_files[$file_key];
 39     } else {
 40         $files = $upload_files;
 41     }
 42 
 43     if($upload_type == 'userphoto' && count($files[$file_key]) > 1) {
 44         return response()->json(['code' => 1004, 'msg' => '头像只能上传一张']);
 45     }
 46 
 47     if(count($files[$file_key]) > MAX_UPLOAD_FILE) {
 48         return response()->json(['code' => 1005, 'msg' => '大于最大上传数限制']);
 49     }
 50 
 51     //过滤大于MAX_FILE_SIZE的情况
 52     foreach ($files[$file_key] as $key => $file) {
 53         if($file-> getClientSize() > MAX_FILE_SIZE * 1024 * 1024) {
 54             return response()->json(['code' => 1006, 'msg' => '文件大小不能超过']);
 55         }
 56     }
 57 
 58     $file_info = [];
 59     $length = strlen($user_id . '');
 60     //兼容批量上传
 61     foreach ($files[$file_key] as $key => $file) {
 62         if(!$file->isValid()) {
 63             return response()->json(['code' => 1007, 'msg' => '上传出错']);
 64         }
 65 
 66         if($upload_type == 'userpic') {
 67             $file_dir = 'userpic';
 68         } else {
 69             $type = $file->getMimeType();
 70             if(empty($type) && !is_array($type)) {
 71                 return response()->json(['code' => 1008, 'msg' => '得到文件类型出错']);
 72             }
 73 
 74             //映射文件类型
 75             $type_arr = explode("/", $type);
 76             switch($type_arr[0]){
 77                 case "image"      : $file_dir = "image"; break;
 78                 case "video"      : $file_dir = "video"; break;
 79                 case "audio"      : $file_dir = "voice"; break;
 80                 case "text"       : $file_dir = "doc";   break;
 81                 case "application": $file_dir = "doc";   break;
 82                 default           : $file_dir = "other"; break;
 83             }
 84         }
 85 
 86         //文件后缀
 87         $postfix = $file->getClientOriginalExtension();
 88         $save_dir = UPLOAD_FILE_PATH;
 89         $file_date = date('Ym');
 90         $file_name = $file_dir . '_' . $file_date . '_' . rand(111111, 999999) . $user_id;
 91         $save_name = $file_name . '.' . $postfix;
 92         $save_path = $file_dir . '/' . $file_date . '/' . $save_name;
 93         Storage::put(
 94             $save_path, 
 95             file_get_contents($file->getRealPath())
 96         );
 97         if(!Storage::exists($save_path)) {
 98             return response()->json(['code' => 1009, 'msg' => '保存文件失败']);
 99         }
100 
101         //生成缩略图
102         if($file_dir == 'image' && (!empty($width) || !empty($height))) {
103             $Image = Image::make($save_dir . $save_path);
104             $img_width = $Image->width();
105             $img_height = $Image->height();
106 
107             //如果有一个为空,则与另一个相等;
108             if(empty($width)) {
109                 //传入的高度如果比实际高度大,就取实际高度
110                 $height = $img_height < $height ? $img_height : $height;
111                 $width = $height;
112             } else if(empty($height)) {
113                 $width = $img_width < $width ? $img_width : $width;
114                 $height = $width;
115             } else {
116                 $height = $img_height < $height ? $img_height : $height;
117                 $width = $img_width < $width ? $img_width : $width;
118             }
119 
120             //拼接缩略图路径
121             $Image->resize($width, $height);
122             $save_name_s = $file_name . '_s.' . $postfix;
123             $save_path_s = $save_dir . $file_dir . '/' . $file_date . '/' . $save_name_s;
124             $file_path_s = $request->root() . '/' . $save_path_s;
125 
126             if($watermark != 1) {
127                 //添加缩略图水印
128                 $news_width = $Image->width();
129                 $news_height = $Image->height();
130                 if($news_width > 100) {
131                     $Image->text('@ u/'. $user_id, $news_width - 40 - $length * 10, $news_height - 24, function($font) {
132                         $font->file('public/foos.ttf');
133                         $font->size(14);
134                         $font->color('#ffffff');
135                     });
136                 }
137             }
138 
139             //保存缩略图
140             $Image->save($save_path_s, 100);
141             $file_size_s = round($Image->filesize() / 1024 ,2) . 'K';
142         }
143 
144         $file_path = $request->root() . '/' . $save_dir . $save_path;
145         $file_size = round($file-> getClientSize() / 1024 ,2) . 'K';
146         $file_info[] = compact(
147             'save_name', 'file_size', 'file_path', 'save_name_s', 'file_size_s', 'file_path_s'
148         );
149     }
150 
151     if(empty($file_info)) {
152         return response()->json(['code' => 1010, 'msg' => '异常出错']);
153     } else {
154         return response()->json(['code' => 0, 'msg' => '', 'data' => $file_info]);
155     }
156 }

结束语:

如上是自家读书着相见的一模一样有问题,不针对的处欢迎指正,这篇稿子只是说了日志与上传,以后会不断创新,包括路由,中间件,容器等等,还有好多需要说的。

注意:

1、本博客同步更新到本人的私有网站:http://www.zhaoyafei.cn

2、本文属原创内容,为了珍惜他人劳动,转载请注明本文地址:

http://www.cnblogs.com/zyf-zhaoyafei/p/5076515.html

 

相关文章

网站地图xml地图