Ref: https://docs.zendframework.com/zend-expressive/
https://docs.zendframework.com/zend-expressive/v3/getting-started/quick-start/
Create Login functionality in Expressive 3
Install via composer:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
teddy@teddy:~/Documents/works$ composer create-project zendframework/zend-expressive-skeleton Installing zendframework/zend-expressive-skeleton (3.2.3) - Installing zendframework/zend-expressive-skeleton (3.2.3): Downloading (connDownloading (100%) Created project in /home/teddy/Documents/works/zend-expressive/zend-expressive-skeleton > ExpressiveInstaller\OptionalPackages::install Setting up optional packages Setup data and cache dir Removing installer development dependencies What type of installation would you like? [1] Minimal (no default middleware, templates, or assets; configuration only) [2] Flat (flat source code structure; default selection) [3] Modular (modular source code structure; recommended) Make your selection (2): - Copying src/App/ConfigProvider.php Which container do you want to use for dependency injection? [1] Aura.Di [2] Pimple [3] zend-servicemanager [4] Auryn [5] Symfony DI Container [6] PHP-DI Make your selection or type a composer package name and version (zend-servicemanager): - Adding package zendframework/zend-servicemanager (^3.3) - Copying config/container.php Which router do you want to use? [1] Aura.Router [2] FastRoute [3] zend-router Make your selection or type a composer package name and version (FastRoute): - Adding package zendframework/zend-expressive-fastroute (^3.0) - Whitelist package zendframework/zend-expressive-fastroute - Copying config/routes.php Which template engine do you want to use? [1] Plates [2] Twig [3] zend-view installs zend-servicemanager [n] None of the above Make your selection or type a composer package name and version (n): 1 - Adding package zendframework/zend-expressive-platesrenderer (^2.0) - Whitelist package zendframework/zend-expressive-platesrenderer - Copying templates/error/404.phtml - Copying templates/error/error.phtml - Copying templates/layout/default.phtml - Copying templates/app/home-page.phtml Which error handler do you want to use during development? [1] Whoops [n] None of the above Make your selection or type a composer package name and version (Whoops): - Adding package filp/whoops (^2.1.12) - Copying config/autoload/development.local.php.dist Remove installer Removing composer.lock from .gitignore Removing Expressive installer classes, configuration, tests and docs Loading composer repositories with package information Updating dependencies (including require-dev) Package operations: 64 installs, 0 updates, 0 removals - Installing zendframework/zend-component-installer (2.1.1): Downloading (connDownloading (100%) - Installing ocramius/package-versions (1.4.0): Downloading (100%) - Installing zendframework/zend-escaper (2.6.0): Loading from cache - Installing zendframework/zend-expressive-template (2.0.0): Downloading (connDownloading (100%) - Installing psr/http-message (1.0.1): Loading from cache - Installing psr/http-server-handler (1.0.1): Downloading (100%) - Installing psr/http-server-middleware (1.0.1): Downloading (100%) - Installing psr/container (1.0.0): Loading from cache - Installing fig/http-message-util (1.1.3): Downloading (100%) - Installing zendframework/zend-expressive-router (3.1.0): Downloading (connecDownloading (100%) - Installing zendframework/zend-expressive-helpers (5.1.3): Downloading (conneDownloading (100%) - Installing league/plates (3.3.0): Downloading (100%) - Installing zendframework/zend-expressive-platesrenderer (2.0.0): DownloadingDownloading (100%) Installing Zend\Expressive\Plates\ConfigProvider from package zendframework/zend-expressive-platesrenderer - Installing roave/security-advisories (dev-master 4e04718) - Installing zendframework/zend-stdlib (3.2.1): Downloading (100%) - Installing zendframework/zend-config-aggregator (1.1.1): Downloading (connecDownloading (100%) - Installing psr/http-factory (1.0.0): Downloading (100%) - Installing container-interop/container-interop (1.2.0): Loading from cache - Installing zendframework/zend-servicemanager (3.4.0): Downloading (connectinDownloading (100%) - Installing nikic/fast-route (v1.3.0): Loading from cache - Installing zendframework/zend-expressive-fastroute (3.0.2): Downloading (conDownloading (100%) Installing Zend\Expressive\Router\FastRouteRouter\ConfigProvider from package zendframework/zend-expressive-fastroute - Installing sebastian/version (2.0.1): Loading from cache - Installing sebastian/resource-operations (2.0.1): Loading from cache - Installing sebastian/recursion-context (3.0.0): Loading from cache - Installing sebastian/object-reflector (1.1.1): Loading from cache - Installing sebastian/object-enumerator (3.0.3): Loading from cache - Installing sebastian/global-state (2.0.0): Loading from cache - Installing sebastian/exporter (3.1.0): Loading from cache - Installing sebastian/environment (4.1.0): Loading from cache - Installing sebastian/diff (3.0.2): Loading from cache - Installing sebastian/comparator (3.0.2): Loading from cache - Installing phpunit/php-timer (2.1.1): Loading from cache - Installing phpunit/php-text-template (1.2.1): Loading from cache - Installing phpunit/php-file-iterator (2.0.2): Loading from cache - Installing theseer/tokenizer (1.1.0): Loading from cache - Installing sebastian/code-unit-reverse-lookup (1.0.1): Loading from cache - Installing phpunit/php-token-stream (3.0.1): Loading from cache - Installing phpunit/php-code-coverage (6.1.4): Loading from cache - Installing doctrine/instantiator (1.1.0): Loading from cache - Installing symfony/polyfill-ctype (v1.10.0): Loading from cache - Installing webmozart/assert (1.4.0): Loading from cache - Installing phpdocumentor/reflection-common (1.0.1): Loading from cache - Installing phpdocumentor/type-resolver (0.4.0): Loading from cache - Installing phpdocumentor/reflection-docblock (4.3.0): Loading from cache - Installing phpspec/prophecy (1.8.0): Loading from cache - Installing phar-io/version (2.0.1): Loading from cache - Installing phar-io/manifest (1.0.3): Loading from cache - Installing myclabs/deep-copy (1.8.1): Loading from cache - Installing phpunit/phpunit (7.5.6): Loading from cache - Installing squizlabs/php_codesniffer (2.9.2): Downloading (100%) - Installing zfcampus/zf-composer-autoloading (2.1.0): Downloading (connectingDownloading (100%) - Installing zendframework/zend-stratigility (3.1.0): Downloading (connecting.Downloading (100%) - Installing zendframework/zend-diactoros (2.1.1):Downloading (100%) ) - Installing zendframework/zend-httphandlerrunner (1.1.0): Downloading (connecDownloading (100%) Installing Zend\HttpHandlerRunner\ConfigProvider from package zendframework/zend-httphandlerrunner - Installing zendframework/zend-expressive (3.2.1): Downloading (connecting...Downloading (100%) - Installing zendframework/zend-eventmanager (3.2.1): Downloading (connecting.Downloading (100%) - Installing zendframework/zend-code (3.3.1): Loading from cache - Installing symfony/polyfill-mbstring (v1.10.0): Loading from cache - Installing symfony/contracts (v1.0.2): Loading from cache - Installing symfony/console (v4.2.4): Downloading (100%) - Installing psr/log (1.1.0): Loading from cache - Installing zendframework/zend-expressive-tooling (1.2.0): Downloading (conneDownloading (100%) - Installing zfcampus/zf-development-mode (3.2.0):Downloading (100%) ) - Installing filp/whoops (2.3.1): Downloading (100%) zendframework/zend-expressive-template suggests installing zendframework/zend-expressive-twigrenderer (^2.0 to use the Twig template renderer) zendframework/zend-expressive-template suggests installing zendframework/zend-expressive-zendviewrenderer (^2.0 to use the zend-view PhpRenderer template renderer) zendframework/zend-expressive-router suggests installing zendframework/zend-expressive-aurarouter (^3.0 to use the Aura.Router routing adapter) zendframework/zend-expressive-router suggests installing zendframework/zend-expressive-zendrouter (^3.0 to use the zend-router routing adapter) zendframework/zend-config-aggregator suggests installing zendframework/zend-config (Allows loading configuration from XML, INI, YAML, and JSON files) zendframework/zend-config-aggregator suggests installing zendframework/zend-config-aggregator-modulemanager (Allows loading configuration from zend-mvc Module classes) zendframework/zend-config-aggregator suggests installing zendframework/zend-config-aggregator-parameters (Allows usage of templated parameters within your configuration) zendframework/zend-servicemanager suggests installing ocramius/proxy-manager (ProxyManager 1.* to handle lazy initialization of services) sebastian/global-state suggests installing ext-uopz (*) phpunit/phpunit suggests installing phpunit/php-invoker (^2.0) zendframework/zend-expressive suggests installing zendframework/zend-auradi-config (^1.0 to use Aura.Di dependency injection container) zendframework/zend-expressive suggests installing zendframework/zend-pimple-config (^1.0 to use Pimple for dependency injection container) zendframework/zend-code suggests installing doctrine/annotations (Doctrine\Common\Annotations >=1.0 for annotation features) symfony/contracts suggests installing psr/cache (When using the Cache contracts) symfony/contracts suggests installing symfony/cache-contracts-implementation symfony/contracts suggests installing symfony/service-contracts-implementation symfony/contracts suggests installing symfony/translation-contracts-implementation symfony/console suggests installing symfony/event-dispatcher symfony/console suggests installing symfony/lock symfony/console suggests installing symfony/process filp/whoops suggests installing symfony/var-dumper (Pretty print complex values better with var-dumper available) filp/whoops suggests installing whoops/soap (Formats errors as SOAP responses) Writing lock file Generating autoload files ocramius/package-versions: Generating version class... ocramius/package-versions: ...done generating version class > zf-development-mode enable You are now in development mode. |
Then go to the project root directory:
|
1 |
teddy@teddy:~/Documents/works$ cd zend-expressive-skeleton/ |
Run the project
|
1 |
teddy@teddy:~/Documents/works/zend-expressive-skeleton$ composer run --timeout=0 serve |
Then open it on your browser: http://localhost:8080/
NOTE: Make sure no other service running port 8080. If it exist, please stop it. In my composer nginx running port 8080. So I need to stop nginx (sudo service nginx stop).
Create Login
I need to install a few components:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
teddy@teddy:~/Documents/works/zend-expressive-skeleton$ composer require \ > zendframework/zend-form:^2.11 \ > zendframework/zend-i18n:^2.7 \ > zendframework/zend-expressive-authentication:^1.0 \ > zendframework/zend-expressive-authentication-session:^1.0 \ > zendframework/zend-expressive-session:^1.0 \ > zendframework/zend-expressive-session-ext:^1.0 ./composer.json has been updated Loading composer repositories with package information Updating dependencies (including require-dev) Package operations: 11 installs, 0 updates, 0 removals - Installing zendframework/zend-expressive-session (1.2.1): Downloading (conneDownloading (100%) Please select which config file you wish to inject 'Zend\Expressive\Session\ConfigProvider' into: [0] Do not inject [1] config/config.php Make your selection (default is 1): Remember this option for other packages of the same type? (Y/n)Y Installing Zend\Expressive\Session\ConfigProvider from package zendframework/zend-expressive-session - Installing zendframework/zend-expressive-authentication (1.1.0): DownloadingDownloading (100%) Installing Zend\Expressive\Authentication\ConfigProvider from package zendframework/zend-expressive-authentication - Installing zendframework/zend-expressive-authentication-session (1.0.0): DowDownloading (100%) Installing Zend\Expressive\Authentication\Session\ConfigProvider from package zendframework/zend-expressive-authentication-session - Installing dflydev/fig-cookies (v2.0.0): Downloading (100%) - Installing zendframework/zend-expressive-session-ext (1.6.0): Downloading (cDownloading (100%) Installing Zend\Expressive\Session\Ext\ConfigProvider from package zendframework/zend-expressive-session-ext - Installing zendframework/zend-hydrator (3.0.1): Downloading (100%) Installing Zend\Hydrator\ConfigProvider from package zendframework/zend-hydrator - Installing zendframework/zend-validator (2.12.0): Downloading (connecting...Downloading (100%) Installing Zend\Validator\ConfigProvider from package zendframework/zend-validator - Installing zendframework/zend-filter (2.9.1): Loading from cache Installing Zend\Filter\ConfigProvider from package zendframework/zend-filter - Installing zendframework/zend-inputfilter (2.10.0): Loading from cache Installing Zend\InputFilter\ConfigProvider from package zendframework/zend-inputfilter - Installing zendframework/zend-form (2.14.1): Downloading (100%) Installing Zend\Form\ConfigProvider from package zendframework/zend-form - Installing zendframework/zend-i18n (2.9.0): Loading from cache Installing Zend\I18n\ConfigProvider from package zendframework/zend-i18n zendframework/zend-expressive-session suggests installing zendframework/zend-expressive-csrf (^1.0 || ^1.0-dev for CSRF protection capabilities) zendframework/zend-expressive-session suggests installing zendframework/zend-expressive-flash (^1.0 || ^1.0-dev for flash message capabilities) zendframework/zend-expressive-authentication suggests installing zendframework/zend-expressive-authentication-basic (Provides an HTTP Basic Authentication AuthenticationInterface implementation) zendframework/zend-expressive-authentication suggests installing zendframework/zend-expressive-authentication-zendauthentication (Provides a zend-authentication AuthenticationInterface implementation) zendframework/zend-hydrator suggests installing zendframework/zend-serializer (^2.9, to use the SerializableStrategy) zendframework/zend-validator suggests installing zendframework/zend-db (Zend\Db component, required by the (No)RecordExists validator) zendframework/zend-validator suggests installing zendframework/zend-math (Zend\Math component, required by the Csrf validator) zendframework/zend-validator suggests installing zendframework/zend-i18n-resources (Translations of validator messages) zendframework/zend-validator suggests installing zendframework/zend-session (Zend\Session component, ^2.8; required by the Csrf validator) zendframework/zend-validator suggests installing zendframework/zend-uri (Zend\Uri component, required by the Uri and Sitemap\Loc validators) zendframework/zend-filter suggests installing zendframework/zend-crypt (Zend\Crypt component, for encryption filters) zendframework/zend-filter suggests installing zendframework/zend-uri (Zend\Uri component, for the UriNormalize filter) zendframework/zend-form suggests installing zendframework/zend-captcha (^2.7.1, required for using CAPTCHA form elements) zendframework/zend-form suggests installing zendframework/zend-view (^2.6.2, required for using the zend-form view helpers) zendframework/zend-form suggests installing zendframework/zendservice-recaptcha (in order to use the ReCaptcha form element) zendframework/zend-i18n suggests installing zendframework/zend-cache (Zend\Cache component) zendframework/zend-i18n suggests installing zendframework/zend-config (Zend\Config component) zendframework/zend-i18n suggests installing zendframework/zend-i18n-resources (Translation resources) zendframework/zend-i18n suggests installing zendframework/zend-view (You should install this package to use the provided view helpers) Writing lock file Generating autoload files ocramius/package-versions: Generating version class... ocramius/package-versions: ...done generating version class |
Ok. I want to put the authentication if any visitor want to visit the homepage so he/she need to login first. I need to create a route for this. so modify config/routes.php file like this:
|
1 2 3 4 5 6 7 8 9 |
... return function (Application $app, MiddlewareFactory $factory, ContainerInterface $container) : void { //$app->get('/', App\Handler\HomePageHandler::class, 'home'); $app->route('/', [ \Zend\Expressive\Authentication\AuthenticationMiddleware::class, App\Handler\HomePageHandler::class, ], ['GET'], 'home'); ... }; |
comment the default home route then add a new route like above. If we refresh our browser for the homepage, it’d show this error:
|
1 |
Service with name "Zend\Expressive\Authentication\AuthenticationMiddleware" could not be created. Reason: AuthenticationInterface service is missing |
we need to register ‘Zend\Expressive\Authentication\AuthenticationInterface’ under ‘factories’ config in config/autoload/dependencies.global.php.:
|
1 2 3 4 5 6 7 8 9 10 11 |
return [ .. 'dependencies' => [ ... // Use 'factories' for services provided by callbacks/factory classes. 'factories' => [ // Fully\Qualified\ClassName::class => Fully\Qualified\FactoryName::class, Zend\Expressive\Authentication\AuthenticationInterface::class => Zend\Expressive\Authentication\Session\PhpSessionFactory::class ], ], ]; |
If we refresh our browser again, it’d show another error:
|
1 |
Service with name "Zend\Expressive\Authentication\AuthenticationInterface" could not be created. Reason: UserRepositoryInterface service is missing for authentication |
So I modify again config/autoload/dependencies.global.php to add ‘Zend\Expressive\Authentication\UserRepositoryInterface’ class in ‘aliases’ config:
|
1 2 3 4 5 6 7 8 9 10 11 |
return [ ... 'dependencies' => [ ... 'aliases' => [ // Fully\Qualified\ClassOrInterfaceName::class => Fully\Qualified\ClassName::class, Zend\Expressive\Authentication\UserRepositoryInterface::class => Zend\Expressive\Authentication\UserRepository\PdoDatabase::class ], ... ], ]; |
When I refresh the browser again. This error would be appear:
|
1 |
Service with name "Zend\Expressive\Authentication\AuthenticationInterface" could not be created. Reason: The redirect configuration is missing for authentication |
So I need to put my database credentials to connect zend expressive to mysql database in config/autoload/local.php file (if this file not exist, please create one):
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
return [ 'authentication' => [ 'pdo' => [ 'dsn' => 'mysql:host=localhost;dbname=expressive', 'username' => 'your-mysql-username', 'password' => ''your-mysql-password', 'table' => 'users', 'field' => [ 'identity' => 'username', 'password' => 'password', ], ], 'redirect' => '/login', ], ]; |
Please create a new database ‘expressive’ and a new table ‘users’ first. The users table consist of only two fields now. There are username (varchar 100) and password (varchar 100). I put ‘redirect’ value to ‘/login’ so it’d redirect the homepage to login page. Make sure the credentials is correct. If not you’d get an error like this:
|
1 |
Service with name "Zend\Expressive\Authentication\UserRepository\PdoDatabase" could not be created. Reason: SQLSTATE[HY000] [1045] Access denied for user ''@'localhost' (using password: NO) |
Then I refresh my browser again. Another error is coming up:
|
1 |
Request is missing the attribute Zend\Expressive\Session\SessionMiddleware::SESSION_ATTRIBUTE ("session"); perhaps you forgot to inject the Zend\Expressive\Session\SessionMiddleware prior to the Zend\Expressive\Authentication\AuthenticationMiddleware? |
Here we need ‘Zend\Expressive\Session\SessionMiddleware’ class before routing middleware. So add it in config/pipeline.php:
|
1 2 3 4 5 6 7 8 9 10 11 |
return function (Application $app, MiddlewareFactory $factory, ContainerInterface $container) : void { ... $app->pipe(\Zend\Expressive\Session\SessionMiddleware::class); // Register the routing middleware in the middleware pipeline. // This middleware registers the Zend\Expressive\Router\RouteResult request attribute. $app->pipe(RouteMiddleware::class); ... }; |
We fixed those errors until here. When we refresh our browser, we’d get the login page. But the content is showing 404 because we haven’t defined the login page!
Create the login form. Add a new file ‘LoginForm.php’ in ‘src/App/Form’ directory. The login form will show username and password fields. The post the form, I’ll put a submit button:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
<?php declare(strict_types=1); namespace App\Form; use Zend\Form\Form; use Zend\InputFilter\InputFilterProviderInterface; use Zend\Form\Element\Text; use Zend\Form\Element\Password; class LoginForm extends Form implements InputFilterProviderInterface { public function __construct() { parent::__construct('login-form'); } public function init() { $this->add([ 'type' => Text::class, 'name' => 'username', 'options' => [ 'label' => 'Username', ], ]); $this->add([ 'type' => Password::class, 'name' => 'password', 'options' => [ 'label' => 'Password', ], ]); $this->add([ 'name' => 'Login', 'type' => 'submit', 'attributes' => [ 'value' => 'Login', ], ]); } public function getInputFilterSpecification() { return [ [ 'name' => 'username', 'required' => true, 'filters' => [ ['name' => 'StripTags'], ['name' => 'StringTrim'], ], ], [ 'name' => 'password', 'required' => true, 'filters' => [ ['name' => 'StripTags'], ['name' => 'StringTrim'], ], ], ]; } } |
then create a login page handler with inject it with login form with the following factory in src/App/Handler/LoginPageFactory.php:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<?php declare(strict_types=1); namespace App\Handler; use Psr\Container\ContainerInterface; use Psr\Http\Server\MiddlewareInterface; use Zend\Expressive\Template\TemplateRendererInterface; use Zend\Form\FormElementManager; use App\Form\LoginForm; class LoginPageFactory { public function __invoke(ContainerInterface $container) : MiddlewareInterface { $template = $container->get(TemplateRendererInterface::class); $loginForm = $container->get(FormElementManager::class)->get(LoginForm::class); return new LoginPageHandler($template, $loginForm); } } |
The LoginPageHandler itself can be initialized in src/App/Handler/LoginPageHandler.php:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
<?php declare(strict_types=1); namespace App\Handler; use Psr\Http\Server\MiddlewareInterface; use Zend\Expressive\Template\TemplateRendererInterface; use App\Form\LoginForm; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\RequestHandlerInterface; use Psr\Http\Message\ResponseInterface; use Zend\Expressive\Session\SessionMiddleware; use Zend\Expressive\Authentication\UserInterface; use Zend\Diactoros\Response\RedirectResponse; use Zend\Diactoros\Response\HtmlResponse; class LoginPageHandler implements MiddlewareInterface { private $template; private $loginForm; public function __construct( TemplateRendererInterface $template, LoginForm $loginForm ) { $this->template = $template; $this->loginForm = $loginForm; } public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface { $session = $request->getAttribute(SessionMiddleware::SESSION_ATTRIBUTE); if ($session->has(UserInterface::class)) { return new RedirectResponse('/'); } $error = ''; return new HtmlResponse( $this->template->render('app::login-page', [ 'form' => $this->loginForm, 'error' => $error, ]) ); } } |
Above, we redirect to ‘/’ page when there is a session data as it already authenticated check. We are going to add authentication process next.
The Login form can be as simple as the following in templates/app/login-page.phtml
|
1 2 3 4 5 6 7 |
<?php echo $error; $form->prepare(); echo $this->form($form); |
We can register the LoginPageHandler at App\ConfigProvider::getDependencies() config in src/App/ConfigProvider.php
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
... class ConfigProvider { ... /** * Returns the container dependencies */ public function getDependencies() : array { return [ 'invokables' => [ ... ], 'factories' => [ Handler\HomePageHandler::class => Handler\HomePageHandlerFactory::class, Handler\LoginPageHandler::class => Handler\LoginPageFactory::class, ], ]; } ... } |
The routing can be registered as follows with add \Zend\Expressive\Authentication\AuthenticationMiddleware::class for next middleware in config/routes.php:
|
1 2 3 4 5 6 7 8 9 10 |
return function (Application $app, MiddlewareFactory $factory, ContainerInterface $container) : void { ... $app->route('/login', [ App\Handler\LoginPageHandler::class, \Zend\Expressive\Authentication\AuthenticationMiddleware::class, ], ['GET', 'POST'], 'login'); ... }; |
Until this, when I refresh the browser, I got this error and can’t continue anymore. I still dont know why the error is happened:
|
1 |
Too few arguments to function App\Handler\LoginPageHandler::__construct(), 0 passed in /home/teddy/Documents/works/zend-expressive-skeleton/vendor/zendframework/zend-expressive/src/MiddlewareContainer.php on line 64 and exactly 2 expected |
I need learn Zend Expressive more!