Using Middleware in CakePHP “3.next”
Middleware support will be come in CakePHP 3.3.0, but you can try it now, there is a branch for it named “3.next”! If you want to start with composer create-project, you can run with the following command:
composer create-project --prefer-dist cakephp/app <dir-target> dev-3.next
By specifying “dev-3.next” after directory target, you will pull the 3.next branch of “cakephp/app”. Once it done, you will now have an Application class inside src/ that bootstrap the application and also setup the middleware your application will use:
namespace App; class Application extends BaseApplication { public function bootstrap(){ /** **/} public function middleware($middleware) { $middleware->push(new ErrorHandlerMiddleware()); $middleware->push(new AssetMiddleware()); $middleware->push(new RoutingMiddleware()); return $middleware; } }
Now, let say you want to add your own middleware, named “Authorization” middleware, let’s create it:
namespace App\Middleware; use Cake\Network\Session; use Cake\Core\Configure; use Zend\Diactoros\Response\RedirectResponse; class Authorization { public function __invoke($request, $response, $next) { $session = Session::create(Configure::read('Session')); $checkHasUserSession = $session->check('user'); $path = $request->getUri()->getPath(); if ($path === '/admin' && ! $checkHasUserSession) { return new RedirectResponse('/auth'); } return $next($request, $response); } }
The “Authorization” middleware we just created now needs to be registered via middleware->push:
namespace App; use App\Middleware\Authorization; class Application extends BaseApplication { public function middleware($middleware) { $middleware->push(new ErrorHandlerMiddleware()); $middleware->push(new AssetMiddleware()); $middleware->push(new RoutingMiddleware()); //add the Authorization middleware $middleware->push(new Authorization()); return $middleware; } }
Done 😉
References:
1. http://www.slideshare.net/markstory/future-of-http-in-cakephp
Using ZF Component’s ConfigProvider in Expressive
If you already tried building Expressive application using modular approach with Expressive Config Manager, you can just use ZF Component’s services by consuming its config provider. If you didn’t use it, you need to first require the Expressive Config Manager in your Expressive application:
composer require mtymek/expressive-config-manager
When done, you can modify the config/config.php
like the following:
use Zend\Expressive\ConfigManager\ConfigManager; use Zend\Expressive\ConfigManager\PhpFileProvider; $configManager = new ConfigManager([ new PhpFileProvider('config/autoload/{{,*.}global,{,*.}local}.php'), ]); return new ArrayObject($configManager->getMergedConfig());
Now, for example, you want to consume Zend\Db
services, you can do:
1. Require it
composer require zendframework/zend-db
2. Register in config/config.php
use Zend\Expressive\ConfigManager\ConfigManager; use Zend\Expressive\ConfigManager\PhpFileProvider; $configManager = new ConfigManager([ new PhpFileProvider('config/autoload/{{,*.}global,{,*.}local}.php'), new Zend\Db\ConfigProvider() ]); return new ArrayObject($configManager->getMergedConfig());
By provide Zend\Db
Config Provider, you can now consume its service, let’s try define sample DB config:
// config/autoload/db.local.php return [ 'db' => [ 'username' => 'root', 'password' => '', 'driver' => 'Pdo', 'dsn' => 'mysql:dbname=test;host=localhost', 'driver_options' => [ PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\'' ], ], ];
And now, you can consume \Zend\Db\Adapter\AdapterInterface::class
as service. Check the per-component’s ConfigProvider::getDependencyConfig()
for available services if you want to use them.
Done 😉
Zend Framework 2 : Using Component as Module
If you use latest zendframework by requiring “zendframework/zendframework”: “^2.5”, You will now get various zendframework components tagged as ~2.7 or ~2.8 as per-component has own life based on each evolution. Interestingly, many components that has services, now act as module. You can check the components on zendframework blog post. In the components mentioned in the post, they will have Module
class that uses ConfigProvider
class when registering services. If you don’t get the Module class yet inside the components mentioned, you need to run:
composer update
Usage
We can consume the components as modules, for example, in config/application.config.php
, you can define:
return [ 'modules' => [ 'Application', 'Zend\Cache' ], // other configs here ];
If you check the services registered in Zend\Cache
, you will get Zend\Cache\Service\StorageCacheAbstractServiceFactory::class
that registered in abstract_factories
, that allow us to configure cache services via array with ‘caches’ config as limbo when no services that has name inside the ‘caches’ array registered yet. So, for example, we have configured ‘caches’ config:
// config/autoload/global.php return [ // ... 'caches' => [ 'cache_file' => [ 'adapter' => 'filesystem', 'options' => [ 'ttl' => 7200, 'cache_dir' => './data/cache', ], ], ], ];
We have cache_file
as service name that utilize filesystem cache adapter as config above. We then can just consume the cache_file
via service manager:
// assumption: $services is a Zend\ServiceManager\ServiceManager // that pulled during Mvc workflow $services->get('cache_file')->setItem('foo', 'fooValue'); echo $services->get('cache_file')->getItem('foo');
Done 😉
6 comments