精简 JSON 输出

发布于 2024-11-25 18:53:31 字数 475 浏览 3 评论 0 原文

我使用 Slim 框架和 PHP 为我的应用程序创建 RESTful API。但是,我假设框架有某种方法来创建更简单的 JSON 输出,而不仅仅是 exit($jsonEncodedVariable);

我是否在框架中遗漏了某些内容,或者我是否需要对每个方法使用 json_encode()... exit($json)... ?

所有数据均从我的 MySQL 数据库中取出,然后根据调用的 REST 请求放入 JSON 数组中。

例如,如果请求 /api/posts/all ,我会 exit() 所有帖子的 JSON 数组,每个帖子都有自己的键 “值”:键

我的问题是,是否有一种简单的方法,使用 slim 框架来 exit()'ing JSON 代码,而不是将其作为纯文本退出?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(17

不美如何 2024-12-02 18:53:31

为什么不直接使用 Slim 的响应对象呢? (另外......为什么退出?)

$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 美分,并就此事进行更多讨论。 Stack 上有关 Slim 的信息越多越好。

我基本上在玩弄同样的事情,我注意到你正在使用 exit;起初,我使用 exit 也是因为 echo 包含一堆 HTML 并弄乱了返回到我的 AJAX 调用的内容。当我使用 exit 时,它干净地剪切了 HTML,但 Slim 响应对象并没有按照我的定义更改响应标头(请参阅上面的代码)。

我意识到这不是 Slim 的设计工作方式。使用 echo,而不是退出。注意 - Slim 文档:

每当您从路由回调中 echo() 内容时,echo() 的内容都会被捕获到输出缓冲区中,然后在 HTTP 响应返回到客户端之前附加到响应正文。< /p>

这很方便,但我无法回应。我搞砸的事情是一个更大的问题。内容与行为分离。如果您像我一样,您正在设置一个单页应用程序,其中该代码基本上位于index.php 上。我需要加载初始 html,因此我将其包含在该页面上。我需要做的是创造一个更干净的分离。我的路由设置正确,因此当人们 GET '/' 时,Slim_Views(请参阅开发相关)会为我返回 html 和 js 的渲染模板。杰出的!

现在我可以使用 Slim 的所有工具,并且我的代码更加干净、独立、易于管理,并且更符合 http 协议。我想这就是框架的用途。 :-)

注意:我并不是说这一切都是你的问题,但我认为这个问题和你的设置看起来非常相似。它可能会帮助另一个走在同样道路上的新人。

更新:正如@alttag提到的,这个答案已经过时了(Slim 2)

对于 Slim3,请参阅下面的答案或查看此页面文档

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

爱她像谁 2024-12-02 18:53:31
header("Content-Type: application/json");
echo json_encode($result);
exit;

提示:使用 Slim PHP 框架开发 REST API

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

Hint: Using The Slim PHP Framework for Developing REST APIs

薆情海 2024-12-02 18:53:31

使用 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 添加了第二个和第三个参数。第二个是 HTTP 状态代码,第三个是 Json 编码选项(最适合特殊字符和其他字符,例如:正确打印“ã”)

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)

楠木可依 2024-12-02 18:53:31

您可以使用输出函数扩展 slim,该函数的输出取决于调用的 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);
});

you can extend slim with an output function which output is depending the REST request was called:

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

and use it like this:

$app->get('/test/', function() use ($app) {
    $data = array(1,2,3,4);
    $app->outputArray($data);
});
随风而去 2024-12-02 18:53:31

由于每个人都用函数和类使他们的答案变得复杂,所以我将给出这个简化的答案。 \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/

Since everyone has complicated their answers with functions and classes, I'll throw in this simplified answer. The \Slim\Http\Response can do it for you like this:

$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();

As you're most likely only returning JSON data it might be a good idea to make an appropriate middleware, see http://www.sitepoint.com/best-practices-rest-api-scratch-introduction/.

还在原地等你 2024-12-02 18:53:31

我认为 Slim 还提供了一个中间件对象,它可以自动执行此操作,因此该框架的用户不必在每个请求上编写 json_decode 和编码,它称为
Slim_Middleware_ContentType 对象。

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

它为你解码。解码效果很好。但是对于编码,最后一篇文章很棒。

谢谢,
陀罗尼

I think Slim also provides a middleware object which does this automatically so users of that framework doesnt have to write json_decode and encode on every request, its called the
Slim_Middleware_ContentType object.

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

it does the decoding for you. the decoding works great.But for encoding the last post is great.

Thanks,
Dharani

迷你仙 2024-12-02 18:53:31

我感受到你的痛苦。我想制作一个可重用的函数,所以我制作了一个帮助程序文件,并包含了这个:

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

编辑:我认为如果已经有像这样的函数内置到响应对象中,那就太好了流行的哑剧类型

I feel your pain. I wanted to make a reusable function, so I made a helpers file, and included this:

function toJSON($app, $content) {
    $response = $app->response;
    $response['Content-Type'] = 'application/json';
    $response->body( json_encode($content) );
};

And then I used it like this:

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

Edit: I think it would be really nice if there were already functions like this built into the response object for the popular mime types

囍孤女 2024-12-02 18:53:31
//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));
    }
});

//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));
    }
});
爱冒险 2024-12-02 18:53:31
function _die($array){
   echo json_encode($array);
   exit;
}


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

_die($array);
function _die($array){
   echo json_encode($array);
   exit;
}


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

_die($array);
是你 2024-12-02 18:53:31

为什么不使用 $response->write(json_encode($dataAry)); 而不是 echo json_encode($dataAry);

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

呢古 2024-12-02 18:53:31

我的解决方法是添加“exit;”在 json 打印输出结束时,我的开发服务器并不关心,但我的实时服务器不会触发 json 结束事件。我不需要添加标头或使用 json_encode。

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.

粉红×色少女 2024-12-02 18:53:31

使用 Slim JSON API https://coderwall.com /p/otcphg/create-a-json-restfull-api-using-slim-framework。您可以用它处理 JSON 输出。

Use Slim JSON API https://coderwall.com/p/otcphg/create-a-json-restfull-api-using-slim-framework. You can handle JSON output with it.

止于盛夏 2024-12-02 18:53:31

[之前]:内容类型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());

[BEFORE]: Content-Type text/html; charset=UTF-8

Not working with 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

Working with 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());
无言温柔 2024-12-02 18:53:31

您可以在 slim3 中使用 Slim 的 Response 对象自定义方法 withJson($data, $status, $encodingOptions)

$app->get('/hello/{name}', function ($request, $response, $args) {
    $data['msg']='Hello '.$request->getAttribute('name');
    $newResponse = $response->withJson($data);
});

详细信息 在此处阅读。

You can use in slim3, Slim’s Response object custom method withJson($data, $status, $encodingOptions)

$app->get('/hello/{name}', function ($request, $response, $args) {
    $data['msg']='Hello '.$request->getAttribute('name');
    $newResponse = $response->withJson($data);
});

For more information read here.

只等公子 2024-12-02 18:53:31

这就是我在 slim 版本 2 中的做法

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

This is how I do it in slim version 2

$app->response->headers->set("Content-Type", 'application/json');
return $app->response->write(json_encode([
    'status' => true,
    'message' => 'Your message'
]));
如果没有 2024-12-02 18:53:31

我使用 https://github.com/entomb/slim-json-api我用 Slim 2 编写的 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));
    });
});

我真的很喜欢使用中间件和路由分组的抽象级别,这样可以轻松地将不同的响应类型应用于应用程序的不同区域。

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.

滿滿的愛 2024-12-02 18:53:31

标头(“内容类型:应用程序/json”);
回显 json_encode($data);

header("Content-Type : application/json");
echo json_encode($data);

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文