0

我正在尝试使用苗条框架版本 3 为 API 设置一个项目,我不知道是谁制作了 PSR-7 并将响应对象标记为不可变,我看不出有任何用处(恕我直言。请解释一下如果我错了)。苗条的时候事情要容易得多 2。现在我在很长一段时间后又恢复苗条了。

我有一个发布方法的路线,我正在获取数据并将其保存到数据库中,并且我正在尝试发送 201 作为响应代码。所有示例和文档都向您展示了如何更改 index.php 文件本身中的响应代码,但我试图从响应构建器中更改它,我尝试使用工厂模式来提供不同的响应。问题是无论我从响应构建器类调用什么函数,响应代码始终保持 200。我尝试了许多论坛和不同的瘦身方式,但仍然无法做到这一点。我几乎决定放弃 PSR 7 路由器实施并实施我自己的路由解决方案。但我记得不要重新发明轮子,所以我来到这里作为最后的尝试。下面是代码。

路线定义

$app->post('/users', function(ServerRequestInterface $req, ResponseInterface $res) {
    $data = $req->getParsedBody();
    $model = new \Apex\Models\User(ApexDB::getInstance());
    $jsonBuilder = ApexResponse::getBuilder('JSON', $res);
    $control = new \Apex\Controllers\User($model, $jsonBuilder);
    $control->create($data);

});

控制器方法(抽象我只是设置它)

public function create($data) {
        if($this->model->save($data)) {
            $this->response->build($data,201);
        } else {
            $this->response->build('error',400);
        }
    }

JSON 构建器

class JSONBuilder implements Response
{
    public $response;

    public function __construct($response)
    {
        $this->response = $response;
    }

    public function build($data, $status)
    {
        $response = $this->response->withJSON($data,$status);
        return $response;
    }
}

谁能指出我正确的方向?

4

1 回答 1

2

PSR-7 决定为请求和响应使用不可变对象记录在为什么值对象?Meta 文档的部分。

使用 Slim 3,您必须始终Response从控制器方法返回一个实例。

$app->post('/users', function(ServerRequestInterface $req, ResponseInterface $res) {
    $data = $req->getParsedBody();
    $model = new \Apex\Models\User(ApexDB::getInstance());
    $jsonBuilder = ApexResponse::getBuilder('JSON', $res);
    $control = new \Apex\Controllers\User($model, $jsonBuilder);

    return $control->create($data);
});

然后您的create方法还需要返回$response

public function create($data) {
    if($this->model->save($data)) {
        $this->response->build($data,201);
    } else {
        $this->response->build('error',400);
    }
    return $this->response;
}

然后它应该工作。

但是,您可以直接从路由声明中使用控制器方法,而无需使用闭包:

$app->post('/users', `Apex\Controllers\User::create`);

控制器的create方法将如下所示:

namespace Apex\Controllers;

class User
{
    public function create($request, $response)
    {
        $data = $request->getParsedBody();

        $model = new \Apex\Models\User(ApexDB::getInstance());
        $jsonBuilder = ApexResponse::getBuilder('JSON', $response);

        if ($model->save($data)) {
            $response = $jsonBuilder->build($data, 201);
        } else {
            $response = $jsonBuilder->build('error', 400);
        }
        return $response;
    }
}

最后,考虑rka-content-type-renderer而不是JsonBuilder,尽管它可能比您展示的更多。


更新:

理想情况下,您会使用构造函数注入将 User 模型注入控制器。去做这个:

  1. 更新您的控制器:

    namespace Apex\Controllers;
    
    use Apex\Models\User as UserModel;
    
    class User
    {
        protected $userModel;
    
        public function __construct(UserModel $userModel)
        {
            $this->userModel = $userModel;
        }
    
        public function create($request, $response)
        {
            $data = $request->getParsedBody();
    
            $jsonBuilder = ApexResponse::getBuilder('JSON', $response);
    
            if ($this->userModel->save($data)) {
                $response = $jsonBuilder->build($data, 201);
            } else {
                $response = $jsonBuilder->build('error', 400);
            }
            return $response;
        }
    }
    
  2. 为 Pimple 依赖注入容器编写一个工厂:

    $container = $app->getContainer();
    $container['Apex\Controllers\User'] = function ($c) {
        $userModel = new \Apex\Models\User(ApexDB::getInstance());
        return new \ApexController\User($userModel);
    };
    
于 2016-11-13T08:38:59.763 回答