在自己的类中访问Slim框架


Accessing Slim framework in your own classes

我使用的是Slim Framework版本3。

我遵循了创建应用程序的教程。其中一部分包括设置一个classes目录,您可以在其中放置自己的PHP类。

我不明白的是你怎么能在里面联系到Slim。例如,如果我有一个类src/classes/Users.php,并想使用瘦响应代码,例如

return $response->withStatus(302)->withHeader('Location', 'login');

显然,$response在这一点上是不可访问的。它似乎只在index.php中,每个回调都将其作为参数接收。

我必须传递一些东西给我自己的类的每个构造函数,或userequire语句在我的类?

我会说,当域层组件需要访问应用程序级组件时——这是一种代码气味。所以,考虑做其他事情,请求对象描述请求。请求包含一些数据,这些数据应该传递给User类,而不是请求对象本身。

如果您仍然希望在Users类中使用Request对象,只需将其作为参数传递,如下所示:

// in your routes
$app->post('users', function($request, $response) {
    $user = new User;
    $user->hydrateAndPersist($request); // there you pass it as argument
});
// in your user class
class User
{
    public function hydrateAndPersist(
        'Psr'Http'Message'ServerRequestInterface $request,
        'Psr'Http'Message'ResponseInterface $response // yes, you force yourself into injecting response object
    ) {
        // request is here, let's extract data from it
        $submittedData = $request->getParams();
        // terrible indeed, but this is just an example:
        foreach ($submittedData as $prop => $value) {
            $this->prop = $value;
        }
        $result = $this->save();
        return $response->withJson($result);
    }
}

然而,在这种情况下,您的User类与PSR-7请求和响应对象紧密耦合。有时耦合不是问题,但在您的情况下,User类属于域层(因为它描述了用户实体),而$request$response是应用层的组件。

尝试减少耦合:

$app->post('users', function($request, $response) {
    $submittedData = $request->getParams();
    $user = new User;
    $result = $user->hydrateAndPersist($submittedData);
    // response is already declared in this scope, let's "put" result of the operation into it
    $response = $response->withJson($result);
    return $response;
});
class User
{
    public function hydrateAndPersist(array $data) : bool
    {
        $result = false;
        foreach ($submittedData as $prop => $value) {
            $this->prop = $value;
        }
        $result = $this->save();
        return $result;
    }
}
看到好处了吗?User::hydrateAndPersist现在接受数组作为参数,它不知道$request$response。因此,它不依赖于HTTP (PSR-7描述了HTTP消息),它可以与任何东西一起工作。类分离,层分离,易于维护。

总结:你可以通过简单地将$request传递给User方法之一来访问User类中的$request对象。然而,这种糟糕的设计会降低代码的可维护性。