在ThinkPHP5之前,ThinkPHP和laravel除了都是采用MVC整体架构模式外,没有其他的相同点,但是从ThinkPHP5开始,ThinkPHP5的结构和语法都在向laravel学习,可以说大部分都一样了,因为laravel的官方文档是英文的,因此建议先学习ThinkPHP5的官方文档,然后再看laravel文档,la会让你快速上手laravel。
laravel官方文档地址:
https://laravel.com/docs
不过国内访问比较慢,可以选择国内的翻译文档看,比如下面的这个网址,可能更新速度比较慢:
https://www.golaravel.com/
在这里不讲laravel的使用,官方文档更详细,这里继续讲使用laravel来搭建企业级API架构的几个方面。
laravel官方提供一个精简版本:lumen,如果只是用于API开发,推荐使用lumen,性能比laravel要好很多,官方文档地址:
https://lumen.laravel-china.org/
laravel企业级项目架构搭建思路还是和上节课一样,分四部分:分层的划分,API版本控制,权限控制,接口文档。laravel的安装请参考官方文档,配置虚拟域名请参考之前的文章全栈开发之PHP开发课程第二讲--开发环境搭建
这里补充一个技巧,如果通过composer安装laravel过程中出现如下错误:
可以通过如下网址下载证书文件,并复制到wamp的PHP安装目录:
https://curl.haxx.se/docs/caextract.html
然后配置php.ini文件,修改openssl.cafile配置为证书文件的路径:
最后重启wamp所有服务即可。
分层的划分:安装完后默认生成了项目模块架构,默认是按照三层架构来生成的,服务层对应app目录下的Providers文件夹,控制器层对应app目录的Http文件夹,模型层需要通过命令手动创建,也是在app目录下,创建模型命令格式为:php artisan make:model 模型名称
由此可以看到laravel比ThinkPHP更专业,基本上就是按照企业级架构来设计的。
API版本控制:laravel控制api版本最简单的方式是通过路由来实现,不需要其他的第三方扩展包,路由规则如下: Route::prefix('v1')->group(function() { Route::get('list','ListController@index');});Route::prefix('v2')->group(function() { Route::get('method','v2\\MethodController@index');});
表示路由api/v1/list访问app/Http/Controllers下面的ListController.php中的index方法
路由api/v2/method访问app/Http/Controllers/v2/MethodController.php中的index方法
但是这样子有个不好就是需要对每个接口都要定义路由,如果不想这么麻烦,可以用第三方的扩展dingo来实现,连接口认证都一同提供了。
具体使用可以参考官方地址:
https://github.com/dingo/api
中文文档地址:
https://www.bookstack.cn/read/dingo-api-wiki-zh/README.md
权限控制:laravel默认提供了oauth协议的access_token是验证方式,oauth协议入门可以查看如下文章:http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html
laravel提供了Passport扩展来简化oauth的实现,具体的使用方式参考如下文章:
https://xueyuanjun.com/post/9745
接口文档:自动生成接口文档可以使用上节课讲的第三方依赖,也可以使用 Laravel 专用的api文档生成器,GitHub地址:https://github.com/mpociot/laravel-apidoc-generator/
具体安装请参考官方文档,或者查看下国人写的文章:
https://xueyuanjun.com/post/4578.html 今日习题 来看看本节课的习题:使用laravel官方提供的api校验文档,实现api校验?
参考答案将在下一节最后给出。好了,最后我们来回顾下上节课的习题:根据上节课介绍的架构,实现jwt统一认证。
我们可以在基控制器的初始化函数添加这个验证逻辑,不需要验证的jwt的可以继承默认的控制器,这里给一个参考代码:
class Base extends Controller{ public function __construct(Request $request = null){ parent::__construct($request); // TODO:实现权限验证 // 从header中获取客户端传过来的jwt,假设header中的字段名称为“Authorization” $jwt = $request->header("HTTP_AUTHORIZATION"); // 解密jwt $decoded = JwtUtil::check($jwt); if (!$decoded) { die(jsonData("error","Authorization非法")); } }}
其中JwtUtil工具类的代码如下:
class JwtUtil{ public static function generateToken(){ date_default_timezone_set('PRC'); //连接本地的 Redis 服务 $redis = new \Redis(); $redis->connect('127.0.0.1', 6379); // 获取缓存中的数据 $jwt = $redis->get("jwt"); if(!$jwt){ // 缓存中的数据不存在,生成jwt $payload = array( // jwt签发者 "iss" => "http://www.aikanshe.com", // 接收jwt的一方 "aud" => "http://baidu.com", // 签发时间 "iat" => $_SERVER["REQUEST_TIME"], "sub" => "用户标志", // 过期时间 "exp" => $_SERVER["REQUEST_TIME"] + 3600 ); // 使用'HS256'算法加密载荷 $jwt = JWT::encode($payload, config("jwt_secret"),'HS256'); // 保存jwt $redis->set("jwt",$jwt); } return $jwt; } public static function check($jwt){ if (empty($jwt)) { throw new Exception("jwt为空"); } // 解密jwt $decoded = JWT::decode($jwt, config("jwt_secret"), array('HS256')); return $decoded; }}
其中config("jwt_secret")表示获取配置文件中jwt_secret值,另外Redis的操作可以使用第三方依赖:predis。本节课程就到这,下节课我们讲swoole,下节课再见。
如果您觉得文章对您有所帮助,请点“在看”以资鼓励或者分享给身边的小伙伴哈~
学习交流QQ群:904092583关注我们,学习全栈开发