How do I create a middleware for database connection


#1

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.


#2

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());


#3

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.


#4

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.


#5

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?


#6

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.