CodeIgniter-Dispatcher uses CodeIgniter's _remap function to do an extra routing to a class-based controller instead of function-based.
CodeIgniter's function-based controller
<?php
class Welcome extends CI_Controller
{
public function index()
{
$this->load->view('welcome_message');
}
}
With CodeIgniter-Dispatcher's class-based controller
<?php
class Index extends \Dispatcher\DispatchableController
{
protected $views = 'welcome_message';
}
-
Download the
composer.phar
executable or use the installercurl -s http://getcomposer.org/installer | php
-
Add this to composer.json
{ "require": { "bcen/ci-dispatcher": "*" } }
-
Run composer
php composer.phar install
-
Include
autoload.php
in your project and add this toroutes.php
\Dispatcher\Common\BootstrapInstaller::run($route);
Dispatcher\BootstrapInstaller::run($route)
will create 3 files inside of CodeIgniter'sAPPPATH
, if you want to skip the file creation, addtrue
to to skip the file check.\Dispatcher\Common\BootstrapInstaller::run($route, true);
Middlewares, DispatchableController and DispatchableResource will be injected by default.
// config/dependencies.php
$config['container']['userDao'] = function($container) {
return new UserDao();
};
$config['container']['dsn'] = 'mydsn_string';
// sharedContainer will return the same instance throughout the request/response cycle
$config['sharedContainer']['pdo'] = function($container) {
return new PDO($container['dsn']);
};
// user_status.php
<?php
class User_Status extends \Dispatcher\DispatchableController
{
// CI-Dispatcher will inject $userDao from config/dependencies.php
// for you.
public function __construct($userDao)
{
$userDao->findUserById(1);
}
}
<?php
class DebugFilter
{
public function processRequest(Dispatcher\Http\HttpRequestInterface $req)
{
// do something
}
public function processResponse(Dispatcher\Http\HttpResponseInterface $res)
{
// do something
}
}
processRequest
and processResponse
are optional, middleware can implement either one or both
to alter the request/response cycle.
Any class that is created by the Dispatcher can implement CodeIgniterAware
to have CI
injection.
E.g.
<?php
// Controller
class User_Status extends \Dispatcher\DispatchableController implements \Dispatcher\Common\CodeIgniterAware
{
public function __construct($userDao)
{
$userDao->findUserById(1);
}
public function setCI($ci)
{
$this->CI = $ci;
}
}
// Middleware
class DebugFilter implements \Dispatcher\Common\CodeIgniterAware
{
public function processRequest(Dispatcher\Http\HttpRequestInterface $req)
{
$cipher = $this->CI->encrypt->encode('plaintext', 'key');
}
public function processResponse(Dispatcher\Http\HttpResponseInterface $res)
{
// do something
}
public function setCI($ci)
{
$this->CI = $ci;
}
}
There are two configuration files, config/dispatcher.php
and config/dependencies.php
.
<?php
$config['middlewares'] = array(
'MyProject\\Namespace\\Middlewares\\SomeFilter',
'debug_filter'
);
$config['debug'] = true;
debug
:
Whether to show or hide debug information.
Set true
to show exception, false
to return error 404 response when stuff gone wrong.
middlewares
:
An array of middleware class(es) to be processed before/after dispatch.
When specifying the middlewares, it can be a fully qualified class name if it is autoloaded, otherwise
the class must live under application/middlewares/
in order for CI-Dispatcher to load it (Note: naming convention applies).
This configuration file is used for DIContainer
to load dependencies and inject them
into Middlewares, DispatchableController and DispatchableResource's constructor.
Note: DIContainer
is a copy cat of Pimple
.
<?php
$config['container'] = array();
$config['sharedContainer'] = array();
$config['container']['dsnString'] = 'dsn:user@192.168.1.100';
$config['container']['userDao'] = function($c) {
return new UserDao($c['dsnString']);
};
Note:
container
can have anonymous function or simple value like string, array, etc...
sharedContainer
must contian only anonymous function.
URL mapping convention follows almost excatly like CodeIgniter's default strategy.
E.g.
http://domain.com/
maps to application/controllers/index.php
with the class name Index
http://domain.com/about_me
maps to application/controllers/about_me.php
with the class name About_Me
http://domain.com/blog
and http://domain.com/blog/ajax/fetch_all_posts
can be mapped to:
controllers
|
+-- blog
|-- index.php
+-- ajax
|
+-- fetch_all_posts.php
CI-Dispatcher will search through each URI segments for the exact file name under application/controllers
.
If it doesn't exists, it will search index.php
under that URI segments.
E.g.
http://domain.com/blog
has the URI segment: blog
.
First CI-Dispatcher will search for application/controllers/blog.php
.
If it doesn't exists, then it will try for application/controllers/blog/index.php
.
Sometime URI segments are not fixed, thus we cannot mapped to a directory or class. However, we can mapp it to the function arguments of the request handler.
E.g.
http://domain.com/blog/posts/this-is-a-crayz-blog-post-about-my-blog/
can be mapped to
application/controllers/blog/posts.php
with the follow class:
<?php
class Posts extends \Dispatcher\DispatchableController
{
protected $views = array('header', 'post_body', 'footer');
// request handler for GET
public function get($request, $slug)
{
$post = $posts->find($slug);
return $this->renderView(array('post' => $post);
}
// request handler for POST
// providing a default value means that that URI segment is optional.
// e.g. POST http://domain.com/blog/posts/some-slug
// or POST http://domain.com/blog/posts
public function post($request, $slug = null)
{
// do something and return response
}
}
Note: The request handler must accept at least one argument for the Request
object.
If middlewares are not autoloaded by class loader like composer
, they must live under
application/middlewares
.
E.g.
$config['middlewares'] => array('debug_filter', 'auth_filter');
debug_filter
will be mapped to application/middlewares/debug_filter.php
with the class name Debug_Filter
.
auth_filter
will be mapped to application/middlewares/auth_filter.php
with the class name Auth_Filter
.
Any class lives under application/controllers/
and extends Dispatcher\DispatchableController
will be created
and injected by the CI-Dispatcher
.
E.g.
Assumes we are sending a GET
request to http://domain.com/blog/posts/special-post
.
CI-Dispatcher
will map the URI toapplication/blog/posts.php
- Creates a new instance of
Posts
- Invokes the method
get
with arguments:Dispatcher\Http\HttpRequestInterface
and'special-post'
- After getting the response object from
get
, thenCI-Dispatcher
will run through all the middlewares to process the response - Finally, send it to browser by invoking
send
on theresponse
object
<?php
class Posts extends \Dispatcher\DispatchableController
{
protected $views = 'post_view';
}
By default, a GET
request handler is provided, when get
got invoked, it will load the views and data.
So when extending the DispatchableController
, you only need to provide where the view files are by
declaring $views = 'post_view'
or as an array $views = array('header', 'post_view', 'footer')
Overrides getContextData
to send data to the view layer:
<?php
class Posts extends \Dispatcher\DispatchableController
{
protected $views = 'post_view';
public function getContextData($request)
{
$posts = array();
return array('posts' => $posts);
}
}
Overrides/implements get
, post
, delete
, put
and etc to take complete
control of the request/response handling.
<?php
class Posts extends \Dispatcher\DispatchableController
{
protected $views = 'post_view';
public function get($request)
{
// returns a ViewTemplateResponse
return $this->renderView(array('post' => $posts));
}
}
$ composer.phar install --dev
$ vendor/bin/phpunit
CI-Dispatcher is released under the MIT public license.