问题
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?
回答1:
header("Content-Type: application/json");
echo json_encode($result);
exit;
Hint: Using The Slim PHP Framework for Developing REST APIs
回答2:
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
回答3:
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)
回答4:
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);
});
回答5:
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/.
回答6:
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
回答7:
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
回答8:
function _die($array){
echo json_encode($array);
exit;
}
$result = mysql_query("SELECT * FROM table");
while($row = mysql_fetch_assoc($result)){
$array[] = $row;
}
_die($array);
回答9:
//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));
}
});
回答10:
why not $response->write(json_encode($dataAry));
instead of echo json_encode($dataAry);
?
回答11:
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.
回答12:
Use Slim JSON API https://coderwall.com/p/otcphg/create-a-json-restfull-api-using-slim-framework. You can handle JSON output with it.
回答13:
[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());
回答14:
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.
回答15:
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'
]));
回答16:
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.
回答17:
header("Content-Type : application/json"); echo json_encode($data);
来源:https://stackoverflow.com/questions/6807404/slim-json-outputs