Sharing Data
Using HTTP Request Object
With PSR-7 Http Message Interfaces it is possible to inject objects/values into the request object as attributes. These objects/values are then passed down to each middleware/route callback/handler/controller via the http request object.
Setting a Value
$app->addMiddleware(function ($request, $response, $next) { // pass the 'name' attribute to other middleware via the request object $request = $request->withAttribute('name', 'John Doe'); return $next($request, $response); });
Reading a Value
The request object exposes attributes passed along with it through the getAttribute()
method:
$app->addMiddleware(function ($request, $response, $next) { // get the 'name' from the request $name = $request->getAttribute('name'); $response->getBody()->write("Hello, $name"); return $next($request, $response); });
Using \BitFrame\Application
Object
\BitFrame\Application
can be used as a very basic DI container or simply to store and retrieve data that is shared between all middleware. This too is done via the request object, but internally the application stores and passes the \BitFrame\Data\ApplicationData
object.
Setting a Value
$app['name'] = 'John Doe'; $app->addMiddleware(function ($request, $response, $next) { // retrieve stored application data $data = $request->getAttribute(\BitFrame\Data\ApplicationData::class); // overwrite name $data['name'] = 'John Wick'; return $next($request, $response); });
Reading a Value
$app->addMiddleware(function ($request, $response, $next) { // retrieve stored application data $data = $request->getAttribute(\BitFrame\Data\ApplicationData::class); // output: "Hello, John Wick" $response->getBody()->write("Hello, {$data['name']}"); return $next($request, $response); });
Defaults
Internally BitFrame passes the following parameters via the request object:
'\BitFrame\Data\ApplicationData'
: Stores application data which can be shared between middlewares associated with the application instance.'\BitFrame\Router\RouteCollectionInterface'
: Stores routes added to the application instance such that the passed routes can be used by a router.
These default parameter keys are reserved for \BitFrame\Application
use.
Passing Arguments
Whether you're handling routes or adding a middleware, in addition to the methods explained earlier, you can inherit variables (for example, from the parent scope) into middleware/router methods/functions as explained below.
Named Classes
For named classes, you can simply pass arguments to the constructor at the time of instantiating an object instance.
Anonymous Class
If you're using an anonymous class, you can pass arguments through to their constructors like so:
use \Psr\Http\Message\ServerRequestInterface; use \Psr\Http\Message\ResponseInterface; use \Psr\Http\Server\RequestHandlerInterface; use \Psr\Http\Server\MiddlewareInterface; $name = 'John Doe'; // pass $name to constructor $app->addMiddleware(new class($name) implements MiddlewareInterface { private $name; public function __construct(string $name) { $this->name = $name; } public function process( ServerRequestInterface $request, RequestHandlerInterface $handler ): ResponseInterface { $response->getBody()->write("Hello, {$this->name}"); return $handler->handle($request); } });
Named Functions
You can use a variable defined in the global namespace inside a named function using the global
language construct.
Inheriting variables from the global scope is different from using variables from the parent scope. Global variables exist in the global scope, which is the same no matter what function is executing.
As an alternative to using global
, you could define an anonymous function assigned to a variable and use the use
language construct to inherit variables from the parent scope like so:
$name = 'John Doe'; $func = function ($request, $response, $next) use ($name) { $response->getBody()->write("Hello, $name"); return $next($request, $response); }; // pass $name to closure $app->addMiddleware($func);
Anonymous Functions
If you're using an anonymous function, you can pass arguments using the use
language construct like so:
$name = 'John Doe'; // pass $name to closure $app->addMiddleware(function ($request, $response, $next) use ($name) { $response->getBody()->write("Hello, $name"); return $next($request, $response); });
Remember to add a response emitter middleware to output the response.