本文将介绍Lumen的使用和遇到的问题,重点是官方文档中没太详细介绍的内容,不定期更新。
Lumen框架使用Laravel模块构建而成。
与Laravel臃肿不同,Lumen是微框架,去繁就简,专注于构建无状态API。
在使用中依然能感受到Laravel一样的艺术感,
Lumen的性能表现也值得称赞。
如果你在构建API应用,请关注Lumen。
安装Lumen框架
- 全局安装Composer
curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer
- 配置Composer中国镜像,国内用户都懂得。
composer config -g repo.packagist composer https://packagist.phpcomposer.com
- 建立一个目录为lumen的项目
composer create-project --prefer-dist laravel/lumen lumen
一些简单的配置
配置web服务器,支持单入口(优雅链接)
Apache配置:
- 打开mod_rewrite模块
- 配置public/.htaccess
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
Nginx:
nginx.conf
location / {
try_files $uri $uri/ /index.php?$query_string;
}
配置开发环境
Lumen把配置放到.env
文件中. 根目录下包含一个.env.example
文件
cp .env.example .env
.env 示例
APP_ENV=local
APP_DEBUG=false
APP_KEY=
如何判断当前程序运行环境?
$environment = app()->environment();
if (app()->environment('local')) {
// 环境是 local
// 加载 local 配置
}
if (app()->environment('local', 'staging')) {
// 环境是 local 或 staging...
}
- 第一个页面 hello world
在routes中添加路由规则 /app/Http/routes.php
方法1:接收闭包函数
$app->get('/hello', function() use ($app) {
return 'Hello World!';
});
方法2:指定路由到控制器方法处理
$app->get('/hello', 'HelloController@index');
一个简单的控制器动作
/app/Http/Controllers/HelloController.php
<?php
namespace App\Http\Controllers;
class HelloController extends Controller
{
public function index()
{
return 'Hello World!';
}
}
Lumen异常处理 修改异常报告
为什么引入这个问题呢?我们一般用Lumen写API接口,返回格式为JSON或XML。
Lumen默认报错是这个样子的, 不满足我们的要求了,我们想实现浏览器呈现的错误信息为JSON
格式怎么办呢?
首先Lumen输出JSON 响应很简单。
return response()->json(['name' => 'Abigail', 'state' => 'CA']);
再来看异常处理如何修改。
Lumen中的异常都交给App\Exceptions\Handler
这个类处理
render
方法负责将指定的异常转换成HTTP响应再发送到浏览器。
我们把报错的行号,文件和错误消息都通过JSON返回:
<?php
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception $e
* @return \Illuminate\Http\Response
*/
public function render($request, Exception $e)
{
$code = $e->getCode() == 0 ? 500 : $e->getCode();
$msg = sprintf("%s:%s:%s", $e->getFile(), $e->getLine(), $e->getMessage());
return response()->json(array('errorNo' => $code, 'errorMsg' => $msg));
}
刚才的错误消息变成了这样
{"errorNo":500,"errorMsg":"\/home\/vagrant\/Code\/www_data\/lumen\/app\/Http\/routes.php:18:Parse error: syntax error, unexpected '$app' (T_VARIABLE)"}
Lumen操作phpredis?
phpredis
是PHP的Redis扩展。
predis
是PHP实现的Redis操作库,
由于phpredis的性能更好,所以我们有必要折腾一下。
在/bootstrap/app.php
中,把phpredis注入到Lumen容器中
//Lumen中使用PhpRedis
$app->singleton('redis', function() {
try {
$redis = new \Redis();
$redis->connect('127.0.0.1', 6379);
return $redis;
} catch (Exception $e) {
echo $e->getMessage();
}
});
unset($app->availableBindings['redis']);
绑定后即可通过 app('redis') 操作Redis了。
Lumen怎么添加自定义配置?
我们看到上面的代码 $redis->connect('127.0.0.1', 6379);
像这种代码把配置信息硬编码到代码中,以后维护起来不是很好的。
我们把Redis连接修改为配置文件怎么办?
方法1:.env
$redis->connect(env('REDIS_HOST', env('REDIS_PORT')));
方法2:Laravel风格的config文件
- 添加文件
/config/redis.php
<?php
return [
'REDIS_HOST' => '127.0.0.1',
'REDIS_PORT' => 6379,
];
- 修改
bootstrap/app.php
, 让配置文件生效
// ...
$app->configure('redis');
return $app;
- 使用
config()
函数来获取配置值
$redis->connect(config('redis.REDIS_HOST'), config('redis.REDIS_PORT'));
Lumen请求相关方法
Lumen Request类由Illuminate\Http\Request实现
// 所有的路由规则
app()->getRoutes();
// 当前REQUEST_URI
// app('request') 是 Illuminate\Http\Request类的实例
app('request')->getRequestUri();
// 当前route
app('request')->route();
怎么得到当前Uri的控制器、Action、路由规则
<?php
namespace App\Http\Controllers;
class HelloController extends Controller
{
public function index()
{
// 当前path
$router = explode("?", $request->getRequestUri())[0];
// 所有的router
$rts = app()->getRoutes();
// 当前route
$routeInfo = app('request')->route();
$rows = [];
foreach ($rts as $rt => $route ) {
$rows[$route['uri']] = [
'verb' => $route['method'],
'uri' => $route['uri'],
'uses' => isset($route['action']['uses']) ? $route['action']['uses'] : 'Closure',
'controller' => $this->getController($route['action']),
'action' => $thiw->getAction($route['action']),
];
}
print_r($rows);
return;
}
/**
* @param array $action
* @return mixed|string
*/
protected function getAction(array $action)
{
if (!empty($action['uses'])) {
$data = $action['uses'];
if (($pos = strpos($data, "@")) !== false) {
return substr($data, $pos + 1);
} else {
return "METHOD NOT FOUND";
}
} else {
return 'Closure';
}
}
/**
* @param array $action
* @return mixed|string
*/
protected function getController(array $action)
{
if (empty($action['uses'])) {
return 'Closure';
}
return current(explode("@", $action['uses']));
}
}
得到的所有路由规则数组
Array
(
[/] => Array
(
[verb] => GET
[uri] => /
[uses] => Closure
[controller] => Closure
[action] => Closure
)
[/hello] => Array
(
[verb] => GET
[uri] => /hello
[uses] => App\Http\Controllers\HelloController@index
[controller] => App\Http\Controllers\HelloController
[action] => index
)
)
Lumen 实现自定义LOG目录
由于篇幅较长,单独成一篇文章 Lumen 实现自定义LOG目录
今天先写到这里,由于本人水平有限,如果文章中有错误,还请大神指点。
大家遇到Lumen使用问题欢迎和我交流,有问题可以在评论区留言。
本文会持续更新。大家可以把这篇文章添加到收藏。