31

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

我是否缺少框架中的某些内容,或者我是否需要对每种方法都使用json_encode()…… exit($json)

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

例如,如果/api/posts/all被请求,我将exit()创建一个包含所有帖子的 JSON 数组,其中每个值为自己的键,"value" : key.

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

4

17 回答 17

62

为什么不直接使用 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() 内容时,echo() 的内容将被捕获 > 在输出缓冲区中,然后在 HTTP 响应 > 返回给客户端之前附加到响应正文。

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

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

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

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

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

于 2012-01-31T08:02:53.417 回答
34
header("Content-Type: application/json");
echo json_encode($result);
exit;

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

于 2011-07-24T14:46:26.640 回答
28

使用 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 编码选项(最适合特殊字符等,例如:正确打印“ã”)

于 2016-02-28T18:51:04.287 回答
11

您可以使用输出函数扩展 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);
});
于 2013-08-23T08:49:30.863 回答
8

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

于 2015-04-13T14:04:45.457 回答
5

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

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

它为您进行解码。解码效果很好。但是对于最后一篇文章的编码来说很棒。

谢谢,陀罗尼

于 2012-06-21T04:41:20.933 回答
4

我感觉到你的痛苦。我想制作一个可重用的功能,所以我制作了一个帮助文件,并包含以下内容:

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 类型的响应对象中已经内置了这样的功能,那就太好了

于 2013-08-06T01:20:17.697 回答
3

//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));
    }
});
于 2016-11-21T11:26:30.957 回答
2
function _die($array){
   echo json_encode($array);
   exit;
}


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

_die($array);
于 2011-07-24T14:42:32.740 回答
2

为什么不$response->write(json_encode($dataAry));代替echo json_encode($dataAry);

于 2012-06-01T05:32:17.403 回答
1

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

于 2012-10-04T09:43:49.057 回答
0

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

于 2015-04-27T21:46:31.237 回答
0

我使用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));
    });
});

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

于 2015-07-20T20:00:45.273 回答
0

[之前]:内容类型文本/html;字符集=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()
        )
    );
});

[之后]:内容类型应用程序/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());
于 2016-06-13T22:01:30.173 回答
0

可以在 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);
});

欲了解更多信息,请阅读此处。

于 2016-07-22T11:09:07.423 回答
0

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

$app->response->headers->set("Content-Type", 'application/json');
return $app->response->write(json_encode([
    'status' => true,
    'message' => 'Your message'
]));
于 2018-04-08T03:05:32.540 回答
-1

header("内容类型:应用程序/json"); 回声 json_encode($data);

于 2017-02-02T12:55:33.223 回答