我正在使用Slim Framework第3版。
我在创建应用时遵循了tutorial。部分原因是设置一个classes
目录,您可以在其中放置自己的PHP类。
我无法理解的是如何在这些内容中访问Slim。例如,如果我有一个类src/classes/Users.php
并且想要使用Slim Response代码,例如
return $response->withStatus(302)->withHeader('Location', 'login');
显然,此时无法访问$response
。它似乎只在index.php
中,每个回调都将其作为参数接收。
我是否必须将某些内容传递给我自己的类的每个构造函数,或者我的类中的use
或require
语句?
答案 0 :(得分:1)
我说当域层组件需要访问应用程序级组件时 - 这是代码味道。因此,考虑做其他事情,请求对象描述请求。请求包含一些数据,并且该数据应该传递给您的User
类,而不是请求对象本身。
如果您仍希望在Request
类中使用Users
对象,只需将其作为参数传递,如下所示:
// 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
方法之一即可访问$request
课程中的User
个对象。但是,这种设计很差,会降低代码的可维护性。