Slimフレームワークを使用してPHP=アプリのRESTful APIを作成します。ただし、フレームワークにはexit($jsonEncodedVariable);
。
フレームワークに何か不足していますか、またはすべてのメソッドにjson_encode()
... exit($json)
...を使用する必要がありますか?
すべてのデータはMySQLデータベースから取り出され、RESTリクエストが呼び出されたものに応じてJSON配列に入れられます。
たとえば、/api/posts/all
が要求された場合、各キーが"value" : key
であるすべての投稿のJSON配列をexit()
します。
私の質問は、JSONコードをプレーンテキストとして終了する代わりにexit()
'するためのスリムなフレームワークを使用した簡単な方法はありますか?
header("Content-Type: application/json");
echo json_encode($result);
exit;
スリムの応答オブジェクトを使用しないのはなぜですか? (また...なぜ終了するのですか?)
$dataAry = // Some data array
$response = $app->response();
$response['Content-Type'] = 'application/json';
$response['X-Powered-By'] = 'Potato Energy';
$response->status(200);
// etc.
$response->body(json_encode($dataAry));
// Or echo json_encode($dataAry)
私はまだ自分を初心者と考えていると言って序文を聞かせてください。エラーを犯している場合は、私が学習できるように修正してください。しかし、私は同様の問題/質問で遊んでいて、私は2セントでチャイムを鳴らして、その問題に関するもう少しの議論をアーカイブするかもしれないと思っていました。 Slim on Stackに関する情報が多いほど良い。
私は基本的に同じことをいじっていましたが、あなたがexitを使用していることに気付きました。最初は、エコーに大量のHTMLが含まれていて、AJAX呼び出しに返されたものをマックアップしているため、exitを使用していました。 Slim応答オブジェクトは、定義したとおり応答ヘッダーを変更していません(上記のコードを参照)。
私が気づいたのは、これはスリムが機能するように設計された方法ではないということでした。終了ではなくエコーを使用します。注-スリムドキュメント:
ルートコールバック内からコンテンツをecho()するたびに、echo()されたコンテンツは出力バッファーにキャプチャされ、後でHTTP応答がクライアントに返される前に応答本文に追加されます。
それは便利ですが、エコーできませんでした。私が台無しにしたのは、より大きな問題でした。コンテンツと行動の分離。あなたが私のような人なら、このコードが基本的にindex.phpにある単一ページのアプリケーションをセットアップしています。ロードする必要がある最初のhtmlがあるので、そのページに含めました。私がする必要があったのは、よりきれいな分離を作成することでした。私のルーティングは適切に設定されていたため、人々がGET '/'を実行すると、Slim_Views(Develop Relを参照)はhtmlとjsのレンダリングされたテンプレートを返します。鮮やかさ!
これで、Slimのすべてのツールを自由に使用できるようになり、私のコードはずっときれいになり、分離され、管理しやすくなり、httpプロトコルに準拠しました。これがフレームワークの目的だと思います。 :-)
注:これがすべてあなたの側に落ちたと言っているわけではありませんが、質問と設定は非常に似ていると思いました。この同じ道をさまよう別の新しい男を助けるかもしれません。
UPDATE:@alttagが述べているように、この答えは古くなっています(Slim 2)
Slim3については、以下の回答を参照するか、 ドキュメントのこのページを参照
Slim 3を使用して、私はこのフォーマットを使用しています:
<?php
$app = new \Slim\App();
$app->get('/{id}', function ($request, $response, $args) {
$id = $request->getAttribute('id');
return $response->withJSON(
['id' => $id],
200,
JSON_UNESCAPED_UNICODE
);
});
要求 "/ 123"で、次の結果JSON
{
id: "123"
}
詳細 こちらをご覧ください 。
[更新] withJSON
に2番目と3番目のパラメーターを追加しました。 2番目はHTTPステータスコード、3番目はJsonエンコードオプションです(特殊な文字などに最適です。たとえば、「ã」を正しく印刷します)。
RESTリクエストが呼び出されたことに依存する出力関数でスリムに拡張できます:
class mySlim extends Slim\Slim {
function outputArray($data) {
switch($this->request->headers->get('Accept')) {
case 'application/json':
default:
$this->response->headers->set('Content-Type', 'application/json');
echo json_encode($data);
}
}
}
$app = new mySlim();
次のように使用します:
$app->get('/test/', function() use ($app) {
$data = array(1,2,3,4);
$app->outputArray($data);
});
誰もが関数とクラスで答えを複雑にしているので、この単純な答えを投げます。\Slim\Http\Responseは次のようにあなたのためにそれを行うことができます:
$app = new \Slim\Slim();
$app->get('/something', function () use ($app) {
$response = $app->response();
$response['Content-Type'] = 'application/json';
$response->status(200);
$response->body(json_encode(['data' => []]));
});
$app->run();
JSONデータのみを返す可能性が高いため、適切なミドルウェアを作成することをお勧めします。 http://www.sitepoint.com/best-practices-rest-api-scratch-introduction/ 。
あなたの痛みが分かります。再利用可能な関数を作りたかったので、ヘルパーファイルを作成し、これを含めました。
function toJSON($app, $content) {
$response = $app->response;
$response['Content-Type'] = 'application/json';
$response->body( json_encode($content) );
};
そして、私はこれを次のように使用しました:
$app->get('/v1/users/:id', function($id) use ($app)
{
//instantiate SMM data model
$model = new user_model($site);
//get all docs, or one, depending on if query contains a page ID
$doc = $model->get(array());
//if the object contains main -- we don't need the outer data.
toJSON($app, $doc);
});
編集:このような関数がすでに人気のあるMIMEタイプの応答オブジェクトに組み込まれていれば、本当にいいと思う
Slimはこれを自動的に行うミドルウェアオブジェクトも提供するので、そのフレームワークのユーザーはjson_decodeを記述して、Slim_Middleware_ContentType
オブジェクト。
$app->response()->('application/json');
$app->add(new Slim_Middleware_ContentType());
デコードを行います。デコードはうまく機能しますが、エンコードについては最後の投稿が素晴らしいです。
ありがとう、ダーラニ
//JSON output in slim3
$app->get('/users', function($request,$response,$args) {
require 'db_connect.php';
$stmt = $pdo->query("SELECT * FROM users");
$result=$stmt->fetchAll(PDO::FETCH_ASSOC);
if ($stmt->rowCount() > 0) {
return $response->withStatus(200)
->withHeader('Content-Type', 'application/json')
->write(json_encode($result));
}
else{
$result = array(
"status" => "false",
"message" => "Result not found"
);
return $response->withStatus(200)
->withHeader('Content-Type', 'application/json')
->write(json_encode($result));
}
});
function _die($array){
echo json_encode($array);
exit;
}
$result = mysql_query("SELECT * FROM table");
while($row = mysql_fetch_assoc($result)){
$array[] = $row;
}
_die($array);
私の修正は「終了」を追加することでした。 jsonの出力の最後で、私の開発サーバーは気にしませんでしたが、私のライブサーバーはjson終了イベントをトリガーしませんでした。ヘッダーを追加したりjson_encodeを使用したりする必要はありませんでした。
なぜ$response->write(json_encode($dataAry));
ではなくecho json_encode($dataAry);
ではないのですか?
Slim3、SlimのResponseオブジェクトのカスタムメソッドで、Json($ data、$ status、$ encodingOptions)を使用できます
$app->get('/hello/{name}', function ($request, $response, $args) {
$data['msg']='Hello '.$request->getAttribute('name');
$newResponse = $response->withJson($data);
});
詳細については こちらをご覧ください
これは私がスリムバージョン2でそれを行う方法です
$app->response->headers->set("Content-Type", 'application/json');
return $app->response->write(json_encode([
'status' => true,
'message' => 'Your message'
]));
スリムJSON APIを使用します https://coderwall.com/p/otcphg/create-a-json-restfull-api-using-slim-framework JSON出力を処理できます。
[前]:Content-Type text/html; charset = UTF-8
SOAPUI JSONで動作しない:(
$this->get('get_all', function ($req, $res, $args) {
$um = new UserModel();
return $res
->withHeader('Content-Type', 'application/json')
->getBody()
->write(
json_encode(
$um->get_all()
)
);
});
[AFTER]:Content-Type application/json; charset = utf-8
SOAPUI JSONの操作;)
$this->get('get_all', function ($req, $res, $args) {
$um = new UserModel();
return $res
->withHeader('Content-type', 'application/json;charset=utf-8')
->withJson($um->get_all());
スリム2で記述されたAPIに https://github.com/entomb/slim-json-api を使用してJSON応答を有効にします。初期化コードは次のようになります。
function APIRequests () {
$app = \Slim\Slim::getInstance();
$app->view(new \JsonApiView());
$app->add(new \JsonApiMiddleware());
}
$app->group('/api', 'APIRequests', function () use ($app) {
$app->get('/areas/:id', function ($id) use ($app) {
$app->render(200, Area::find($id));
});
});
ミドルウェアとルートのグループ化を使用する抽象化レベルが本当に好きで、アプリのさまざまな領域にさまざまな応答タイプを簡単に適用できます。