web-dev-qa-db-ja.com

スリムなJSON出力

Slimフレームワークを使用してPHP=アプリのRESTful APIを作成します。ただし、フレームワークにはexit($jsonEncodedVariable);

フレームワークに何か不足していますか、またはすべてのメソッドにjson_encode() ... exit($json) ...を使用する必要がありますか?

すべてのデータはMySQLデータベースから取り出され、RESTリクエストが呼び出されたものに応じてJSON配列に入れられます。

たとえば、/api/posts/allが要求された場合、各キーが"value" : keyであるすべての投稿のJSON配列をexit()します。

私の質問は、JSONコードをプレーンテキストとして終了する代わりにexit() 'するためのスリムなフレームワークを使用した簡単な方法はありますか?

30
max_
header("Content-Type: application/json");
echo json_encode($result);
exit;

ヒント: スリムPHP開発用フレームワークの使用REST API

32
hakre

スリムの応答オブジェクトを使用しないのはなぜですか? (また...なぜ終了するのですか?)

$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については、以下の回答を参照するか、 ドキュメントのこのページを参照

57
jmk2142

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エンコードオプションです(特殊な文字などに最適です。たとえば、「ã」を正しく印刷します)。

25
jeff_drumgod

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);
});
11
d3nnis

誰もが関数とクラスで答えを複雑にしているので、この単純な答えを投げます。\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/

8

あなたの痛みが分かります。再利用可能な関数を作りたかったので、ヘルパーファイルを作成し、これを含めました。

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タイプの応答オブジェクトに組み込まれていれば、本当にいいと思う

4
Kristian

Slimはこれを自動的に行うミドルウェアオブジェクトも提供するので、そのフレームワークのユーザーはjson_decodeを記述して、Slim_Middleware_ContentTypeオブジェクト。

$app->response()->('application/json');
$app->add(new Slim_Middleware_ContentType());

デコードを行います。デコードはうまく機能しますが、エンコードについては最後の投稿が素晴らしいです。

ありがとう、ダーラニ

4
//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));
    }
});
2
Sumit Shinde
function _die($array){
   echo json_encode($array);
   exit;
}


$result = mysql_query("SELECT * FROM table");
while($row = mysql_fetch_assoc($result)){
    $array[] = $row;
}

_die($array);
2
genesis

私の修正は「終了」を追加することでした。 jsonの出力の最後で、私の開発サーバーは気にしませんでしたが、私のライブサーバーはjson終了イベントをトリガーしませんでした。ヘッダーを追加したりjson_encodeを使用したりする必要はありませんでした。

1
pikknz

なぜ$response->write(json_encode($dataAry));ではなくecho json_encode($dataAry);ではないのですか?

1
k33g_org

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);
});

詳細については こちらをご覧ください

0
Nanhe Kumar

これは私がスリムバージョン2でそれを行う方法です

$app->response->headers->set("Content-Type", 'application/json');
return $app->response->write(json_encode([
    'status' => true,
    'message' => 'Your message'
]));
0
Sajjad Ashraf

スリム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());
0
user3104260

スリム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));
    });
});

ミドルウェアとルートのグループ化を使用する抽象化レベルが本当に好きで、アプリのさまざまな領域にさまざまな応答タイプを簡単に適用できます。

0
emccracken