I have this simple REST api, done in Slim,
<?php
require '../vendor/autoload.php';
function getDB()
{
$dsn = 'sqlite:/home/branchito/personal-projects/slim3-REST/database.sqlite3';
$options = array(
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
);
try {
$dbh = new PDO($dsn);
foreach ($options as $k => $v)
$dbh->setAttribute($k, $v);
return $dbh;
}
catch (PDOException $e) {
$error = $e->getMessage();
}
}
$app = new \Slim\App();
$app->get('/', function($request, $response) {
$response->write('Bienvenidos a Slim 3 API');
return $response;
});
$app->get('/getScore/{id:\d+}', function($request, $response, $args) {
try {
$db = getDB();
$stmt = $db->prepare("SELECT * FROM students
WHERE student_id = :id
");
$stmt->bindParam(':id', $args['id'], PDO::PARAM_INT);
$stmt->execute();
$student = $stmt->fetch(PDO::FETCH_OBJ);
if($student) {
$response->withHeader('Content-Type', 'application/json');
$response->write(json_encode($student));
} else { throw new PDOException('No records found');}
} catch (PDOException $e) {
$response->withStatus(404);
$err = '{"error": {"text": "'.$e->getMessage().'"}}';
$response->write($err);
}
return $response;
});
$app->run();
however, I can't get browser to send me application/json
content type, it
always sends text/html
? What I am doing wrong?
EDIT:
Ok, after two hours of hitting the head against the wall, I stumbled upon this answer:
https://github.com/slimphp/Slim/issues/1535 (at the bottom of a page)
which explains what happens, appears that response
object is immutable and
as such it must be returned or reassigned if you want to return it after
while.
So, instead of this:
if($student) {
$response->withHeader('Content-Type', 'application/json');
$response->write(json_encode($student));
return $response;
} else { throw new PDOException('No records found');}
Do like this:
if($student) {
return $response->withStatus(200)
->withHeader('Content-Type', 'application/json')
->write(json_encode($student));
} else { throw new PDOException('No records found');}
And all is well and good.
For V3, withJson()
is available.
So you can do something like:
return $response->withStatus(200)
->withJson(array($request->getAttribute("route")
->getArgument("someParameter")));
Note: Make sure you return the $response
because if you forget, the response will still come out but it will not be application/json
.
For V3, the simplest method as per the Slim docs is:
$data = array('name' => 'Rob', 'age' => 40);
return $response->withJson($data, 201);
This automatically sets the Content-Type to application/json;charset=utf-8
and lets you set a HTTP status code too (defaults to 200 if omitted).
You can also use:
$response = $response->withHeader('Content-Type', 'application/json');
$response->write(json_encode($student));
return $response;
because withHeader
return new response object. That way you have more then one write and code between.
来源:https://stackoverflow.com/questions/34646008/slim-how-to-send-response-with-content-type-application-json-header