webservco / controller
A PHP component/library. Base controllers, and the instantiator that creates the right controller for a route along with its module's dependencies.
Requires
- php: ^8.4
- psr/http-server-handler: ^1
- webservco/dependency-container: ^2
- webservco/reflection: ^2
- webservco/route: ^2
- webservco/view: ^2
Requires (Dev)
- pds/skeleton: ^1
- phan/phan: ^6
- php-parallel-lint/php-console-highlighter: ^1
- php-parallel-lint/php-parallel-lint: ^1
- phpmd/phpmd: ^3
- phpstan/phpstan: ^2
- phpstan/phpstan-deprecation-rules: ^2
- phpstan/phpstan-phpunit: ^2
- phpstan/phpstan-strict-rules: ^2
- phpunit/phpunit: ^13
- slevomat/coding-standard: ^8
- squizlabs/php_codesniffer: ^4
- vimeo/psalm: ^6
- webservco/coding-standards: ^2
- webservco/component-common: ^2
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
A PHP component/library. Please see webservco/sandbox for an example project using these types of components.
Base controllers, and the instantiator that creates the right controller for a route along with its module's dependencies.
- Related:
webservco/http-request-handler(calls the instantiator),webservco/view(views and renderers),webservco/dependency-container(containers passed to every controller),webservco/reflection(checks controller constructors)
Installation
composer require webservco/controller
Usage
A controller
Each module has a marker interface (here ExampleControllerInterface) and an abstract controller that sets the layout template. The controller builds a view and returns a response.
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; final class TestController extends AbstractExampleController implements ExampleControllerInterface { public function handle(ServerRequestInterface $request): ResponseInterface { // \WebServCo\View\Contract\ViewContainerInterface $viewContainer = $this->viewServicesContainer->getViewContainerFactory()->createViewContainerFromView( new TestView(17, 'foo'), // resources/templates/vanilla/example/test.php 'example/test', ); return $this->createResponse($request, $viewContainer); } }
The project's base controller extends AbstractDefaultController and implements createTemplateService() (where templates live). Module controllers implement createMainViewContainer() (which layout to use). See src/Project/Controller/ in the webservco/sandbox project.
The instantiator
use WebServCo\Controller\Factory\ControllerInstantiatorFactory; $controllerInstantiatorFactory = new ControllerInstantiatorFactory(); // \WebServCo\Controller\Contract\ControllerInstantiatorInterface $controllerInstantiator = $controllerInstantiatorFactory->createControllerInstantiator( $applicationDependencyContainer, // Maps module interfaces to module instantiators. new SpecificModuleControllerInstantiator(), );
Contracts
| Interface | Implementation | Purpose |
|---|---|---|
Contract\ControllerInterface |
Service\AbstractDefaultController |
A PSR-15 request handler, with createResponse() and createRedirectResponse(). |
Contract\ControllerInstantiatorInterface |
Service\ControllerInstantiator |
Checks the route's controller class and creates it. |
Contract\SpecificModuleControllerInstantiatorInterface |
Service\AbstractSpecificModuleControllerInstantiator |
You list module interface => module instantiator. |
Contract\ModuleControllerInstantiatorInterface |
Service\AbstractModuleControllerInstantiator |
You create the module's local container and the controller. |
| none | Factory\ControllerInstantiatorFactory |
Wires the instantiator with reflection and view renderer services. |
Namespaces are relative to WebServCo\Controller\.
Configuration
AbstractDefaultController puts BASE_URL into the common view that every layout receives.
BASE_URL = https://example.ddev.site/
Notes
A controller's constructor takes three arguments, in this order: the application container, the module's local container and the view services container. Each one can be typed as a more specific interface, such as your module's container interface. The instantiator uses reflection to check the types before creating the controller.
In getAvailableModuleControllerInstantiators(), the first matching interface wins. Put the more specific interfaces at the top.
createRedirectResponse() only accepts redirect status codes. The default is 303.
Development
# Start project. ddev start # Install dependencies. ddev c u # Run all validations. ddev c c # Run unit tests. ddev c test:dox