Call db in a normal function

Hello. I’m very new to Slim and PHP. I’m getting trouble with bring database connection out off $app function. But i get errors, i’ll provide my code below.

This is my project structure.

-public
—index.php
-src
—functions.php
—routes.php
-vendor

My routes.php

$app->post('/search/[{phone}]', function($request, $response, $args) use ($app){
$token = $request->getParam('token');
$phone = $args['phone'];

if (isTokenValid($app, $token)){
	return $this->response->withJson("valid");
}
return $this->response->withJson("invalid");

});

My function in functions.php

function isTokenValid($app, $token){
$sql = 'SELECT id FROM users WHERE token = :token';
$s = $app->db->prepare($sql);
$s->bindParam(':token', $token);
if ($s->execute()){
    if($sth->rowCount() > 0){
        return true;
    }
}
return false;

}

But i get
Call to a member function prepare() on null

How to fix it? And how to access $app globally instead of passing as a variable?

@HieuTruong You would want to create a container for your database connection and pass that object in as the function parameter rather than app:

$c = $app->getContainer();

$c['db'] = function() {
	return new DB($host,$user,$pass,$name);
};

$app->post('/search/[{phone}]', function($request, $response, $args) use ($c) {
	$token = $request->getParam('token');
	$phone = $args['phone'];

	if (isTokenValid($c->db, $token)){
		return $response->withJson("valid");
	}
	return $response->withJson("invalid");

});


function isTokenValid($db, $token){
	$sql = 'SELECT id FROM users WHERE token = :token';
	$s = $db->prepare($sql);
	$s->bindParam(':token', $token);
	if ($s->execute()){
	    if($sth->rowCount() > 0){
	        return true;
	    }
	}
	return false;
}

Containers help make your own code reusable, testable and independent from the Slim app object.

Also, rather than $this->response, you can just use $response.

https://www.slimframework.com/docs/concepts/di.html