2016-01-07 14 views
20

Ho questo semplice API REST, fatto in Slim,Slim - Come inviare risposta con l'intestazione "Content-Type: application/json"?

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

tuttavia, non posso ottenere browser per mandarmi application/json tipo di contenuto, è sempre manda text/html? Cosa sto facendo di sbagliato?

EDIT:

Ok, dopo due ore di colpire la testa contro la parete, sono incappato in questa risposta:

https://github.com/slimphp/Slim/issues/1535 (nella parte inferiore di una pagina) che spiega cosa succede, sembra che l'oggetto response sia immutabile e come tale deve essere restituito o riassegnato se si desidera restituirlo dopo while.

+0

È stata impostata l'intestazione della risposta http 'Content-Type' prima di inviare una risposta? – Rao

+1

..come potete vedere nel mio codice '$ response-> withHeader ('Content-Type', 'application/json');' – branquito

+0

Non dovrebbe 'return' essere' echo'? – Darren

risposta

21

Così, invece di questo:

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

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

fare così:

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

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

E tutto va bene e buono.

8

Per V3, withJson() è disponibile.

Così si può fare qualcosa di simile:

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

Nota: Assicurati di restituire il $response perché se si dimentica, la risposta sarà ancora uscire, ma non sarà application/json.

+0

Perché non è possibile concatenare mentre si lavora su linee separate? –

+0

@JomarSevillejo, avrei bisogno di vedere il tuo codice per fornire un suggerimento, ma se sono su linee separate, avrai ancora bisogno di restituire l'oggetto dopo quelle linee. – conrad10781

+1

@ jomar-sevillejo Questo perché l'oggetto Response è immutabile. Ogni volta che vuoi "modificare" una delle sue proprietà, tutto ciò che fai in effetti è creare un clone con il nuovo valore per questa proprietà. Pertanto, il concatenamento funziona e questo è l'ultimo che è necessario tornare a Slim. – Gabriel