asgrim / mini-mezzio
Minimal Application Factory for Mezzio
Requires
- php: 8.1.*|8.2.*|8.3.*
- laminas/laminas-diactoros: ^3.1
- laminas/laminas-httphandlerrunner: ^2.7
- laminas/laminas-stratigility: ^3.10
- mezzio/mezzio: ^3.17
- mezzio/mezzio-router: ^3.16
- psr/container: ^2.0
Requires (Dev)
- doctrine/coding-standard: ^12.0
- laminas/laminas-servicemanager: ^4.0@dev
- mezzio/mezzio-fastroute: ^3.11
- phpunit/phpunit: ^10.5
- psalm/plugin-phpunit: ^0.18.4
- vimeo/psalm: ^5.17
README
Make setting up a Mezzio application even quicker by using this package. This makes an assumption that you are happy to use:
laminas/diactoros
for the application's PSR-7 server request implementation- You do not need to use the
SapiStreamEmitter
- Your
ServerRequest
comes from$_SERVER
All you need to provide is:
- A container instance implementing
ContainerInterface
, for example laminas-servicemanager - A router instance implementing
RouterInterface
, for example FastRoute
You would then pipe the RouteMiddleware
, DispatchMiddleware
, and any other
middleware or request handlers that your application needs.
Basic Usage: Example Application using Mini Mezzio
First you must require Mini Mezzio, a container, and a router with Composer. In this example, we'll use Laminas ServiceManager and FastRoute.
$ composer require asgrim/mini-mezzio laminas/laminas-servicemanager mezzio/mezzio-fastroute
Then in public/index.php
we can create our application:
<?php declare(strict_types=1); use Laminas\Diactoros\Response\TextResponse; use Laminas\ServiceManager\ServiceManager; use Asgrim\MiniMezzio\AppFactory; use Mezzio\Router\FastRouteRouter; use Mezzio\Router\Middleware\DispatchMiddleware; use Mezzio\Router\Middleware\RouteMiddleware; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\RequestHandlerInterface; require __DIR__ . '/../vendor/autoload.php'; $container = new ServiceManager(); $router = new FastRouteRouter(); $app = AppFactory::create($container, $router); $app->pipe(new RouteMiddleware($router)); $app->pipe(new DispatchMiddleware()); $app->get('/hello-world', new class implements RequestHandlerInterface { public function handle(ServerRequestInterface $request): ResponseInterface { return new TextResponse('Hello world!'); } }); $app->run();
You can use the PHP built-in web server to check this works. Spin this up with:
$ php -S 0.0.0.0:8080 -t public public/index.php
Now if you visit http://localhost:8080/hello-world in your browser, you should see the text
Hello world!
displayed. Now you're ready to make middleware in minutes!
Use the container for pipeline and endpoints
It probably won't be long before you'll want to leverage the container to use
dependency injection for your middleware handlers instead of putting them all
in the public/index.php
. Since Mezzio already can pull middleware from the
container it is given, you can put your handler in a proper class:
<?php declare(strict_types=1); namespace MyApp\Handler; use Laminas\Diactoros\Response\JsonResponse; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\RequestHandlerInterface; final class HelloWorldHandler implements RequestHandlerInterface { public function handle(ServerRequestInterface $request): ResponseInterface { return new JsonResponse(['message' => 'Hello world!'], 200); } }
You can update your public/index.php
to pull things from the container:
<?php declare(strict_types=1); use Laminas\ServiceManager\AbstractFactory\ReflectionBasedAbstractFactory; use Laminas\ServiceManager\ServiceManager; use Asgrim\MiniMezzio\AppFactory; use Mezzio\Router\FastRouteRouter; use Mezzio\Router\Middleware\DispatchMiddleware; use Mezzio\Router\Middleware\RouteMiddleware; use Mezzio\Router\RouterInterface; require __DIR__ . '/../vendor/autoload.php'; $container = new ServiceManager(); $container->addAbstractFactory(ReflectionBasedAbstractFactory::class); $container->setFactory(RouterInterface::class, static function () { return new FastRouteRouter(); }); $app = AppFactory::create($container, $container->get(RouterInterface::class)); $app->pipe(RouteMiddleware::class); $app->pipe(DispatchMiddleware::class); $app->get('/hello-world', \MyApp\Handler\HelloWorldHandler::class); $app->run();
We've updated several things here, using the power of Laminas Service Manager:
- Added the
ReflectionBasedAbstractFactory
- this allows DI autowiring based on reflection. This can autowire most things - Added a factory for
\Mezzio\Router\RouterInterface
which returns the instance ofMezzio\Router\FastRouteRouter
. TheRouteMiddleware
can then be autowired using theReflectionBasedAbstractFactory
RouteMiddleware
andDispatchMiddleware
are now referred to with just::class
rather than creating instances; since they're just strings, they are looked up in the container.- The route
GET /hello-world
is mapped to\MyApp\Handler\HelloWorldHandler
that we created above; again, since this is a string, the instance is fetched from the container.