Code Monkey home page Code Monkey logo

zend-expressive's Introduction

zend-expressive

Repository abandoned 2019-12-31

This repository has moved to mezzio/mezzio.

Build Status Coverage Status

Develop PSR-7 middleware applications in minutes!

zend-expressive builds on zend-stratigility to provide a minimalist PSR-7 middleware framework for PHP, with the following features:

Installation

We provide two ways to install Expressive, both using Composer: via our skeleton project and installer, or manually.

Using the skeleton + installer

The simplest way to install and get started is using the skeleton project, which includes installer scripts for choosing a router, dependency injection container, and optionally a template renderer and/or error handler. The skeleton also provides configuration for officially supported dependencies.

To use the skeleton, use Composer's create-project command:

$ composer create-project zendframework/zend-expressive-skeleton <project dir>

This will prompt you through choosing your dependencies, and then create and install the project in the <project dir> (omitting the <project dir> will create and install in a zend-expressive-skeleton/ directory).

Manual Composer installation

You can install Expressive standalone using Composer:

$ composer require zendframework/zend-expressive

However, at this point, Expressive is not usable, as you need to supply minimally:

  • a router.
  • a dependency injection container.

We currently support and provide the following routing integrations:

  • Aura.Router: composer require zendframework/zend-expressive-aurarouter
  • FastRoute: composer require zendframework/zend-expressive-fastroute
  • zend-router: composer require zendframework/zend-expressive-zendrouter

We recommend using a dependency injection container, and typehint against PSR-11 Container. We can recommend the following implementations:

  • zend-servicemanager: composer require zendframework/zend-servicemanager
  • Pimple (see docs for more details): composer require zendframework/zend-pimple-config
  • Aura.Di (see docs for more details): composer require zendframework/zend-auradi-config

Additionally, you may optionally want to install a template renderer implementation, and/or an error handling integration. These are covered in the documentation.

Documentation

Documentation is in the doc tree, and can be compiled using mkdocs:

$ mkdocs build

Additionally, public-facing, browseable documentation is available at https://docs.zendframework.com/zend-expressive/

zend-expressive's People

Contributors

acelaya avatar bakura10 avatar belgattitude avatar danizord avatar devgkz avatar ezimuel avatar froschdesign avatar geerteltink avatar harikt avatar koopzington avatar kynx avatar localheinz avatar maks3w avatar michaelmoussa avatar michalbundyra avatar moderndeveloperllc avatar mtymek avatar mwillbanks avatar ocramius avatar ojhaujjwal avatar orkin avatar pine3ree avatar samsonasik avatar samuel20miglia avatar settermjd avatar snapshotpl avatar spiffyjr avatar weierophinney avatar xerkus avatar zf2timo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

zend-expressive's Issues

Route with optional params throws errors with Zend Router and View

I am using Zend\Expressive with the Zend View and the Zend Router and have some problems with an optional route param.

[
    'name' => 'voting',
    'path' => '/voting[/:pos[/:neg]]',
    'middleware' => Application\Action\VotingAction::class,
    'allowed_methods' => ['GET'],
],

The routing works fine. But the usage of the URL view helper does not. It forces me to always path values for both optional params.

<?php echo $this->url('voting', array('pos' => '1', 'neg' => '1')) ?>

But if I pass no values for the optional params, I get a Zend\Mvc\Router\Exception\InvalidArgumentException with message Missing parameter "pos".

Is this a bug or is my route config wrong?

How to deal with i18n?

Localizing application is a pretty common task. How should work in Zend Expressive app?

Usually, application will detect user's language (by reading some cookies, or by parsing user agent string), and store it inside some object ("translator"). This introduces global state, which is not desired in middleware app - it gives similar problems as passing RouteResult around. On the other hand, having single, global translator is super handy - it can be injected into view helpers, or services dealing with text output.
So, what would be the preferred way of handling this inside Expressive app? I can imagine writing middleware that detects language and passes it to inner layers, but what to do next? Where to create translator, and how to tell view helpers to use it?

Render JSON using a template renderer?

Hi :),

I've been trying to install a template library (in this case, Plates) in order to use it for rendering JSON (so I can separate my controller from my rendering code).

My middleware's invoke method therefore does something like that:

return new JsonResponse($this->template->render('app::my-resource', ['resource' => $object]));

My template code is a simple file that looks like that:

return [
  'foo' => $object->getFoo()
]

I verified and the template is properly called, so my configuration is right. However the fact that it extract the content using ob_start makes me think that I'm using it the wrong way.

What is the recommended way to achieve that? I'm liking the idea of rendering my resources in a separate file, so I can have access to plates features, as well as being able to render URLs and so on...

Thanks!

Configuration for Whoops error handler

When going through the docs I've come up with a basic configuration. The 404 pages do render as expected but the error/error is empty.

return [
    'dependencies' => [
        'invokables' => [
            'Zend\Expressive\Whoops' => Whoops\Run::class,
            'Zend\Expressive\WhoopsPageHandler' => Whoops\Handler\PrettyPageHandler::class,
        ],
        'factories' => [
            'Zend\Expressive\FinalHandler' => Zend\Expressive\Container\WhoopsErrorHandlerFactory::class,
        ],
    ],

    'whoops' => [
        'json_exceptions' => [
            'display'    => true,
            'show_trace' => true,
            'ajax_only'  => true,
        ],
    ],

    'zend-expressive' => [
        'error_handler' => [
            'template_404'   => 'error::404',
            'template_error' => 'error::error',
        ],
    ],
];

When using the TemplatedErrorHandlerFactory it does work as expected (in combination with Twig):

'Zend\Expressive\FinalHandler' => Zend\Expressive\Container\TemplatedErrorHandlerFactory::class,

This is how the error is triggered inside middleware:

return $next($request, $response, new \Exception('Oh no!'));

Did I miss something in the configuration?

Best practices over how to store request attributes?

Hi everyone,

I'm not sure if this fit more Zend\Expressive or Zend\Stratigility or Zend\Diactoros.

I find the pre_routing very interesting, as it allows to attach a middleware that could do various authentication work, and returning early if authentication does not match.

Actually, while refactoring ZfrOAuth2 to take advantage of middlewares, here is how it worked: https://github.com/zf-fr/zfr-oauth2-server/blob/middleware/src/Server/ResourceServerMiddleware.php#L57

As you can see, someone can attach this middleware, that will automatically inspecting the incomign request, doing the OAuth token check, and return a 401 if there are error. Then, it sets the token as part of the request: https://github.com/zf-fr/zfr-oauth2-server/blob/middleware/src/Server/ResourceServerMiddleware.php#L66

Next middlewares could therefore inspect the request, find the oauth_token and do more advanced validation. This actually completely remove the need for Zend\Authentication.

The issue is the naming. Should we encourage, as part of Expressive\Stratigility, best practices over how people should store attributes in order to not conflict with router attributes?

I thought of a simple scheme, like package:variable, in this case it would be zfr_oauth2:oauth_token.

What do oyu think?

Config factory typo in docs

Looks like there is a quick typo in /doc/book/usage-examples.md where the config globbing examples are. The example uses \Zend\Config\Config::fromFiles() but it appears that method is actually in the factory class - \Zend\Config\Factory::fromFiles(). Cheers!

Use PSR7 interfaces in match

Hi,

I've just had a quick look at the code, and it seems the match could accept a ServerRequestInterface instead (https://github.com/zendframework/zend-expressive/blob/master/src/Router/RouterInterface.php#L19). That would make things easier and a great way to take advantage of those interfaces from start to end. It seems that next version of Aura.Router that you rely on supports this directly: https://github.com/auraphp/Aura.Router/blob/3.x/src/Matcher.php#L110

For adapter that do not support it (like FastRoute), a transformation should be done before passing the info.

Throw exception instead silently return for type checks

Adding parameters to templates before render-time

Right now we've only got one chance to add parameters to templates, via render($name, $params).

However it'd be really useful to add data in stages. So a piped middleware could be responsible for populating standard stuff like the current user's name, then the routed middleware adds the stuff it's responsible for.

Plates offers addData() that does just this. From what I can tell it's possible in Zend View as well. Twig doesn't, but it could be faked easily enough by storing the data in the Twig bridge until render time.

Anyone else think this is good idea?

skeleton project

while this component is in active development, I think we can start have 1 skeleton that people can try and to make sure every feature is working properly.

Support route-specific middleware pipeline via configuration?

When defining routes, we can specify the middleware to be executed in the configuration:

return [
    'routes' => [
        [
            'name' => 'foo',
            'path' => '/foo/{id}',
            'middleware' => FooMiddleware::class,
            'allowed_methods' => ['GET'],
        ]
    ]
];

I have a use case where I'd like to service a route by chaining a few different middlewares. They are application-specific middlewares that are shareable among resources (think user input validation, entity retrieval, and things of that nature), but I can only specify a single middleware in this configuration. I considered using the pre_routing and post_routing configuration pipelines, but they execute too early or too late, respectively, and I only need them to execute for this specific route, not for every request.

I managed to implement what I wanted by having my FooMiddleware actually be a middleware pipe:

class FooMiddlewareFactory
{
    public function __invoke(ContainerInterface $container)
    {
        $middleware = new MiddlewarePipe();
        $middleware->pipe($container->get(SomeMiddleware::class));
        $middleware->pipe($container->get(SomeOtherMiddleware::class));
        $middleware->pipe($container->get(YetAnotherMiddleware::class));

        return $middleware;
    }
}

Since a MiddlewarePipe is itself middleware, Expressive will accept it as the target middleware for this route, and execute the middlewares in the proper sequence.

However, it'd be much more convenient to be able to create this pipeline in the configuration rather than needing to create a factory to do it programmatically:

return [
    'routes' => [
        [
            'name' => 'foo',
            'path' => '/foo/{id}',
            'middleware' => [
                SomeMiddleware::class,
                SomeOtherMiddleware::class,
                YetAnotherMiddleware::class,
            ],
            'allowed_methods' => ['GET'],
        ]
    ]
];

This is currently not allowed because the value of middleware must be callable.

  1. Is there a better way to do what I'm trying to do already via configuration?
  2. Is the inability to create route-specific pipelines like above via configuration an oversight, or intentional?
  3. If it's an oversight, would you accept a backwards-compatible patch to get this into 1.0.0?

Dispatcher middleware?

I would like to propose adding additional layer to execution stack - dispatcher.

Currently routing process passes execution directly to matched middleware (which acts as "controller" in MVC app). In my proposal, router injects routing result into an attribute of request object, which is later used by dispatcher to locate and execute the controller.
With this setup you gain a lot of flexibility - for example you could build a dispatcher that accepts returning ViewModel from controller, emulating ZF2's MVC.

See following code:

// router
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next) 
{
    $request = $request->withAttribute('route_match', $this->router->match($request));
    return $next($request, $response);
}

// dispatcher
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next) 
{
    if ($match = $request->getAttribute('route_match')) {
    $controller = $this->container->get($match->getControllerName());

    $result = $controller($request, $response);

        // got response - return it
    if ($result instanceof ResponseInterface) {
        return $result;
    }

        // got array - convert it to ViewModel and proceed
    if (is_array($result)) {
        $result = new ViewModel($result);
    }

         // got view model - render it and inject output into response
    if ($result instanceof ViewModel) {
        return $this->renderViewModelIntoResponse($response, $result);
    }
    }

    return $next($request, $response);
}

Does it fit into scope of zend-expressive?

Container Docs

Hi,

I was trying to make use of Aura.Di v3 which satisfies container-interop .

Going through the docs of pimple https://github.com/zendframework/zend-expressive/blob/master/doc/book/container/pimple.md and zend-service manager I guess there is something wrong.

Eg : In Pimple.

$container['Zend\Expressive\Application'] = new Container\ApplicationFactory;
// ... more code
$app = $container->get('Zend\Expressive\Application');
$app->run();

See getting the service Zend\Expressive\Application it will actually gives you an object of Zend\Expressive\Container\ApplicationFactory , and inorder to get the object of Zend\Expressive\Application you need to pass the container itself.

$container['Zend\Expressive\Application'] = new Container\ApplicationFactory;
// ... more code
$app = $container->get('Zend\Expressive\Application');
$app = $app($container);
$app->run();

Interested to hear whether it was a typo or I am understanding it wrongly.

Thank you.

405 Methods not Allowed does not work

Assuming the following config:

'services' => [
        'config' => [
            'routes' => [
                [
                    'path' => '/',
                    'middleware' => 'Application\HelloWorld',
                    'allowed_methods' => [ 'POST' ],
                ],
            ],
        ]
    ],

Hitting "/" returns a 404, while expected result is 405. It seems the logic handled for "isMethodFailure" is wrong.

Debug toolbar conversation

This was from thread #180 . Just wanted to make another thread so the discussion don't get lost

harikt : There need some sort of way to debug things easily. Eg : Middleware when is it called, is it registered etc something like the symfony debug bar which helps to show the event handlers registered / called. ( feature )

mwop : something like the symfony debug bar

That's what Z-Ray is for… Seriously, though, there are lot's of such debug toolbars out there. It sucks that most are not generic, and need to be built for the specific project. That's one thing I like about Z-Ray; generic, and pluggable. We're already working on a PSR-7 plugin for it, and will likely build one around middleware signatures (though that one's far harder, as most are not implementing an interface, so we have to look at arguments).

Renaming "Template" to "TemplateRenderer" or "TemplateEngine"?

Maybe it's just me, but I think the current naming sounds a bit confusing.

The TemplateInterface currently exposes the public method render($name, $params = []), but a template does not render stuff, it actually gets rendered by a renderer or template engine.

Should we rename TemplateInterface to TemplateEngineInterface or TemplateRendererInterface?

AuraRouter, setConfig() on NOTES.md

Hi

I can't find a method named setConfig on Class AuraRouter, on NOTES.md at the part "Hello world, container version, all services defined". I can't find how to fix this :(

Regards

Add Album tutorial to docs

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?

multiple routes with same path

Hi, I tried to do this

$app->get('/users', 'Users::FetchAll');
$app->post('/users', 'Users::Create');

but the last route overwrites the first one because in https://github.com/zendframework/zend-expressive/blob/master/src/Router/Aura.php#L65 it's using the path as the route name

I'm currently using Aura.Router in other project and I give each route a different name to be able to call $router->generate($routeName, $params), I don't know if you would be interested in this, but at least if we use a combination of path+method as route name it will fix the problem

register to packagist

currently, I can't get zendframework/zend-expressive in packagist for testing it.

allowed_methods doesn't work

I tried using :

    'routes' => [
        [
            'path' => '/',
            'middleware' => 'Application\HelloWorld',
            'allowed_methods' => [ 'GET' ],
        ],
   ],

When I tried to call "/" via POST method, it get blank page with 200 status.

[Cookbook] Config best practices

Hi,

We should add a note about what would be the best way to organize config files at scale (with .local/.global explanation, if config files should better be split by concerns - routes / services / ... - or by middleware/modules)... and so on.

It's a bit confusing, because of the lack of modules and merging of config (as of today).

Injecting container into middleware?

There are many types of services that may be useful to have in multiple middleware classes - database connectivity for instance. If I am using a Configuration-Driven Container, it would appear that I would want to make my middleware classes factories instead of invokables so I could inject the container on __construct() and have the standard public function __invoke($req, $res, $next) for when the middleware gets piped.

Am I just eating the penalty for non lazy-loading because I want the container to be available? Or am I thinking about this in the wrong way?

pipe fails to continue with no matched route

The problem occurs when I try to return add a JsonResponse to the $next callable in pre_routing. Having something in post_routing doesn't really make any difference but I was expecting the request to reach a middleware there.

https://gist.github.com/fabiocarneiro/81ea4e1eb0a52b8ded12

2015/10/05 15:32:17 [error] 15#0: *320 FastCGI sent in stderr: "PHP message: PHP Catchable fatal error:  Argument 4 passed to Zend\Stratigility\Dispatch::__invoke() must be an instance of Zend\Stratigility\Http\Response, instance of Zend\Diactoros\Response\JsonResponse given, called in /usr/share/nginx/html/vendor/zendframework/zend-stratigility/src/Next.php on line 113 and defined in /usr/share/nginx/html/vendor/zendframework/zend-stratigility/src/Dispatch.php on line 53" while reading response header from upstream, client: 172.17.42.1, server: , request: "POST /login HTTP/1.1", upstream: "fastcgi://unix:/var/run/php5-fpm.sock:", host: "localhost", referrer: "http://localhost:63342/frontend/index.html"

FinalHandler trying to display exceptions is freezing the system

Hi,
I am not sure if this should be called as a bug.

But when there is an exception occured and if the exception is happening from di, the system is getting freezed trying to dump all the di values and configurations :-( .

Probably there need a better way to handle the exception ?

Stdlib dependency

Hi :),

Zend/Stdlib is marked as a require dependency but I couldn't found a place where it is actually used.

Exhausted memory when uploading files

I'm experiencing this error from time to time on an application that I'm developing with Expressive.
Sometimes when I try to upload a file I get this Fatal error.

[Mon Oct 19 23:08:17.670338 2015] [:error] [pid 5435] [client 127.0.0.1:43546] PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 140367508812784 bytes) in Unknown on line 0, referer: http://foobar.local

I've seen it both in apache's log and by using the PHP's built-in web server, but I'm not sure what's causing it.

What I'm doing is getting the uploaded files from the request (usually just a small file, from 50 to 300 Kb), and parsing them to array in order to be able to validate them with a Zend\InputFilter\FileInput object.
This is how my parsing method looks like:

public static function uploadedFileToArray(UploadedFileInterface $uploadedFile)
{
    return [
        'tmp_name' => $uploadedFile->getStream()->getMetadata('uri'),
        'name' => $uploadedFile->getClientFilename(),
        'type' => $uploadedFile->getClientMediaType(),
        'size' => $uploadedFile->getSize(),
        'error' => $uploadedFile->getError()
    ];
}

The FileInput has just one Zend\Validator\File\IsImage validator.
If I comment the $inputFilter->isValid() call, then the file is properly uploaded and the error is not produced.
I'm not sure if it has something to do with the way the stream is handled in the Zend\Diactoros\UploadedFile object, that grows too much for some reason.

Renaming route to router?

Hi !

While reading some part of the source code, I've felt a bit confused by the naming of the various router adapters.

Actually, it seems that the various adapters are actually router (a list of route, and can be matched), but all the adapter are actually named "AuraRoutE", "FastRoutE", "Zf2RoutE". That's a bit confusing because in my head, a route is... well, a single route.

I'd suggest therefore renaming:

  • AuraRoute => AuraRouter
  • FastRoute => FastRouter
  • Zf2 => Zf2Router (for consistency)

I know a version has already been tagged, but I think this would be a sane change to reduce confusness (and I really was ^^).

Templating is not working out of the box with the default classes

As mentioned on IRC, I can't get any of the template engines working with this configuration:

'invokables' => [
    Zend\Expressive\Template\TemplateInterface::class => Zend\Expressive\Template\<engine-name>::class,
],
'factories' => [
    'Zend\Expressive\FinalHandler' => Zend\Expressive\Container\TemplatedErrorHandlerFactory::class,
],

Mostly it's issues with finding the templates I think. The easiest way was to create factories for Twig, zend-view and plates and add a unified configuration. With factories I'm also able to inject extensions easily to add basic function like constructing named routes.

My solutions are here: https://github.com/xtreamwayz/expressive-composer-installer/tree/master/src/App/Template

I had a hard time figuring out how to get zend-view working. It heavily depends on other components from zend framework. I don't think it is working with other containers than zend-servicemanager, but I can't test that until I've got the other containers working. Besides that some plugins need to be hooked up with other services, like Zend\View\Helper\Url with the router.

Some zend-view plugins are not working

Some plugins are missing dependencies. Like the Zend\View\Helper\Url needs a router to resolve named routes.

I have looked into this and it does depend on Zend\ServiceManager and Zend\Mvc\Router. The easiest way would be to somehow overwrite the plugin with a custom plugin and inject the Container and Router. But looking at the code this might be hard to achieve.

Increase interoperability by using vendor/package config keys

Some config keys have a vendor and/or package name like whoops or zend-expressive and some config keys have an independent name like templates or routes. There exists a discussion #155 about config structure, but it seems to be only a Cookbook.

Is there a special reason why not every config key has a vendor/package name?

What is if we add module support like ZF2 has and each module can have it's own template renderer and it's own router or it's own DI container configuration? The template configuration for example, has for each template engine it's own option keys, but uses the same main config key name.

I think the following config structure makes more sense, because there is no way to support different libraries with one config structure. With this structure, it is also possible to switch between implementations by changing the factories or to use different renderer, DI or router in one application.

return [
    // vendor name
    'twig' => [
        // package name
        'view' => [ /* options */ ],
    ],
     // vendor name
    'zend' => [
        // package name
        'view' => [ /* options */ ],
        // package name
        'service-manager' => [ /* options */ ],
        // package name
        'expressive' => [ /* options */ ],
        ],
    ],
];

Maybe the complexity is higher, but it's better to understand for the user and it's more flexible. It exists a PSR config proposal which defines the config structure. The config structure is important.

Config autoload fails when splitting routes in different files

This issue is either for zend-expressive or zend-expressive-skeleton, depending on the solution. However issues are not yet activated for the skeleton project.

The problem arises when you split routes into different files. E.g. you have a routes.admin.global.php with this:

    'routes' => [
        [
            'name' => 'admin.dashboard',
            'path' => '/admin/dashboard',
            'middleware' => App\Admin\Dashboard\Index::class,
            'allowed_methods' => ['GET'],
        ],
    ],

and a routes.api.global.php with this:

    'routes' => [
        [
            'name' => 'api',
            'path' => '/api/{resource:[a-z]+}[/{resourceId:\d+}[/{relation:[a-z]+}[/{relationId:\d+}]]]',
            'middleware' => App\Api\ApiMiddleware::class,
            'allowed_methods' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'],
        ],
    ],

When merging the two files they overwrite each other because they have the same key. There are two possible solutions.

  1. Use the name as a key:

    'routes' => [
        'api' => [
            'path' => '/api/{resource:[a-z]+}[/{resourceId:\d+}[/{relation:[a-z]+}[/{relationId:\d+}]]]',
            'middleware' => App\Api\ApiMiddleware::class,
            'allowed_methods' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'],
        ],
    ],
  2. Use zend-stdlib in config/config.php in the skeleton. The config.php file looks then like this:

    use Zend\Stdlib\ArrayUtils;
    use Zend\Stdlib\Glob;
    
    $cachedConfigFile = 'data/cache/app_config.php';
    
    $config = [];
    if (is_file($cachedConfigFile)) {
        // Try to load the cached config
        $config = json_decode(file_get_contents($cachedConfigFile), true);
    } else {
        foreach (Glob::glob('config/autoload/{{,*.}global,{,*.}local}.php', Glob::GLOB_BRACE) as $file) {
            $config = ArrayUtils::merge($config, include $file);
        }
    
        // Cache config if enabled
        if (isset($config['config_cache_enabled']) && $config['config_cache_enabled'] === true) {
            file_put_contents($cachedConfigFile, json_encode($config));
        }
    }
    
    // Return an ArrayObject so we can inject the config as a service in Aura.Di
    // and still use array checks like ``is_array``.
    return new \ArrayObject($config, \ArrayObject::ARRAY_AS_PROPS);

Personally I use option 2 anyway, but this adds an extra dependency on zend-stdlib.

Middleware not getting called

Hi,

I am working on expressive with Aura.Di . Added a middleware basically as simple as

<?php
namespace App\Middleware;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

class IsAuthenticated
{   
    public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next = null)
    {       
        var_dump("Hello World");
        exit;
    }
}

and this middleware is added in the config/autoload

// in middleware-pipeline.global
return [    
    'middleware_pipeline' => [        
        'pre_routing' => [
            [             
                'middleware' => 'App\Middleware\IsAuthenticated',             
                'error' => true,
            ],            
        ],
        'post_routing' => [           
        ],
    ],
];

The service is also defined in the container. For some reason the class is never called.

I tried a few other variations like

$app->pipe('App\Middleware\IsAuthenticated');
$app->run()
$app->pipe($di->get('App\Middleware\IsAuthenticated'));
$app->run()
$app->pipe('/', $di->get('App\Middleware\IsAuthenticated'));
$app->run()

But didn't get the expected result Hello World dumped.

Using $this in route clousure?

I notice that we cannot $this like in Slim 3 in the current version of Expressive

$app->route('/hello/{name}', function ($request, $response, $next) {
    $container = $this->getContainer();
    $name = $request->getAttribute('name');
    $response->getBody()->write('Hello, ' . $name);
    return $response;
});

I will get an an error for that above. I have to pass in $app via use which is not as neat as Slim:

$app->route('/hello/{name}', function ($request, $response, $next)  use ($app) {
    $container = $app->getContainer();
    $name = $request->getAttribute('name');
    $response->getBody()->write('Hello, ' . $name);
    return $response;
});

Would you make that possible in the future versions?

Installation fails for standalone usage

Following the guide here http://zend-expressive.readthedocs.org/en/stable/quick-start/. It fails to install with composer:

composer require zendframework/zend-expressive zendframework/zend-expressive-fastroute zendframework/zend-servicemanager

Error:

C:\...\test>composer require zendfra
mework/zend-expressive zendframework/zend-expressive-fastroute zendframework/zen
d-servicemanager
Using version ^0.5.3 for zendframework/zend-expressive
Using version ^0.2.0 for zendframework/zend-expressive-fastroute
Using version ^2.6 for zendframework/zend-servicemanager
./composer.json has been created
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Installation request for zendframework/zend-expressive-fastroute ^0.2.0 ->
 satisfiable by zendframework/zend-expressive-fastroute[0.2.0].
    - zendframework/zend-expressive-fastroute 0.2.0 requires zendframework/zend-
expressive ^1.0@rc -> no matching package found.

Potential causes:
 - A typo in the package name
 - The package is not available in a stable-enough version according to your min
imum-stability setting
   see <https://groups.google.com/d/topic/composer-dev/_g3ASeIFlrc/discussion> f
or more details.

Read <https://getcomposer.org/doc/articles/troubleshooting.md> for further commo
n problems.

Installation failed, deleting ./composer.json.

RouteResult in Router

Why is the RouteResult not saved in the Router for later usage to check the route name used etc ?

Integration with Aura.View

Hi,

Was trying to integrate Aura.View. A few things I noticed are aura uses 2 step view and expects layout and view to be passed. And the current render only accepts view name and params.

public function render($name, $params = []);

I am having an idea of pushing something like render('view::layout', $params) same for many of the functionalities. Do you have any thoughts on this ? Or do you think you guys can keep an optional $layout = null in the render ?

Expressive modules

I like the idea of zf2 modules. It would be useful to have this functionality in expressive application by default. Ideally before v. 1.0 release comes.

Don't recommend pimple-interop

mouf/pimple-interop is based on Pimple 1. The Pimple project is currently on version 3.0.2. We probably don't want to be recommending Pimple 1.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.