Тонкие выходы JSON - PullRequest
       74

Тонкие выходы JSON

29 голосов
/ 24 июля 2011

Я использую среду Slim с PHP для создания RESTful API для моего приложения. Тем не менее, я предположил, что у фреймворка будет какой-то способ создания более простых выходных данных JSON, а не просто exit($jsonEncodedVariable);.

Я что-то упустил в рамках или мне нужно использовать json_encode() ... exit($json) ... для каждого метода?

Все данные извлекаются из базы данных MySQL и затем помещаются в массив JSON в зависимости от того, какой запрос REST был вызван.

Например, если запрошено /api/posts/all, я exit() буду массивом JSON всех сообщений, каждое из которых имеет свой собственный ключ, "value" : key.

У меня вопрос: есть ли простой способ, используя тонкий фреймворк, для exit() использования кода JSON вместо его вывода в виде простого текста?

Ответы [ 17 ]

57 голосов
/ 31 января 2012

Почему бы просто не использовать объект ответа Слима?(также ... зачем выходить?)

$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 на стеке, тем лучше.

Я в основном играл с той же вещью и заметил, что вы используете exit ;Сначала я использовал exit также потому, что echo включал в себя кучу HTML и копировал то, что возвращалось моему вызову AJAX.Когда я использовал выход, он аккуратно вырезал HTML, но тогда объект ответа Slim не изменял заголовки ответа, как я определил (см. Код выше).

Я понял, что это не так, как Slimбыл предназначен для работы.Используйте эхо, а не выход.ПРИМЕЧАНИЕ. - Slim Doc:

Всякий раз, когда вы выводите содержимое echo () из обратного вызова маршрута, содержимое echo () записывается> в выходной буфер, а затем добавляется в тело ответа перед HTTPответ возвращается клиенту.

Это удобно, но я не смог повторить.То, что я испортил, было большей проблемой.Отделение контента от поведения.Если вы похожи на меня, вы настраиваете одностраничное приложение, где этот код находится в основном на index.php.Существует исходный HTML, который мне нужно было загрузить, поэтому я включил его на этой странице.Мне нужно было создать более чистое разделение.Моя маршрутизация была правильно настроена, и поэтому, когда люди GET '/' Slim_Views (см. Разработка Rel.) Возвращает мне отрендеренный шаблон html и js.Блестяще!

Теперь у меня есть все инструменты Slim, и мой код намного чище, отдельно, управляем и более совместим с протоколами http.Я думаю, это то, для чего нужны рамки.: -)

ПРИМЕЧАНИЕ: я не говорю, что это все, что обернулось с вашей стороны, но я подумал, что вопрос и ваши настройки кажутся очень похожими.Это может помочь другому новому парню, который бродит по этому же пути.

ОБНОВЛЕНИЕ: Как упоминает @alttag, этот ответ устарел (Slim 2)

Для Slim3 см. Ответ ниже или см. Эту страницу в документации

32 голосов
/ 24 июля 2011
header("Content-Type: application/json");
echo json_encode($result);
exit;

Подсказка: Использование Slim PHP Framework для разработки REST API

25 голосов
/ 28 февраля 2016

Используя 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 (лучше всего подходит для специальных символов и других, например: правильно вывести «ã»)

10 голосов
/ 23 августа 2013

Вы можете расширить 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);
});
8 голосов
/ 13 апреля 2015

Поскольку каждый усложнил свои ответы функциями и классами, я добавлю этот упрощенный ответ.\ 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/.

4 голосов
/ 06 августа 2013

Я чувствую твою боль. Я хотел создать функцию многократного использования, поэтому я создал файл помощников и включил в него следующее:

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

Редактировать: Я думаю, было бы очень хорошо, если бы уже были встроены такие функции в объект ответа для популярных типов пантомимы

4 голосов
/ 21 июня 2012

Я думаю, что Slim также предоставляет объект промежуточного программного обеспечения, который делает это автоматически, поэтому пользователям этой инфраструктуры не приходится писать json_decode и кодировать при каждом запросе, он называется объектом Slim_Middleware_ContentType.расшифровка для вас.декодирование работает отлично. Но для кодирования последний пост отлично.

Спасибо, Дхарани

2 голосов
/ 24 июля 2011
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 голосов
/ 21 ноября 2016

//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));
    }
});
1 голос
/ 01 июня 2012

почему бы не $response->write(json_encode($dataAry)); вместо echo json_encode($dataAry);?

...