web-dev-qa-db-fra.com

Slim - Comment envoyer une réponse avec l'en-tête "Content-Type: application/json"?

J'ai cette simple REST api, réalisée dans 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();

cependant, je ne peux pas obtenir de navigateur pour m'envoyer le type de contenu application/json, il envoie toujours text/html? Qu'est ce que je fais mal?

MODIFIER:

Ok, après deux heures de frapper la tête contre le mur, je suis tombé sur cette réponse:

https://github.com/slimphp/Slim/issues/1535 (au bas d'une page) Ce qui explique ce qui se passe, semble que l'objet response est immuable et que, comme tel, il doit l'être retourné ou réaffecté si vous voulez le retourner après while.

25
branquito

Donc, au lieu de cela:

if($student) {
            $response->withHeader('Content-Type', 'application/json');
            $response->write(json_encode($student));
            return $response;

        } else { throw new PDOException('No records found');}

Fait comme ça:

if($student) {
    return $response->withStatus(200)
        ->withHeader('Content-Type', 'application/json')
        ->write(json_encode($student));

} else { throw new PDOException('No records found');}

Et tout va bien.

30
branquito

Pour V3, withJson() est disponible.

Ainsi, vous pouvez faire quelque chose comme:

return $response->withStatus(200)
                ->withJson(array($request->getAttribute("route")
                ->getArgument("someParameter")));

Remarque: Assurez-vous de renvoyer le $response car, si vous oubliez, la réponse sera toujours envoyée mais ce ne sera pas application/json.

13
conrad10781

Pour la V3, la méthode la plus simple selon le Slim docs est:

$data = array('name' => 'Rob', 'age' => 40);
return $response->withJson($data, 201);

Cela définit automatiquement le type de contenu sur application/json;charset=utf-8 et vous permet également de définir un code d'état HTTP (la valeur par défaut est 200 si elle est omise).

1
benyafai

Vous pouvez aussi utiliser:

$response = $response->withHeader('Content-Type', 'application/json');
$response->write(json_encode($student));
return $response;

parce que withHeader renvoie un nouvel objet de réponse. De cette façon, vous avez plus d'une écriture et code entre.

0
jcubic