Slim Framework - 如何在正常函数中查询db

I'm very new to PHP and Slim Framework which helps creating APIs. Everything is ok If i query db inside $app->post or get. But I want to separate it to normal function. It will help when I need to use it later in other APIs.

I tried to call this

$app->get('/search/[{phone}]', function($request, $response, $args) use ($app){
    $token = $response->getHeader('token');
    // $phone = $args['phone'];
    if (isTokenValid($token)){
        return $this->response->withJson("valid");
    }
    return $this->response->withJson("invalid");

});

My isTokenValid() function

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

But I get 500 Internal Server Error

Type: Error
Message: Call to a member function prepare() on null
File: /Applications/MAMP/htdocs/aigoido/src/functions.php
Line: 25

How to call it outside $app? Thanks.

Pass $app to your function as parameter. The function has it own context so $app is not available without that.

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

You want to create a dependency injection container for your database connection and pass that object in as the function parameter rather than app object. This makes the db connection reusable throughout your app.

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

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

$c = $app->getContainer();

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

$app->post('/search/[{phone}]', function($request, $response, $args) use ($c) {
     $token = $response->getHeader('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;
}