it-swarm.com.de

Schlanke JSON-Ausgänge

Ich verwende das Slim-Framework mit PHP, um eine RESTful-API für meine App zu erstellen. Ich ging jedoch davon aus, dass das Framework auf irgendeine Weise einfachere JSON-Ausgaben erstellen könnte, als nur exit($jsonEncodedVariable);.

Fehlt etwas im Framework oder muss ich für jede Methode json_encode()... exit($json)... verwenden?

Alle Daten werden aus meiner MySQL-Datenbank entnommen und dann in ein JSON-Array gestellt, je nachdem, welche REST -Anforderung aufgerufen wurde.

Wenn zum Beispiel /api/posts/all angefordert wurde, würde ich exit() ein JSON-Array aller Posts erstellen, für die jeder Wert seinen eigenen Schlüssel "value" : key enthält.

Meine Frage ist, gibt es eine einfache Möglichkeit, mithilfe des schlanken Frameworks JSON-Code zu exit()en, anstatt ihn als Nur-Text-Code zu beenden?

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

Hinweis: Verwenden des Slim PHP - Frameworks für die Entwicklung von REST - APIs

32
hakre

Warum nicht einfach das Antwortobjekt von Slim verwenden? (auch ... warum verlassen?)

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

Lassen Sie mich vorab sagen, dass ich mich immer noch als Noob betrachte. Wenn ich Fehler mache, korrigieren Sie mich bitte, damit ich lernen kann. Aber ich spielte mit einem ähnlichen Problem/einer ähnlichen Frage und dachte, ich könnte mit 2 Cent einschlagen und ein wenig mehr Diskussion darüber archivieren. Je mehr Informationen es zu Slim on Stack gibt, desto besser.

Ich spielte im Grunde mit der gleichen Sache und bemerkte, dass Sie exit verwendeten. Zuerst benutzte ich exit auch deshalb, weil das Echo eine Menge HTML enthielt und die Informationen zu meinem AJAX - Aufruf zusammenfasste. Bei der Verwendung von exit wurde der HTML-Code sauber ausgeschnitten, aber das Slim-Antwortobjekt hat die Antwortheader bei der Definition nicht geändert (siehe Code oben).

Mir wurde klar, dass Slim nicht so funktioniert. Verwenden Sie Echo, nicht beenden. HINWEIS - Slim Doc:

Wenn Sie den Inhalt von echo () innerhalb eines Route-Callbacks echo (), wird der Inhalt des echo () in einem Ausgabepuffer erfasst und später an den Antworttext angehängt, bevor die HTTP-Antwort an den Client zurückgegeben wird.

Das ist praktisch, aber ich konnte es nicht wiederholen. Was ich vermasselte, war ein größeres Problem. Trennung von Inhalt und Verhalten. Wenn Sie wie ich sind, richten Sie eine Einzelseitenanwendung ein, deren Code im Wesentlichen auf index.php steht. Es gibt ein erstes HTML, das ich laden musste, also habe ich es auf dieser Seite hinzugefügt. Was ich tun musste, war eine sauberere Trennung. Mein Routing wurde korrekt eingerichtet, und wenn Leute GET '/' erhalten, geben Slim_Views (siehe Develop Rel.) Eine gerenderte Vorlage von HTML und Js für mich zurück. Brillant!

Jetzt stehen mir alle Tools von Slim zur Verfügung und mein Code ist viel sauberer, separater, handhabbarer und mit den http-Protokollen kompatibel. Ich denke, dafür sind die Rahmenbedingungen gedacht. :-)

HINWEIS: Ich sage nicht, dass dies alles an Ihrem Ende gescheitert ist, aber ich dachte, die Frage und Ihr Setup schienen sehr ähnlich zu sein. Es könnte einem anderen neuen Mann helfen, der denselben Weg entlanggeht.

UPDATE: Wie @alttag erwähnt, ist diese Antwort nicht mehr aktuell (Slim 2).

Für Slim3 sehen Sie eine Antwort unten oder siehe diese Seite in der Dokumentation

57
jmk2142

Mit Slim 3 verwende ich dieses 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
    );
});

Auf Anfrage "/ 123", Ergebnis JSON mit:

{
  id: "123"
}

Weitere Infos hier lesen .

[UPDATE] Zweiter und dritter Parameter zu withJSON hinzugefügt. Zweitens ist der HTTP-Statuscode und drittens die Json-Codierungsoptionen (am besten für bestimmte Zeichen und andere, zum Beispiel: "ã" richtig drucken).

23
jeff_drumgod

sie können Slim mit einer Ausgabefunktion erweitern, deren Ausgabe davon abhängt, dass die Anforderung REST aufgerufen wurde:

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

und benutze es so:

$app->get('/test/', function() use ($app) {
    $data = array(1,2,3,4);
    $app->outputArray($data);
});
10
d3nnis

Da jeder seine Antworten mit Funktionen und Klassen verkompliziert hat, werde ich diese vereinfachte Antwort einwerfen. Die\Slim\Http\Response kann dies für Sie wie folgt tun:

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

Da Sie höchstwahrscheinlich nur JSON-Daten zurückgeben, ist es möglicherweise eine gute Idee, eine geeignete Middleware zu erstellen, siehe http://www.sitepoint.com/best-practices-rest-api-scratch-introduction/ .

8

Ich fühle deinen Schmerz. Ich wollte eine wiederverwendbare Funktion erstellen, also habe ich eine Hilfedatei erstellt und Folgendes hinzugefügt:

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

Und dann habe ich es so benutzt:

$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: Ich denke, es wäre wirklich schön, wenn in den Antwortobjekten der populären Mime-Typen bereits Funktionen wie diese eingebaut wären

4
Kristian

Ich denke, Slim stellt auch ein Middleware-Objekt bereit, das dies automatisch tut, so dass Benutzer dieses Frameworks nicht json_decode schreiben und bei jeder Anforderung codieren müssen. Das Objekt heißt Slim_Middleware_ContentType.

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

es erledigt die Dekodierung für Sie. die decodierung funktioniert super.

Danke, Dharani

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

Mein Fix fügte hinzu, "exit"; Am Ende des Json-Ausdrucks war es meinem Dev-Server egal, aber mein Live-Server würde das Json-End-Ereignis nicht auslösen. Ich musste keine Header hinzufügen oder json_encode verwenden.

1
pikknz

warum nicht $response->write(json_encode($dataAry)); anstelle von echo json_encode($dataAry);?

1
k33g_org

Sie können in Slim3, der benutzerdefinierten Methode des Slim-Antwortobjekts, mit Json ($ data, $ status, $ codingOptions) 

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

Weitere Informationen hier lesen.

0
Nanhe Kumar

So mache ich es in der schlanken Version 2

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

Verwenden Sie Slim JSON API https://coderwall.com/p/otcphg/create-a-json-restfull-api-using-slim-framework Sie können damit die JSON-Ausgabe behandeln.

[VOR]: Inhaltstyp Text/HTML; Zeichensatz = UTF-8 

Funktioniert nicht mit 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-Anwendung/json; Zeichensatz = utf-8 

Mit SOAPUI JSON arbeiten;)

$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

Ich benutze https://github.com/entomb/slim-json-api für meine in Slim 2 geschriebene API, um JSON-Antwort zu aktivieren. Init-Code sieht ungefähr so ​​aus:

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

Die Abstraktionsebene mit Middleware und das Gruppieren von Routen gefällt mir sehr gut. Dadurch können verschiedene Antworttypen auf verschiedene Bereiche der App angewendet werden.

0
emccracken