0

スリム フレームワーク バージョン 3 を使用して API のプロジェクトをセットアップしようとしています。誰が PSR-7 を作成し、応答オブジェクトを不変としてマークしたのかわかりません。その用途は見当たりません (私見です。説明してください私が間違っている場合)。スリムだった頃は楽だった 2. 久しぶりにスリムに戻った。

post メソッドであるルートがあり、データを取得してデータベースに保存し、応答コードとして 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

Request と Response に不変オブジェクトを使用するという PSR-7 の決定については、「値オブジェクトを使用する理由」に記載されています。メタ ドキュメントのセクション。

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-rendererJsonBuilderを検討してください。


アップデート:

理想的には、コンストラクター注入を使用して 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 に答える