内容简介:写这个框架的起因,是因为公司项目中用到的 Yaf 框架不能很好的满足需求。在前不久写单元测试时,发现由于 Yaf 对命名空间支持的不足导致没办法写出期望的单元测试代码,除非大量修改业务代码才能绕过去,得不偿失。具体可参考我给 Yaf 提的 issue
关于
写这个框架的起因,是因为公司项目中用到的 Yaf 框架不能很好的满足需求。
在前不久写单元测试时,发现由于 Yaf 对命名空间支持的不足导致没办法写出期望的单元测试代码,除非大量修改业务代码才能绕过去,得不偿失。
具体可参考我给 Yaf 提的 issue https://github.com/laruence/yaf/issues/417
于是,开始考虑是否替换掉 Yaf 框架。
Yaf 框架我个人很喜欢,简单灵活高效不废话,且作为 PHP 扩展运行能几乎忽略框架本身的开销。 市面上也有其它非常优秀的框架,但各自侧重点不一样,很难选出一个像 Yaf 这样精简高效的框架。
所以便有了 Zim 框架,基于 Zephir 开发编译为 PHP 扩展,尽量避免框架本身开销,性能比 Yaf 要差一点,不过可接受。 同时足够简单,仅提供基础特性:命名空间、路由分发、配置、事件、依赖注入等。
代码大部分来自 Laravel 和 Symfony 组件,然后翻译成 zephir 代码并编译为 PHP 扩展。
于是,同时提供了 zim-php
和 zim-ext
两个项目,功能相同,只是前者为 php 实现,后者为扩展。
特性
命名空间
完整的命名空间支持,遵循 PSR-4 规范
路由
默认路由
无需配置路由规则,默认根据 uri 分发到对应的 controller 和 action (类似 Yaf)。
如:
uri | controller | action | 备注 |
---|---|---|---|
/ | IndexController | indexAction | |
/foo | FooController | indexAction | |
/foo/bar | FooController | barAction | |
/xx | IndexController | xxAction | 如果 XxController 不存在 |
另外,controller 文件内可以通过 $actions
来指定 action 文件,类似 Yaf
如下, /page
会分发到 PageAction
的 execute
方法
use App\Action\Index\PageAction; class IndexController extends Controller { protected $actions = [ 'page' => PageAction::class, ]; }
配置路由
基于 Symfony/Routing 组件,去掉了 host, schema 等匹配支持。
配置文件 config/routes.php
,
可以通过 Route::get
Route::post
等快捷方式定义路由,如下:
use \Zim\Routing\Route; // 分发至 FooController barAction Route::get('/foo/bar', 'Foo@bar'); // 参数 id 为数字,且默认为 1 Route::get('/user/{id<\d+>?1}', 'User@show'); // page 参数为数字且默认值 123,对应到闭包的第一个参数 Route::post('/page/{page<\d+>?123}', function($page) { return 'page '.$page; }); // 同时匹配多个 method Route::match(['POST', 'PUT', 'GET'], '/put', function() { return 'test match'; }); // 除通过 Route 快捷方法外,也可直接 return 路由定义规则 return [ '/' => 'Index@index', '/closure' => function() { return 'closure ok'; }, '/post/{page<\d+>?1}' => 'Index@post', '/demo' => 'Demo/Index@test', '/hello/{world}' => [ 'to' => 'Index@hello', 'methods' => ['GET', 'POST'], 'requirements' => [ 'world' => '\d+', ], 'defaults' => ['world' => 2] ], ];
注:
默认路由、 Route
快捷方法 以及配置的路由规则,三者同时生效。
优先级:快捷方法 > 路由规则 > 默认路由
Action
Action 是处理 Http 请求的单元,有以下几种方式:
- 路由定义的闭包
- controller 文件内的某个 xxAction 方法
- controller actions 配置的某个 Action 文件内的 execute 方法
响应数据,正常应为 Zim\Http\Response
对象,同时,可 return 标量来由框架自行判断:
Route::get('/page', function() { return 'page test'; }); //数组会自动响应为 json Route::get('/json', function() { return ['k' => 'v']; });
配置
默认配置文件 config/app.php
,获取配置可通过 Zim::config('app.name')
如果新增配置文件 config/xx.php
,可通过 Zim::config('xx.key')
获取
类似 Laravel
容器、依赖
Zim
基于 Laravel
的 Container
,精简到仅保留核心注册、绑定、扩展三个功能。
同时,简化了对象初始化自动注入机制,应用于对象管理、路由、事件、Controller Action等各方面。
示例,action 内注入 Config
:
public function pageAction($page = 2, Config $config) { return [ 'page' => $page, 'config' => $config->all(), ]; }
具体可参考 Zim\Container\MagicInjection
Service
参考 Laravel service provider
自定义 Service 类继承 Zim\Service
,且加入到配置 app.services
内
Service 提供两个方法
register
方法,初始化时调用,仅用于容器注册、绑定等,不建议用于业务处理(因为业务用到的容器对象可能还未初始化)
boot
方法,用于业务逻辑,在路由分发前调用。
事件
事件系统同时参考了 Laravel 和 Symfony 的处理方式。
发出事件
Event::fire(new MyEvent());
监听事件
Event::listen($events, function($event, $payload) {});
Http 完整生命周期内均提供了系统事件可订阅或修改 Request
Response
等数据
系统事件如下:
Zim\Event\RequestEvent Zim\Event\DispatchEvent Zim\Event\ResponseEvent Zim\Event\ExceptionEvent
示例,监听系统响应事件并修改响应数据:
class AppService extends Service { public function boot() { Event::listen(ResponseEvent::class, function($event, $resp) { $resp->setResponse(new Response('test response event')); }); }
其它
TODO
以上所述就是小编给大家介绍的《终于受不了 Yaf,写了个精简框架 Zim,可作为 PHP 扩展运行》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Pro Django
Marty Alchin / Apress / 2008-11-24 / USD 49.99
Django is the leading Python web application development framework. Learn how to leverage the Django web framework to its full potential in this advanced tutorial and reference. Endorsed by Django, Pr......一起来看看 《Pro Django》 这本书的介绍吧!