adelowo / cfar
使用 Aura.Router 的控制器
1.2
2016-08-24 11:08 UTC
Requires
- php: ~5.5|~7.0
- aura/router: ^3.0
- container-interop/container-interop: ^1.1
Requires (Dev)
- phpunit/phpunit: ~5.0
- scrutinizer/ocular: ~1.1
- squizlabs/php_codesniffer: ~2.3
Suggests
- pimple/pimple: A lightweight container that works (~3.0)
README
这个库是为了让 Aura.Router 的用户能够使用 symfony/laravel 的 "type" 控制器而编写的。
已经使用 CFAR,迁移到: 1.2
安装
建议使用最新可用的 PHP 版本,但 CFAR 应该可以在 >=5.5 上运行。
CFAR 有一个依赖项,即 Aura.Router。>=1.0 版本需要 Aura.Router 3.x,而 <=0.2.1 需要 Aura.Router 2.x。
可以通过以下方法之一安装 CFAR
- Composer :
composer require "adelowo/cfar" : "~1.0"
如果您仍然在使用 Aura.Router 2.x,请安装 0.x
composer require "adelowo/cfar" : "~0.2"
- 仓库克隆
git clone https://github.com/adelowo/cfar.git
如果没有使用 composer 或直接从仓库克隆来下载库,您将不得不自己编写一个自动加载器
用法
Cfar 不需要任何特殊的配置 - 除了指定作为您控制器的类(命名空间)和要调用的方法之外 - 您仍然可以像 Aura.Router 的(3.x)文档中指定的那样编写路由。
Aura.Router 3 是对深受喜爱的路由器的一个重大改进,它被分解为许多部分,如 Mapper、Matcher、Route(包含匹配的路由)。
Cfar 内部使用 PHP 的 Reflection Api。
默认情况下,Cfar 会搜索并调用一个名为
indexAction
的方法
以下是一个展示 Aura.Router 和 Cfar 完全集成 的小片段,包括 index.php
文件和路由的控制器的代码。
<?php //filename : index.php use Aura\Router\RouterContainer; require_once "vendor/autoload.php"; $routeContainer = new RouterContainer(); $routeMapper = $routeContainer->getMap(); $routeMapper->get('blog.read', '/blog/{ide}') ->handler('\Http\controller\BlogController@show'); $routeMapper->get(null, "/") ->handler('\Http\controller\BlogController'); $routeMapper->get('dev', '/dev'); $routeMapper->get(null,'/error') ->handler('\Http\controller\ErrorController'); //`indexAction` would be the invoked method $routeMatcher = $routeContainer->getMatcher(); $request = Zend\Diactoros\ServerRequestFactory::fromGlobals( $_SERVER, $_GET, $_POST, $_COOKIE, $_FILES ); $matched = $routeMatcher->match($request); if (!$matched) { throw new \Aura\Router\Exception("Route does not exists"); } foreach ($matched->attributes as $key => $val) { $request = $request->withAttribute($key, $val); } /** * This is totally optional. But you could use some "Control Inverting", than have `new` wrap all lines of your code *`SomeContainer` implement `Interop\Container\ContainerInterface`.; * A neat way to do this is to extend your choosen container and have the `get` method exposed by the interface retrieve the service from the container. * @see https://github.com/slimphp/slim/ */ $container = new SomeContainer(); //Add an ORM, Doctrine in this case. $container['db'] = function ($container) { $paths = array("/src/Entities"); $isDevMode = false; $dbParams = [ 'driver' => 'pdo_mysql', 'user' => 'root', 'password' => 'xx-xxx-xx-xx', 'dbname' => 'foo', ]; $config = \Doctrine\ORM\Tools\Setup::createAnnotationMetadataConfiguration($paths, $isDevMode); return \Doctrine\ORM\EntityManager::create($dbParams, $config); }; //You def' need a logger $container['logger'] = function ($container) { $logger = new \Monolog\Logger("Your App Name"); $handler = new \Monolog\Handler\SyslogHandler('Owambe'); $handler->setFormatter(new \Monolog\Formatter\LineFormatter()); $logger->pushHandler($handler); return $logger; }; //register X,Y,Z services try { $cfar = new \Adelowo\Cfar\Cfar($matched , $container); $cfar->dispatch(); } catch (\Adelowo\Cfar\CfarException $exception) { echo $exception->getMessage(); }
控制器的构造函数将始终接收一个容器。可能为 null 或有效的。由您决定。
参数将按照在路由中定义的顺序传递给调用的方法。对于
/users/{id}/{name}
的方法应该有两个参数,其中第一个参数将传递给由路由器捕获的{id}
的值,反之亦然。
<?php namespace Adelowo\Controller; class BlogController { protected $container; public function __construct(ContainerInterface $container = null) { $this->container = $container; } public function showUser($id , $param) { $db = $this->container->get('db'); $data = $db->find("User" , $id); var_dump($data); } public function showPdf($name) { echo $name; } public function indexAction($id ,$name) { echo $id. PHP_EOL; echo $name; } }
许可证
MIT