Hello Guys,
I am new to the Slim framework.
I am trying to create a middleware for database connection that will be used for every route in my app.
My goal is: for every API call, the middleware creates a database connection, calls the NEXT function (passing the connection as a parameter) when the Next function finishes executing, the middleware closes the connection.
My challenge is how to pass the connection to the Next function. I am trying to include it as part of the request object but can’t seem to figure out the proper way to do that.
This my coode snippet:
$connection = function ($request, $response, $next) {
$request->getBody()->db = db_connect(); //db_connect() returns a database connection
$response = $next($request, $response);
$request->connection = null;
return $response;
};
$app->add($connection);
$app->group(’/api’, function () use ($app) {
$app->post('/login', 'login');
$app->post('/logout', 'logout');
});
function login($request, $response) {
$param = json_decode($request->getBody());
$db = $param->db;
$email = $param->email;
$password = $param->password;
…
}
This is the error message I get:
Undefined property: stdClass::$db in …
Please I need help the right approach to take.
Why do’t you use the DI-container for creating/storing the connection?
If you still want to do it in middleware, you can use request attributes, e.g.
$request = $request->withAttribute(‘db’, db_connect());
Thanks tstadler. Shortly after I posted the problem, I tried the
request->withAttribute method and it worked.
I’m totally new to using php frameworks and Slim is the first I’m working
with. I’m yet to study and understand containers but I like doing things
the best way possible.
Pls if you think using DI-container is better, can you help me with a code
that will achieve that.
Thanks.
Pleas have a look at https://www.slimframework.com/docs/concepts/di.html for the DI-Conecpt of slim.
Basically you need to do something like
$container = $app->getContainer();
$container[‘db’] = function() {
return db_connect();
};
to tell the DI container about the DB-connection.
Thanks, Tstadler. I really appreciate.
After creating $container[‘db’] as the db connection, please how do I access it from inside another function?
And what are the advantages of this container method over using middleware?
You need to inject it your function/class as a dependency, e.g.
$container = $app->getContainer();
$container[‘db’] = function() {
return db_connect();
};
class MyController {
private $db;
public function __construct($db) {
$this->db = $db;
}
public function index($request, $response, $args) {
return $response;
}
}
$container[‘myController’] = function($c) {
return new MyController($c->get(‘db’));
};
$app->get(’/’, ‘MyController:index’);
Also please see https://akrabat.com/di-factories-for-slim-controllers/ for a example. The main advantages of the DI approach are discussed in the comments.