J'utilise le framework Slim avec PHP pour créer une API RESTful pour mon application. Cependant, j'ai supposé que le cadre aurait un moyen de créer des sorties JSON plus faciles au lieu de exit($jsonEncodedVariable);
.
Me manque-t-il quelque chose dans le framework ou dois-je utiliser json_encode()
... exit($json)
... pour chaque méthode?
Toutes les données sont extraites de la base de données MySQL et sont ensuite placées dans un tableau JSON en fonction de la requête REST qui a été appelée.
Par exemple, si /api/posts/all
était demandé, je voudrais exit()
un tableau JSON de tous les posts dont chaque valeur correspond à sa propre clé, "value" : key
.
Ma question est la suivante: existe-t-il un moyen simple, à l’aide du framework slim, de exit()
'ing de code JSON au lieu de le sortir en texte brut?
header("Content-Type: application/json");
echo json_encode($result);
exit;
Astuce: Utilisation du framework PHP pour le développement d'API REST Slim
Pourquoi ne pas simplement utiliser Response Object de Slim? (aussi ... pourquoi sortir?)
$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)
Permettez-moi de commencer par dire que je me considère toujours comme un noob, donc si je fais des erreurs, corrigez-moi pour que je puisse apprendre. Mais, je jouais avec un problème/une question similaire et je pensais pouvoir ajouter 2 cents et archiver un peu plus de discussions sur le sujet. Plus il y a d'informations sur Slim on Stack, mieux c'est.
En gros, je jouais avec la même chose et j'ai remarqué que vous utilisiez exit; Au début, j’utilisais aussi exit parce que echo incluait un ensemble de HTML et consignait ce qui était renvoyé à mon appel AJAX. Lorsque j'ai utilisé exit, le HTML a été coupé de manière nette, mais l'objet de réponse Slim ne modifiait pas les en-têtes de réponse tels que je les ai définis (voir le code ci-dessus).
Ce que j'ai compris, c'est que ce n'est pas ainsi que Slim a été conçu pour fonctionner. Utilisez echo, pas la sortie. NOTE - Slim Doc:
Chaque fois que vous echo () du contenu depuis un rappel de route, le contenu de echo () est> capturé dans un tampon de sortie, puis ajouté au corps de la réponse avant que la réponse HTTP ne soit> renvoyée au client.
C'est pratique, mais je n'ai pas pu faire écho. Ce qui me dérangeait était un problème plus grave. Séparation du contenu du comportement. Si vous êtes comme moi, vous configurez une application d'une seule page où ce code repose essentiellement sur index.php. Il y avait le code HTML initial que je devais charger, je l'ai donc inclus sur cette page. Ce que je devais faire, c'était créer une séparation plus nette. Mon routage a été correctement configuré. Ainsi, lorsque les utilisateurs obtiennent '/' Slim_Views (voir Développer une relation), un modèle de rendu HTML et js est rendu pour moi. Brillant!
Maintenant, je dispose de tous les outils de Slim et mon code est beaucoup plus propre, distinct, gérable et plus compatible avec les protocoles http. Je suppose que c’est à cela que servent les cadres. :-)
NOTE: Je ne dis pas que tout ceci est ce qui s'est passé de votre côté, mais je pensais que la question et votre configuration semblaient très similaires. Cela pourrait aider un autre nouveau type qui se promène dans la même voie.
UPDATE: Comme @alttag le mentionne, cette réponse devient obsolète (Slim 2)
Pour Slim3, voir la réponse ci-dessous ou voir cette page dans la documentation
En utilisant Slim 3, j'utilise ce 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
);
});
Sur demande "/ 123", résultat JSON avec:
{
id: "123"
}
Plus d'infos lire ici .
[UPDATE] Ajouté les deuxième et troisième paramètres à withJSON
. Deuxièmement, le code d'état HTTP et le troisième, les options de codage Json (idéales pour les caractères spéciaux et autres, par exemple: print "ã" correctement)
vous pouvez étendre slim avec une fonction de sortie dont la sortie dépend de la demande REST qui a été appelée:
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();
et l'utiliser comme ça:
$app->get('/test/', function() use ($app) {
$data = array(1,2,3,4);
$app->outputArray($data);
});
Puisque tout le monde a compliqué ses réponses avec des fonctions et des classes, je vais ajouter cette réponse simplifiée. Le\Slim\Http\Response peut le faire pour vous comme ceci:
$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();
Comme vous ne renvoyez probablement que des données JSON, il peut être judicieux de créer un middleware approprié, voir http://www.sitepoint.com/best-practices-rest-api-scratch-introduction/ .
Je ressens ta douleur. Je voulais créer une fonction réutilisable. J'ai donc créé un fichier helpers et inclus ceci:
function toJSON($app, $content) {
$response = $app->response;
$response['Content-Type'] = 'application/json';
$response->body( json_encode($content) );
};
Et puis je l'ai utilisé comme ça:
$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: Je pense que ce serait vraiment bien s'il y avait déjà des fonctions comme celle-ci intégrées dans l'objet de réponse pour les types de mime populaires
Je pense que Slim fournit également un objet middleware qui le fait automatiquement afin que les utilisateurs de ce framework ne soient pas obligés d'écrire json_decode et d'encoder à chaque requête, il s'appelle l'objet Slim_Middleware_ContentType
.
$app->response()->('application/json');
$app->add(new Slim_Middleware_ContentType());
il fait le décodage pour vous. le décodage fonctionne très bien. Mais encoder le dernier message est génial.
Merci, Dharani
//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));
}
});
function _die($array){
echo json_encode($array);
exit;
}
$result = mysql_query("SELECT * FROM table");
while($row = mysql_fetch_assoc($result)){
$array[] = $row;
}
_die($array);
Mon correctif ajoutait "exit;" à la fin de l'impression json, mon serveur de développement ne s'en souciait pas, mais mon serveur live ne déclencherait pas l'événement json end Je n'ai pas eu besoin d'ajouter des en-têtes ou d'utiliser json_encode.
pourquoi pas $response->write(json_encode($dataAry));
au lieu de echo json_encode($dataAry);
?
Vous pouvez utiliser dans slim3 la méthode personnalisée de l’objet Réponse de Slim avecJson ($ data, $ status, $ encodingOptions)
$app->get('/hello/{name}', function ($request, $response, $args) {
$data['msg']='Hello '.$request->getAttribute('name');
$newResponse = $response->withJson($data);
});
Pour plus d'informations lire ici.
Voici comment je le fais dans la version 2 mince
$app->response->headers->set("Content-Type", 'application/json');
return $app->response->write(json_encode([
'status' => true,
'message' => 'Your message'
]));
Utiliser l'API JSON mince https://coderwall.com/p/otcphg/create-a-jjson-restfull-api-using-slim-framework . Vous pouvez gérer la sortie JSON avec elle.
[AVANT]: Content-Type text/html; jeu de caractères = UTF-8
Ne fonctionne pas avec 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()
)
);
});
[APRES]: application de type de contenu/json; charset = utf-8
Travailler avec 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());
J'utilise https://github.com/entomb/slim-json-api pour mon API écrite en Slim 2 pour activer la réponse JSON. Le code d'initialisation ressemble à ceci:
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));
});
});
J'aime beaucoup le niveau d'abstraction qui utilise un middleware et le regroupement d'itinéraires, ce qui facilite l'application de différents types de réponse à différents domaines de l'application.