mezzio / mezzio Goto Github PK
View Code? Open in Web Editor NEWPSR-15 Middleware Microframework
Home Page: https://docs.mezzio.dev/mezzio/
License: BSD 3-Clause "New" or "Revised" License
PSR-15 Middleware Microframework
Home Page: https://docs.mezzio.dev/mezzio/
License: BSD 3-Clause "New" or "Revised" License
Q | A |
---|---|
Version mezzio/mezzio | 3.2.2 |
Version laminas/laminas-router | 3.3.2 |
PHP | 7.2.31 |
Actually I have an Zend MVC Application with the following routing:
return [
'routes' => [
'wizard' => [
'type' => Segment::class,
'options' => [
'route' => '/wizard/[:embed/]:id/:sessionId',
'constraints' => [
'id' => '[1-9][0-9]*',
'embed' => 'embed',
],
'defaults' => [
'controller' => Controller\IndexController::class,
'id' => 1,
],
],
]
I'm using this call to generate an Uri in a view script:
$this->url('wizard', ['id' => 1, 'embed' => null, 'sessionId' => 'os09t2ujphehcbvp7nr7fgs5ei'])
The generated Uri is "/wizard/1/os09t2ujphehcbvp7nr7fgs5ei".
I'm trying to rewrite that Application to an Mezzio Application.
The new Route configuration is:
$wizardRoute = $app->post(
'/wizard/[:embed/]:id/:sessionId',
[
MandantHandler::class,
SessionMiddleware::class,
StartFormHandler::class,
],
'wizard'
);
$wizardRoute->setOptions(
[
'constraints' => [
'id' => '[1-9][0-9]*',
'embed' => 'embed',
],
'defaults' => [
'id' => 1,
'embed' => '', // <-- this is nessesary to get this working
],
]
);
The new Call in a view script has to be:
$this->url('wizard', ['id' => 2, 'embed' => '', 'sessionId' => '2d5d501b4a0f1d8caa171258e8821a54'])
The generated Uri is now "/wizard//2/2d5d501b4a0f1d8caa171258e8821a54". (With double Slash)
If I set the "embed" parameter to null or don't set default, I get this Exception:
Laminas\Router\Exception\InvalidArgumentException thrown with message "Missing parameter "embed""
Stacktrace:
#63 Laminas\Router\Exception\InvalidArgumentException in /home/developer/projects/mezzio/vendor/laminas/laminas-router/src/Http/Segment.php:310
#62 Laminas\Router\Http\Segment:buildPath in /home/developer/projects/mezzio/vendor/laminas/laminas-router/src/Http/Segment.php:329
#61 Laminas\Router\Http\Segment:buildPath in /home/developer/projects/mezzio/vendor/laminas/laminas-router/src/Http/Segment.php:424
#60 Laminas\Router\Http\Segment:assemble in /home/developer/projects/mezzio/vendor/laminas/laminas-router/src/Http/Part.php:208
#59 Laminas\Router\Http\Part:assemble in /home/developer/projects/mezzio/vendor/laminas/laminas-router/src/Http/TreeRouteStack.php:371
#58 Laminas\Router\Http\TreeRouteStack:assemble in /home/developer/projects/mezzio/vendor/mezzio/mezzio-laminasrouter/src/LaminasRouter.php:128
#57 Mezzio\Router\LaminasRouter:generateUri in /home/developer/projects/mezzio/vendor/mezzio/mezzio-helpers/src/UrlHelper.php:106
#56 Mezzio\Helper\UrlHelper:__invoke in /home/developer/projects/mezzio/vendor/mezzio/mezzio-helpers/src/UrlHelper.php:129
#55 Mezzio\Helper\UrlHelper:generate in /home/developer/projects/mezzio/vendor/mezzio/mezzio-laminasviewrenderer/src/UrlHelper.php:47
...
#2 Laminas\HttpHandlerRunner\RequestHandlerRunner:run in /home/developer/projects/mezzio/vendor/mezzio/mezzio/src/Application.php:82
#1 Mezzio\Application:run in /home/developer/projects/mezzio/public/index.php:29
#0 {closure} in /home/developer/projects/mezzio/public/index.php:30
It is possible to set an optional Parameter to null and the Parameter is not in the generated Uri.
Q | A |
---|---|
Proposed Version(s) | 3.7.0 |
BC Break? | No |
To unblock PHP 8.1 support from this package, we should remove all router integration tests and only do unit tests when it comes to integration tests (and/or use our own laminas-router
where we actually can always provide patches to be compatible with new versions - e.g. PHP or major versions of this package).
mezzio/mezzio-aurarouter
does not support PHP 8.1 yet. To provide proper 8.1 support (without deprecation warnings), we would have to provide patches to https://github.com/auraphp/Aura.Router
To avoid having that huge amount of work until we can get this package ready for 8.1, we should move all integration tests to the related components.
Users wont have any impact on this as we only require these packages for integration tests.
If we do want to keep that package, we should at least remove integration tests from this package and port them to the router component.
Q | A |
---|---|
New Feature | yes |
RFC | yes |
BC Break | no |
In this package, Mezzio\ApplicationPipeline
is a service identifier to retrieve the assembled middleware pipeline for a mezzio project which does not actually represents a class.
This pipeline is consumed by these classes in a mezzio project:
Line 33 in 24bfca0
That pipeline gets assembled in:
And registered in:
Line 54 in 24bfca0
Retrieving this pipeline via a PSR-11 is quite annoying due to the fact that neither an IDE is able to auto-complete the typed service name nor a static-analysis tool is able to understand what is happening.
My suggestion would be to create a class called ApplicationPipeline
which implements MiddlewarePipeInterface
(which implements both RequestHandlerInterface
and MiddlewareInterface
) and thus allow factories to retrieve that pipeline via:
Mezzio\ApplicationPipeline
class-stringPsr\Http\Server\RequestHandlerInterface
class-string (alias to Mezzio\ApplicationPipeline
)This would allow us to properly fetch the application pipeline from within the ApplicationFactory
and the RequestHandlerRunnerFactory
:
Recently trying to work on a PR for mezzio-skeleton
and I'm getting a lot of failing tests regarding config being an ArrayObject
and not a map caused by the following line:
I also found the following related issue: https://github.com/mezzio/mezzio-authentication/pull/11/files
Q | A |
---|---|
Proposed Version(s) | 4.0.0 |
BC Break? | Yes |
callable
response factory supportdeclare(strict_types=1);
where its missingWe already prepared v3 to support native PSR-17
factories (when available) and now we just have to create a new major to drop support for the callable factory.
mezzio/mezzio
(like laminas/laminas-mvc
) is supposed to work as a "project". I dont think that there are too many components which depend on it and thus, we can safely create a new major.
To get fully PSR-17 compatible, we just have to remove the ResponseInterface
service usage (which was used to receive a callable
which creates a PSR-7 ResponseInterface
when being invoked.
Component | PSR-17 compatible |
---|---|
mezzio/mezzio-router |
❗ as of 3.6.0 ResponseFactoryInterface , StreamFactoryInterface still missing |
mezzio/mezzio-authentication-basic |
✔️ as of 1.4.0 |
mezzio/mezzio-authentication-laminasauthentication |
✔️ as of 1.3.0 |
mezzio/mezzio-authentication-oauth2 |
✔️ as of 2.4.0 |
mezzio/mezzio-authentication-session |
✔️ as of 1.4.0 |
mezzio/mezzio-authorization |
✔️ as of 1.4.0 |
mezzio/mezzio-hal |
✔️ as of 2.3.0 |
mezzio/mezzio-problem-details |
✔️ as of 1.5.0 |
mezzio/mezzio-problem-details |
❌ |
laminas/laminas-httphandlerrunner |
not affected |
I have a little module that configures the FormElementManager
like this:
return[
'form_elements' => [
'factories' => [
PriceFieldset::class => PriceFieldsetFactory::class,
ProductFormInterface::class => ProductFormFactory::class,
],
],
];
This config is loaded by a ConfigProvider
class and loaded by the ConfigManager
in the /config/config.php
file like this:
$configManager = new ConfigManager(
[
Zend\Form\ConfigProvider::class,
Product\ConfigProvider::class,
new PhpFileProvider($pattern),
],
$cachedConfigFile
);
When I want to access the ProductFormInterface::class
from the FormElementManager
it is not found. I need to these lines to the /config/container.php
file to get this running.
$container = new ServiceManager();
(new Config($config['dependencies']))->configureServiceManager($container);
// Inject config
$container->setService('config', $config);
/** @var FormElementManagerV3Polyfill $formElementManager */
$formElementManager = $container->get('FormElementManager');
$formElementManager->configure($config['form_elements']);
return $container;
What am I doing wrong? I don't think this is a wanted behaviour. In my module I also have some validators, filters, hydrators and input filters as well. Currently, I need to add the configuration manually for every specialized service managers.
Originally posted by @RalfEggert at zendframework/zend-expressive#387
Q | A |
---|---|
New Feature | yes |
RFC | no |
BC Break | no |
It would be nice to be able to define "controller-like" handlers for multiple routes without resorting to:
https://docs.mezzio.dev/mezzio/v2/cookbook/using-routed-middleware-class-as-controller/#handling-multiple-routes-in-a-single-class
At present stage middleware definitions such as:
$app->route('/news/article/create', [News\ArticleController::class, 'create']);
$app->route('/news/article/update/{id}', [News\ArticleController::update');
are treated as callable-handlers and obviously do not work.
This would also remove the need for setting an extra 'action' request attribute and maybe cleaner route definitions
(example updated with allowed_methods on 2020-04-13)
// file config/autoload/routes.global.php
return [
// ...
'routes' => [
// article creation handling submitted form data
'news/article/create' => [
'path' => 'news/article/create',
'middleware' => [News\ArticleController::class, 'create'],
// or
// 'middleware' => 'News\ArticleController::create',
'allowed_methods' => ['POST'],
],
// show article update form
'news/article/edit' => [
'path' => 'news/article/edit/{id}',
'middleware' => [News\ArticleController::class, 'update'],
'allowed_methods' => ['GET'],
],
// article update handling submitted form data
'news/article/update' => [
'path' => 'news/article/update/{id}',
'middleware' => [News\ArticleController::class, 'update'],
'allowed_methods' => ['POST', 'PATCH', 'PUT'],
],
// article deletion
'news/article/delete' => [
'path' => 'news/article/delete/{id}',
'middleware' => [News\ArticleController::class, 'delete'],
'allowed_methods' => ['POST', 'DELETE'],
],
// instead of the following
// this may look simpler but:
// 1. We have only 1 route and we have to add a subst param ['action' => 'create'] in UrlHelper
// 2. We to examine the request action-attribute in the controller(handler) handle method to reroute the request to internal method
'news/article' => [
'path' => 'news/article/{action:create|update|delete}(/{id})',
'options' => [
'defaults' => [
'action' => 'whatever',
],
],
'middleware' => News\ArticleController::class,
],
],
];
The idea is to have a LazyControllerMiddleware that handles these 2 types of middleware definitions. The LazyControllerMiddleware would fetch the controller(handler) from the container on demand, create a wrapping middleware and run the defined controller-method in the wrapper process() method.
This would be useful when different handlers have the same dependencies (e.g. crud write-handlers).
Anyone else likes the idea?
kind regards,
maks
Good morning,
I've an expressive application with a config-driven pipeline. That application exposes different UI levels such as /admin, /reseller and /client, among others...
Right now, I've a specific pipeline middleware that I want to execute only for specific paths:
...
protected function getPipeline()
{
return [
[
'path' => '/admin',
'middleware' => \Zend\Expressive\Navigation\Middleware\NavigationMiddleware::class
],
[
'path' => 'reseller',
'middleware' => \Zend\Expressive\Navigation\Middleware\NavigationMiddleware::class
],
[
'path' => '/client',
'middleware' => \Zend\Expressive\Navigation\Middleware\NavigationMiddleware::class
],
];
}
...
This is working but, I would rather be able to do something like this:
...
protected function getPipeline()
{
return [
[
'paths' => ['/admin', '/reseller', '/client'],
'middleware' => \Zend\Expressive\Navigation\Middleware\NavigationMiddleware::class
],
}
}
...
Of course, I could use a custom delegator but I think this could be integrated in the default \Zend\Expressive\Container\ApplicationConfigInjectionDelegator
delegator as follows:
...
public static function injectPipelineFromConfig(Application $application, array $config) : void
{
if (empty($config['middleware_pipeline'])) {
return;
}
// Create a priority queue from the specifications
$queue = array_reduce(
array_map(self::createCollectionMapper(), $config['middleware_pipeline']),
self::createPriorityQueueReducer(),
new SplPriorityQueue()
);
foreach ($queue as $spec) {
$paths = $spec['path'] ?? ($spec['paths'] ?? '/');
foreach((array) $paths as $path) {
$application->pipe($path, $spec['middleware']);
}
}
}
...
instead of
....
public static function injectPipelineFromConfig(Application $application, array $config) : void
{
if (empty($config['middleware_pipeline'])) {
return;
}
// Create a priority queue from the specifications
$queue = array_reduce(
array_map(self::createCollectionMapper(), $config['middleware_pipeline']),
self::createPriorityQueueReducer(),
new SplPriorityQueue()
);
foreach ($queue as $spec) {
$path = $spec['path'] ?? '/';
$application->pipe($path, $spec['middleware']);
}
}
....
Thank you.
Originally posted by @nuxwin at zendframework/zend-expressive#652
Provide a narrative description of what you are trying to accomplish:
2.2.0 release of zendframework/zend-expressive-zendviewrenderer
adds support for extension
parameter for default suffix to be used by zend-view resolver, in line with other template renderers.
extension
config parameter.Originally posted by @Xerkus at zendframework/zend-expressive#664
Summary: explain the pros/cons, speed and other differences between the choices we have.
When I first looked at zend expressive I was impressed but confused, It looked nice, but I didn't know what happened with mvc nor the difference between these two choices, and I also looked at all the choices I had when it came to view, routing etc. And did not know what to pick or what the difference was. A Routing choices page where the differences are listed, as well as a template choices page in the getting started section.
Originally posted by @AndersMadsen at zendframework/zend-expressive#512
Q | A |
---|---|
Version(s) | master |
In section "Get Started Now!" (https://docs.mezzio.dev/mezzio/) the button "Learn more" is not rendered properly:
And another one below:
Following the doc about debugbars, the php-middleware/php-debug-bar
neither bitExpert/prophiler-psr7-middleware
didn't work in a 'programmatic_pipelines' context.
What is the recommended way to pipe middleware only for development ?
For now I've ended up adding them in the config/pipeline.php
file:
$app->pipe(ErrorHandler::class);
$debug = $app->getContainer()->get('config')['debug'] ?? false;
if ($debug) {
/* example with phpdebugbar */
$debugBarFactory = new \PhpMiddleware\PhpDebugBar\PhpDebugBarMiddlewareFactory();
$middleware = $debugBarFactory();
$app->pipe($middleware);
/* example with prophilermiddleware */
$prophiler = new \Fabfuel\Prophiler\Profiler();
$toolbar = new \Fabfuel\Prophiler\Toolbar($prophiler);
$middleware = new \bitExpert\Http\Middleware\Psr7\Prophiler\ProphilerMiddleware($toolbar);
$app->pipe($middleware);
}
$app->pipe(ServerUrlMiddleware::class);
//...
Not sure if it's a good practive. BTW both debugbars looks pretty minimal. Is there any plan to have the ZendDeveloperTools toolbar for expressive ?
Note, for PHP7 and ProphilerMiddleware, you add:
$ composer require --dev fabfuel/prophiler:dev-feature/php7 bitexpert/prophiler-psr7-middleware
Originally posted by @belgattitude at zendframework/zend-expressive#488
Q | A |
---|---|
Version(s) | 3.11.0 |
mezzio-tooling installation fails on this line
Line 74 in d5bf81f
➜ criticker-api git:(master) ✗ php vendor/mezzio/mezzio/bin/mezzio-tooling
Installing mezzio-tooling
Using version ^2.6 for mezzio/mezzio-tooling
./composer.json has been updated
Running composer update mezzio/mezzio-tooling
Loading composer repositories with package information
Updating dependencies
Nothing to modify in lock file
Installing dependencies from lock file (including require-dev)
Nothing to install, update or remove
Generating autoload files
composer/package-versions-deprecated: Generating version class...
composer/package-versions-deprecated: ...done generating version class
60 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
No security vulnerability advisories found
Installed tooling package, but package does not contain script information?
Check your installation, and follow the migration documentation to use the tooling.
I have a mezzio-project developed. I use the Apache Server. The problem is that my https-requests will produce 404-errors, but when i changed to http it will work.
Q | A |
---|---|
Version(s) | 3.2.1 |
When installing the skeleton of mezzio using the following command:
composer create-project mezzio/mezzio-skeleton .
I get an error when loading the home page:
composer create-project mezzio/mezzio-skeleton .
php -S 0.0.0.0:9000 -t public/
Also, the problem was solved running composer update
.
I expect the following home page:
Hi guys!
I'm trying to integrate mezzio/mezzio-laminasviewrenderer
into our mezzio project which was only api oriented. I need laminas-view
templates to generate html code for emails.
I have read documentation from this page https://docs.mezzio.dev/mezzio/v3/features/template/laminas-view/
And there is an example of rendering html like this one
$content = $renderer->render('blog/entry', [
'layout' => 'layout::blog',
'entry' => $entry,
]);
What is 'blog/entry'
???
What is 'layout::blog'
???
How to configure them and how to attach them to real phtml files?
I was trying to understand source code from /vendor/mezzio/mezzio-laminasviewrenderer/src/LaminasViewRendererFactory.php
. It contains this example:
* <code>
* 'templates' => [
* 'extension' => 'default template file extension',
* 'layout' => 'name of layout view to use, if any',
* 'map' => [
* // template => filename pairs
* ],
* 'paths' => [
* // namespace / path pairs
* //
* // Numeric namespaces imply the default/main namespace. Paths may be
* // strings or arrays of string paths to associate with the namespace.
* ],
* ]
* </code>
Can somebody show me and example of configuring 'paths'?
Looks like it should be like this:
'templates' => [
'paths' => [
[
'blog/entry' => '/path/to/blog/entry.phtml'
]
],
]
or
'templates' => [
'paths' => [
'some::namespace' => [
'blog/entry' => '/path/to/blog/entry.phtml'
]
],
]
Am I correct? Is there a good example with source code how to use laminas-view with mezzio?
As this class is extendable and I do extend it, I would be happy to have this property as protected
. Otherwise, everything that happens in parents constructor, stays in parent constructor, which leads to constructor duplication in the child class.
mezzio/src/MiddlewareFactory.php
Line 56 in 7d71a48
Hello! How I can change default_suffix from .phtml on something else?
I use zend-view with service-manager.
Originally posted by @Auramel at zendframework/zend-expressive#641
Q | A |
---|---|
New Feature | yes |
RFC | no |
BC Break | no |
#60 introduces PHP 8 compatibility, but by adding a --ignore-platform-reqs
composer flag during installation.
That's OK, since we're doing it to speed up the upgrade to PHP 8, but we need to remove said flag in 3.4.0
I'm trying to include zend-expressive in my project, but unsuccessfully.
When i require zend-expressive via console ( composer require zendframework/zend-expressive ), i get the following error:
Your requirements could not be resolved to an installable set of packages.
Problem 1
- zendframework/zend-expressive 3.0.0 requires zendframework/zend-httphandlerrunner ^1.0.1 -> satisfiable by zendframework/zend-httphandlerrunner[1.0.1].
- zendframework/zend-expressive 3.0.1 requires zendframework/zend-httphandlerrunner ^1.0.1 -> satisfiable by zendframework/zend-httphandlerrunner[1.0.1].
- zendframework/zend-expressive 3.0.2 requires zendframework/zend-httphandlerrunner ^1.0.1 -> satisfiable by zendframework/zend-httphandlerrunner[1.0.1].
- zendframework/zend-httphandlerrunner 1.0.1 requires psr/http-message-implementation ^1.0 -> no matching package found.
- Installation request for zendframework/zend-expressive ^3.0 -> satisfiable by zendframework/zend-expressive[3.0.0, 3.0.1, 3.0.2].
Potential causes:
- A typo in the package name
- The package is not available in a stable-enough version according to your minimum-stability setting
see <https://getcomposer.org/doc/04-schema.md#minimum-stability> for more details.
- It's a private package and you forgot to add a custom repository to find it
Read <https://getcomposer.org/doc/articles/troubleshooting.md> for further common problems.
composer require zendframework/zend-expressive
Expected composer to install the package
Composer returned an error regarding package dependencies
Originally posted by @itapai at zendframework/zend-expressive#624
I really love Zend\Expressive
so far. To really get in rolling for beginners, I would love to see a tutorial like the Album tutorial for a Zend\Mvc
project. It is really nice to see the examples, but beginners will also look for help how to structure their applications based on Zend\Expressive
properly.
Any ideas and thoughts about this?
Originally posted by @RalfEggert at zendframework/zend-expressive#176
Q | A |
---|---|
Proposed Version(s) | 3.x |
BC Break? | No |
Standardize how routes and middleware are piped into the application, by providing a, let's call it ApplicationProgrammaticConfigDelegator
, that wraps the logic of loading the config/routes.php
and config/pipeline.php
files.
Then, users would need to decorate their Application service with either ApplicationProgrammaticConfigDelegator
or ApplicationConfigInjectionDelegator
(or none, if they want to follow a completely different approach).
The skeleton application would use this new delegator by default.
I find myself in the next situation:
I have a mezzio-based project where I have been historically defining routes and middlewares via configuration, so I had my Application service decorated with ApplicationConfigInjectionDelegator
.
When the mezzio-swoole package was created (still zend-expressive-swoole back then), I started experimenting with it, in order to support serving this application with swoole.
On its first versions, the command to start a mezzio app with swoole was more opinionated, and always tried to load the config/routes.php
and config/pipeline.php
files, which did not exist in my case, making the start-up fail.
I provided a PR to make the loading optional, and I have been successfully using it since.
Recently I have also added support for RoadRunner, so now the project can be bootstrapped/run in three different ways (plus the CLI).
Also recently, due to a couple of new features, the loading of routes and middleware via config has become more inconvenient, and using the programmatic approach mkes more sense now.
The problem is that I now have two different scopes (php-fp and roadrunner) where I have to manually require the routes.php
and pipeline.php
files, as they have different entry points.
I have considered writting a common script which is then used by both entry points, but I already have too many scripts "calling" each other and it's becoming harder to follow.
I have also considered writting this delegator myself, but this would conflict with mezzio-swoole's start command, since it would try to load them again. I would need to conditionally register this delegator based on the execution context.
On mezzio, none that I can think of. Users would need to add the new delegator and remove the manually requirement of the files from their entry points, but as long as they don't do it, everything should continue working.
On mezzio-swoole, the logic that right now loads those files if they exist, would need to somehow check if they have been already included, and avoid it in that case. That would keep backwards compatibility. Including this in a major version and just removing the logic from the start command would be another option.
As already more or less explained, my proposal would be to be less opinionated on mezzio-swoole, and also avoid forcing entry points to require the two mentioned files, in case the project has multiple entry points.
Instead, mezzio would provide two ways to load the config, which would require decorating the Application service one way or another (the docs should explain both options).
Then, different entry points would be able to pull the Application service from the container and it would already have all the config no matter the entry point.
after running
composer install --no-dev
config/autload/development.local.php symlink still remains .
My project crashes with error message "Uncaught Error: Class 'Whoops\Run' ".
I have to manually delete "development.local.php" after install.
May be there is a problem with my workflow. I sync development files to deployment space and run composer install --no-dev afterwards. But at least switching from development to no-dev should work.
Q | A |
---|---|
Version(s) | x.y.z |
composer install
composer install --no-dev
config/autload/development.local.php symlink still remains .
composer install
composer install --no-dev
config/autload/development.local.php should not exist
Hi all,
I have read zendframework/zend-expressive#342 and I still have a few questions. Firstly, let me describe the scenario.
Current situation
Web application written in Zend Framework 1. There are two modules in the ZF1 app structure:
"default" model used for the publicly accessible website
"admin" model used for web administrators (accessible only by employees of the company) to update the website content and much more things covering the internal processes of the mentioned company
The future
Convert the "default" module to an rest API to let 3rd party companies create the public website using this to be developed API to deliver the content.
The "admin" module will stay untouched for now.
The question
I know I could probably simply tweak the old ZF1 "default" module to serve as an API (remove all the views and update all the controllers to return some JSON structure). But I would like to take this as an opportunity to get my hands on something new. So I am thinking about ZF3, Expressive or Apigility.
I want to deliver simple REST API which would basically serve to:
What I believe is a must have is a self-generated documentation (I would prefer Swagger) because the API will be used by 3rd party companies to create/redesign the website.
Which of the Zend "frameworks" mentioned above is suited for such a task? What do you guys think?
I pretty much like the Zend Expressive as it is kind of minimalistic and can be tweaked to whatever needed however I am not able to find out whether there is a swagger component. I have found Swagger component for ZF3. And Apigility is a bit mystery to me. It seems like it is a online tool for creating rest apis which sounds interesting and scary at the same time as I cannot imagine myself writing a controller code in a browser but I might be missing something about Apigility.
Thanks you very much and if you want me to clarify anything just let me know.
Originally posted by @starkskalle at zendframework/zend-expressive#665
This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.
These problems occurred while renovating this repository. View logs.
These updates are awaiting their schedule. Click on a checkbox to get an update now.
These updates have all been created already. Click a checkbox below to force a retry/rebase of any.
laminas/laminas-servicemanager
, laminas/laminas-stratigility
)composer.json
php ~8.1.0 || ~8.2.0 || ~8.3.0
fig/http-message-util ^1.1.5
laminas/laminas-httphandlerrunner ^2.1
laminas/laminas-stratigility ^3.5
mezzio/mezzio-router ^3.7
mezzio/mezzio-template ^2.2
psr/container ^1.0||^2.0
psr/http-factory ^1.0
psr/http-message ^1.0.1 || ^2.0.0
psr/http-server-middleware ^1.0
webmozart/assert ^1.10
filp/whoops ^2.15.4
laminas/laminas-coding-standard ~2.5.0
laminas/laminas-diactoros ^3.3.1
laminas/laminas-servicemanager ^3.22.1
mezzio/mezzio-aurarouter ^3.7
mezzio/mezzio-fastroute ^3.11
mezzio/mezzio-laminasrouter ^3.9
phpunit/phpunit ^10.5.28
psalm/plugin-phpunit ^0.19.0
vimeo/psalm ^5.25.0
.github/workflows/continuous-integration.yml
.github/workflows/docs-build.yml
.github/workflows/release-on-milestone-closed.yml
An entry "Installation" is completely missing in the navigation: https://docs.mezzio.dev/mezzio/
We need a separate page which shows the different ways for an installation. Creating a project via the skeleton application is one of them. The manual installation via composer require laminas/laminas-diactoros mezzio/mezzio
may be another.
Q | A |
---|---|
Version(s) | x.y.z |
I will not use layout templates for error pages, so I want to set layout to null for error templates. Using this configuration;
[ 'mezzio' => [ 'error_handler' => [ 'layout' => null ] ] ]
this does not cancel layout. However, instead of null if I use empty string ('') this works. But I don't know if this is right and will break in future versions.
This behaviour is inconsistent with other parts. For example I can cancel global layout with this configuration;
[ 'templates' => ['layout' => null] ]
[ 'mezzio' => [ 'error_handler' => [ 'layout' => null ] ] ]
does not cancel error handler layout.
[ 'mezzio' => [ 'error_handler' => [ 'layout' => null ] ] ]
should cancel error handler layout
I cannot see a proper stack trace of errors while I'm developing, which is obviously very frustrating.
However, when I switch php error reporting on I can see an exception raised by Diactoros (...Unsupported response reason phrase; must be a string, received NULL...zendframework/zend-diactoros/src/Response.php:185 Stack trace...) , but no trace/indication of where the problem actually occurred, when php error reporting is off then I get a blank screen with server 500 error.
I thought Zend Expressive has default exception and other response handling built in i.e. 404, methodNotAllowed etc, instead of just bombing out on all problems... or is it up to the developer to write this core functionality?
I've wasted so much time searching for examples, but as usual nothing that that works... I cannot believe this is so badly documented (or an architecture flaw in v1?)
I mostly use PHP Slim and it has the above baked in, the developer can also override it with custom handlers...simple and to-the-point. I can unfortunately not use Slim and have to solve this error reporting issue with Zend Expressive.. please help
Originally posted by @TradeSharer at zendframework/zend-expressive#653
# create project from zend-expressive-skeleton
composer create-project zendframework/zend-expressive-skeleton .
# run container
docker run --rm -p 8080:80 -v "$PWD:/app" -w "/app" php:apache sh -c '
a2enmod rewrite
rmdir /var/www/html
ln -s /app/public /var/www/html
exec apache2-foreground
'
# run curl in other terminal, and see response
curl -i -0 http://localhost:8080/
curl request is HTTP/1.0, but zend-expressive has HTTP/1.1 response.
HTTP/1.1 200 OK
Date: Wed, 26 Jul 2017 10:46:48 GMT
Server: Apache/2.4.10 (Debian)
X-Powered-By: PHP/7.1.7
Content-Length: 151
Content-Type: application/json
:
Next, I tried ApacheBench.
ab -c 1 -n 1 http://localhost:8080/
Very very slow.
:
Requests per second: 0.20 [#/sec] (mean)
Time per request: 5021.594 [ms] (mean)
Time per request: 5021.594 [ms] (mean, across all concurrent requests)
:
ApacheBench expect active close of server, but server does not close until KeepAliveTimeout seconds.
This problem can solved by fix response protocol version based on request protocol version.
// pipeline.php
use Psr\Http\Message\ServerRequestInterface;
use Interop\Http\ServerMiddleware\DelegateInterface;
$app->pipe(function (ServerRequestInterface $request, DelegateInterface $delegate) {
return $delegate->process($request)->withProtocolVersion($request->getProtocolVersion());
});
Originally posted by @ngyuki at zendframework/zend-expressive#502
Support for laminas-httphandlerrunner 2.x versions
Q | A |
---|---|
New Feature | yes |
RFC | no |
BC Break | yes? |
It is possible have support in composer both httphandlerrunner major version 1.x || 2.x Or it is should be new major release (4.0) with 2.x only??
Q | A |
---|---|
New Feature | yes |
To be prepared for the december release of PHP 8.0, this repository has some additional TODOs to be tested against the new major version.
In order to make this repository compatible, one has to follow these steps:
composer.json
to provide support for PHP 8.0 by adding the constraint ~8.0.0
composer.json
to drop support for PHP less than 7.3composer.json
to implement phpunit 9.3 which supports PHP 7.3+.travis.yml
to ignore platform requirements when installing composer dependencies (simply add --ignore-platform-reqs
to COMPOSER_ARGS
env variable).travis.yml
to add PHP 8.0 to the matrix (NOTE: Do not allow failures as PHP 8.0 has a feature freeze since 2020-08-04!)On our last TSC meeting we agreed to use vimeo/psalm
as a static analysis tool.
We'd like to switch to use this library instead of phpstan.
Example implementation and configuration can be found in:
Q | A |
---|---|
Proposed Version(s) | 3.3.0 |
BC Break? | No |
Mezzio has its own convention to create an instance of ResponseInterface
and ServerRequestInterface
.
One has to use laminas-diactoros
which works out-of the box with mezzio due to several internal factories or one has to create those callables to ensure other PSR-7 packages are working.
I'd like to change this to PSR-17 factories instead which would enable packages to provide some kind of autowiring (like in laminas-diactoros).
I am currently working on a Proxy request handler which should pass a provided ServerRequestInterface
to another, external API with cURL. I see that diactoros
has some kind of $_POST
usage which passes multipart/form-data
to parsedBody
while the Body StreamInterface
contains php://input
which does not contain the multipart/form-data
stuff.
This is kinda weird as I would expect containing the StreamInterface
having the "RAW" data of that request while parsedBody
is some kind of pre-parsed Body.
I want to verify if thats probably some diactoros
-related bug by switching the underlying PSR-7 library but as I can't just provide the configuration as in laminas-diactoros
(ConfigProvider
, see link above) but have to write code for this, I realized that this is not the de-facto standard PSR-17
but an own implementation.
When implementing PSR-17, this would mean that we can either support the callables or the PSR-17 factory interfaces.
We can either change this in a major version or add this within a minor version and provide callables from the current existing factories (in case they're available) and remove the callable logic with the next major.
In case we want to introduce a BC-Break in the next major, we need to document this breaking change but forward compatibility would be quite easy to apply as laminas-diactoros
already provide the ConfigProvider
example on how that might look like.
If an application uses an other PSR-7 implementation, they have just to provide the mapping from the interface to the implementation (which can be like copy & paste from the laminas-diactoros
package).
Current "factories" could consume PSR-17 factories and wrapping these in the callables
.
Those "services" which are working with those callables
don't need changes until we bump the major of this package and thus changing the __construct
to consume PSR-17 interfaces instead of callables
.
So we can provide some kind of forward-compatibility regarding the configuration but there has to be a hard BC break with the next major version bump to switch from callable
annotation to *Interface
annotation.
Currently known packages which are affected by this change:
Maybe there are more packages, I did not check any package around tho.
I've found "generate-factory-for-class" very usefull, but executing it on Windows was a small problem at first.
If I could suggest a small change in this tutorial, I recomend adding a comment saying that correct syntax of this command would be:
.\vendor\bin\generate-factory-for-class "App\Action\TemplateTestAction" > src/App/src/Action/TemplateTestActionFactory.php
The biggest problem was that classname shouldn't be App\\Action\\TemplateTestAction but App\Action\TemplateTestAction. Well, at least in my environment.
Originally posted by @asui at zendframework/zend-expressive#472
Q | A |
---|---|
QA | yes |
As decided during the Technical-Steering-Committee Meeting on August 3rd, 2020, Laminas wants to implement vimeo/psalm in all packages.
Implementing psalm is quite easy.
psalm.xml
in the project root$ composer require --dev vimeo/psalm
$ vendor/bin/psalm --set-baseline=psalm-baseline.xml
static-analysis
with the command psalm --shepherd --stats
script:
in .travis.yml
: - if [[ $TEST_COVERAGE == 'true' ]]; then composer static-analysis ; fi
phpstan.neon.dist
, .travis.yml
entry, composer.json
require-dev
and scripts
)Example:
config
[
'name' => 'my.post',
'path' => "/my",
'middleware' => [
Action\PostAction::class,
Action\PostAction2::class, // add another action to react on path
],
'allowed_methods' => ['POST'],
],
Im using a middleware (priority PHP_INT_MAX) to catch fatal error (register_shutdown_function
).
When im using one action only in the config
and when i force an fatal error in that action
the registered shutdown function gets called.
If im using two actions as shown above
then no registered shutdown function gets called.
The middleware im using wont be invoked/loaded before the action.
Originally posted by @cottton at zendframework/zend-expressive#361
Q | A |
---|---|
Version(s) | 3.5.1 |
I have use-case where I do not need routes but want to use mezzio.
The Application
requires RouteCollector
which is provided by the various router services. Due to the lack of an interface, the RouteCollector
cannot be stripped away and thus, one has to provide a factory for the RouteCollector
even tho the project does not need any routes.
When no router implementation is required by composer (and thus no factory is available for the RouteCollector
), mezzio crashes.
Laminas\ServiceManager\Exception\ServiceNotCreatedException: Service with name "Mezzio\Router\RouteCollector" could not be created. Reason: Missing dependency "Mezzio\Router\RouterInterface" for service "Mezzio\Router\RouteCollector"; please make sure it is registered in your container. Refer to the Mezzio\Router\RouteCollector class and/or its factory to determine what the service should return.
create-project
syntax as described within documentationcomposer remove mezzio/<router>
Until no route is provided to the application, nothing should happen.
When calling $app->route
(or those aliases which wrap that method) on an app without a RouteCollector
, an exception should be thrown.
We have to remove the alias RequestHandlerRunnerInterface
introduced in #110 and instead add it to the factories
.
This should also remove the RequestHandlerRunner
factory so that the RequestHandlerRunner
service is not available via the container anymore.
This introduces a BC break but will provide better capabilities for projects which want to decorate the runner.
This can go to 3.11.x indeed, but we should change this from aliases
to factories
in 4.x since RequestHandlerRunner
should not be requestable as a service from the container.
Since delegators
only work on services, this would be a BC break for sure and therefore I'd like to keep this in mind and thus dropping it here. Creating a new issue for 4.x from this comment to keep track.
Originally posted by @boesing in #110 (comment)
I have made routes and locale middleware with this Cookbook:
setting-locale-depending-routing-parameter.md
Now I wonder how I can pass the locale to Twig Extension which I use to create function {{ __('translate me') }}
Twig Extension is added in config/autoload/templates.global.php
like this:
return [
'dependencies' => [
'factories' => [
Twig_Environment::class => TwigEnvironmentFactory::class,
TemplateRendererInterface::class => TwigRendererFactory::class,
TranslationExtension::class => TranslationExtension::class,
],
],
'templates' => [
'extension' => 'html.twig',
],
'twig' => [
'cache_dir' => 'data/cache/twig',
'assets_url' => '/',
'assets_version' => null,
'extensions' => [
// extension service names or instances
TranslationExtension::class
],
'runtime_loaders' => [
// runtime loader names or instances
],
'globals' => [
// Variables to pass to all twig templates
],
'timezone' => 'Europe/Helsinki',
],
];
Originally posted by @back-2-95 at zendframework/zend-expressive#524
I'm having difficulty in parsing the $request->getParsedBody() for PUT/PATCH method - it only returns empty array.
I've enabled Body Parsing Middleware on my controller and it works with POST method.
https://docs.zendframework.com/zend-expressive/features/helpers/body-parse/
I'm trying to implement the REST Controller by Alejandro Celaya
Appreciate your input here. Thanks in advance.
Originally posted by @gabbydgab at zendframework/zend-expressive#371
Q | A |
---|---|
Version(s) | x.y.z |
Missing documentation for UrlHelper and reuse_result_params - no mention of reuse_result_params in current documentation.
I was looking to generate canonical url's for blog posts, using $this->serverUrl($this->url('blog.list')), the default behaviour is to re-use route params, so URLs were generating route params. Instead of generating '/blog/' I was getting '/blog/category/videos' for example.
I was able to generate the correct URLs using:
$this->serverUrl($this->url('blog.list', [], [], null, ['reuse_result_params' => false]))
Q | A |
---|---|
New Feature | yes |
RFC | no |
BC Break | no |
This issue aims to track the PHP 8.1 support addition to the project. Happy to help on this issue if it's necessary.
I just found this in the Expressive v3 project:
Document v3 changes
We need to document version 3. We can begin by creating a new v3 section of the docs based on latest v2, and modifying it to conform to what will actually release with v3.
We may want to consider splitting documentation into discrete repositories as well: pushing router and template renderer docs to the appropriate repositories, etc.
Especially the last part. I'm all in favor of this. I've seen too many notes in those projects that docs need to be updated in zend-expressive.
I'm opening the issue here so we can discuss it and I can close the expressive v3 project.
Originally posted by @geerteltink at zendframework/zend-expressive#594
I'm just playing around with expressive and zend-expressive-swoole and noticed that given the WhoopsErrorResponseGenerator is configured as ErrorResponseGenerator no response body will be sent. The default ErrorResponseGenerator however works fine.
Get response body generated by WhoopsErrorResponseGenerator
empty response on errors.
Originally posted by @iwyg at zendframework/zend-expressive#635
I believe "Content-Type" header is missing from the newly created response object when a 404 error is handled.
/src/Handler/NotFoundHandler.php
/**
* Generates a response using a template.
*
* Template will receive the current request via the "request" variable.
*/
private function generateTemplatedResponse(
TemplateRendererInterface $renderer,
ServerRequestInterface $request
) : ResponseInterface {
$response = ($this->responseFactory)()->withStatus(StatusCodeInterface::STATUS_NOT_FOUND);
$response->getBody()->write(
$renderer->render($this->template, ['request' => $request, 'layout' => $this->layout])
);
return $response;
}
Should be
/**
* Generates a response using a template.
*
* Template will receive the current request via the "request" variable.
*/
private function generateTemplatedResponse(
TemplateRendererInterface $renderer,
ServerRequestInterface $request
) : ResponseInterface {
$response = ($this->responseFactory)()
->withHeader('Content-Type', 'text/html')
->withStatus(StatusCodeInterface::STATUS_NOT_FOUND);
$response->getBody()->write(
$renderer->render($this->template, ['request' => $request, 'layout' => $this->layout])
);
return $response;
}
Originally posted by @cgaube at zendframework/zend-expressive#647
Q | A |
---|---|
Version(s) | 3.6.0 (likely earlier as well) |
Using ApplicationConfigInjectionDelegator
more than once (in multiple modules simultaneously) results results in a DuplicateRouteException. I found out about this after being contacted by a reader of Mezzio Essentials.
If you load the ApplicationConfigInjectionDelegator
in more than one module in a Mezzio project, such as in the example below, in the module's ConfigProvider
, then a DuplicateRouteException
is thrown.
public function getDependencies() : array
{
return [
// ... existing configuration
'delegators' => [
Application::class => [
ApplicationConfigInjectionDelegator::class,
],
],
];
}
This happens because ApplicationConfigInjectionDelegator::injectRoutesFromConfig
calls Mezzio\Application::route
, which ultimately throws a DuplicateRouteException
because it injectRoutesFromConfig
doesn't check if a route is in the routing table before attempting to add the existing routing table to the routing table. I don't know if this is the intended functionality, but thought that if a route was added, that it would overwrite an existing one.
Add the above code snippet in more than one module. You don't need to add any further configuration.
That if there are no, actual, duplicate routes, that no DuplicateRouteException
would be thrown.
Missing documents about building complex queries using like operators and others. Related topic https://discourse.laminas.dev/t/how-to-build-complex-queries-using-like-methods/1929/5
Q | A |
---|---|
Version(s) | x.y.z |
Should added to documentation.
There is no detailed information.
https://discourse.laminas.dev/t/how-to-build-complex-queries-using-like-methods/1929/5
Allow for mezzio to be run in a sub directory of the web server, out of the box, without need of configuration.
Q | A |
---|---|
New Feature | yes |
RFC | no |
BC Break | maybe |
When installing mezzio it does not work, out of the box, when running the website in a sub directory.
I found an article on "Cookbook Using Mezzio from a subdirectory", but that contains a series of actions and configurations.
My humble opinion is that it should work in a sub directory out of the box, like for example the Laravel, Symfony and Yii Framework does. Doing so would make it easier for first come users to adapt the framework since it has less restrictions on the development- and production environment in which it runs.
My reason for this opinion is mainly from an educational perspective. When doing education using Mezzio, one can not always expect the students to have their own servers. We for example are using a shared server where the students publish their websites. This can also be thought of as a usability perspective.
I can not say if this request would interfere with other existing features of mezzio. This was just my first experience of using mezzio. I did not see any notes on this requirement while I was browsing the documentation (however I might have missed it...).
composer create-project mezzio/mezzio-skeleton app
I access the website and gets this.
I then get this response.
I set up a fresh installation of Zend Expressive 3 through the composer create-project command, and selected the following options:
Without adjusting anything within the project and accessing the project in my local development environment I'm faced with the following error:
Fatal error: Uncaught Zend\ServiceManager\Exception\InvalidArgumentException: Zend\ServiceManager\AbstractPluginManager expects a ConfigInterface or ContainerInterface instance as the first argument; received Symfony\Component\DependencyInjection\ContainerBuilder in /var/www/zend-expressive-skeleton/vendor/zendframework/zend-servicemanager/src/AbstractPluginManager.php:59 Stack trace: #0 /var/www/zend-expressive-skeleton/vendor/zendframework/zend-view/src/HelperPluginManager.php(253): Zend\ServiceManager\AbstractPluginManager->__construct(Object(Symfony\Component\DependencyInjection\ContainerBuilder), Array) #1 /var/www/zend-expressive-skeleton/vendor/zendframework/zend-expressive-zendviewrenderer/src/HelperPluginManagerFactory.php(20): Zend\View\HelperPluginManager->__construct(Object(Symfony\Component\DependencyInjection\ContainerBuilder)) #2 /var/www/zend-expressive-skeleton/vendor/jsoumelidis/zend-sf-di-config/src/CallbackFactory.php(94): Zend\Expressive\ZendView\HelperPluginManagerFactory->__invoke(Object(Symfony\Com in /var/www/zend-expressive-skeleton/vendor/zendframework/zend-servicemanager/src/AbstractPluginManager.php on line 59
The problem seems to be that the application can not be instantiated as AbstractPluginManager (by extension by the HelperPluginManager) expects an instance of Interop\Container while Symfony\Component\DependencyInjection\ContainerBuilder does not implement this, but rather implements the Psr\Container\ContainerInterface directly.
This same problem also happens with both Pimple and Auryn, also selectable DI Containers. When I set up the project with the same modules, but select the default Zend DI Container it works just fine out of the box. I expected to see the same result when choosing the Symfony DI Container, Pimple, or Auryn in the configuration options, as the create project wizard leads me to believe these are supported DI Containers.
Some additional information, according to composer.lock:
As a side note: I do not fully understand why the AbstractPluginManager expects an instance of Interop\Container since this is an interface which has been deprecated over a year ago in favour of the PSR-11 Container interface. DI Containers like Symfony, Pimple and Auryn have clearly already caught up with this. As Zend Expressive 3 is so new I expect it to use the PSR-11 interface for the best compatibility with up to date DI Containers.
Originally posted by @olger01 at zendframework/zend-expressive#608
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.