Slim JSON Outputs

2019-03-08 03:48发布

I am using the Slim framework with PHP to create a RESTful API for my app. However, I assumed that the framework would have some way of creating easier JSON outputs rather than just exit($jsonEncodedVariable);.

Am I missing something in the framework, or do I need to use json_encode()... exit($json)... for every method?

All of the data is taken out of the my MySQL database and would then be put into a JSON array depending on what REST request was called.

For example, if /api/posts/all was requested, I would exit() a JSON array of all the posts which each value for its own key, "value" : key.

My question is, is there an easy way, using the slim framework, for exit()'ing JSON code instead of exiting it as plain text?

17条回答
女痞
2楼-- · 2019-03-08 04:24

Why not just use Slim's Response Object? (also... why 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)

Let me preface by saying I still consider myself a noob so if I'm making errors please correct me so I can learn. But, I was playing with a similar problem/question and I thought I might chime in with 2 cents and archive a little more discussion on the matter. The more information there is about Slim on Stack the better.

I was basically toying with the same thing and I noticed that you were using exit; At first, I was using exit also because echo was including a bunch of HTML and mucking up what was being returned to my AJAX call. When I used exit, it cleanly cut the HTML out but then the Slim response object wasn't changing the response headers as I defined (see above code.)

What I realized was that this isn't how Slim was designed to work. Use echo, not exit. NOTE - Slim Doc:

Whenever you echo() content from within a route callback, the echo()’d content is captured >in an output buffer and later appended to the Response body before the HTTP response is >returned to the client.

That's convenient, but I was not able to echo. What I was messing up on was a bigger problem. Separation of content from behavior. If you're like me, you're setting up a single page application where this code basically sits on index.php. There is initial html that I needed to load up so I included it on that page. What I needed to do was create a cleaner separation. My routing was properly set up and so when people GET '/' the Slim_Views (see Develop Rel.) returns a rendered template of html and js for me. Brilliant!

Now I have all of Slim's tools at disposal and my code is much much cleaner, separate, manageable, and more compliant with http protocols. I guess this is what frameworks are for. :-)

NOTE: I'm not saying all this is what went down on your end, but I thought the question and your setup seemed very similar. It might help another new guy who wanders down this same path.

UPDATE: As @alttag mentions, this answer is getting out of date (Slim 2)

For Slim3, see an answer below or see this page in the documentation

查看更多
Explosion°爆炸
3楼-- · 2019-03-08 04:26

Using Slim 3, I'm using this format:

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

On request "/123", result JSON with:

{
  id: "123"
}

More infos read here.

[UPDATE] Added second and third param to withJSON. Second is The HTTP status code, and third is Json encoding options (best for especial chars and others, for example: print "ã" correctly)

查看更多
该账号已被封号
4楼-- · 2019-03-08 04:26

I use https://github.com/entomb/slim-json-api for my API written in Slim 2 to enable JSON-response. Init code looks something like this:

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

I really like the abstraction level using middleware and grouping of routes, making it easy to apply different response types to different areas of the app.

查看更多
Melony?
5楼-- · 2019-03-08 04:27

//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));
    }
});
查看更多
甜甜的少女心
6楼-- · 2019-03-08 04:28

why not $response->write(json_encode($dataAry)); instead of echo json_encode($dataAry); ?

查看更多
等我变得足够好
7楼-- · 2019-03-08 04:28

My fix was adding "exit;" at the end of the json print out, my dev server didn't care, but my live server would not trigger the json end event. I did not need to add headers or use json_encode.

查看更多
登录 后发表回答