Devolver JSON de un script PHP

877

Quiero devolver JSON de un script PHP.

¿Acabo de hacer eco del resultado? ¿Tengo que configurar el Content-Typeencabezado?

Scott Nicol
fuente

Respuestas:

1605

Si bien normalmente está bien sin él, puede y debe establecer el encabezado Content-Type:

<?PHP
$data = /** whatever you're serializing **/;
header('Content-Type: application/json');
echo json_encode($data);

Si no estoy usando un marco en particular, generalmente permito que algunos parámetros de solicitud modifiquen el comportamiento de salida. Puede ser útil, generalmente para la resolución rápida de problemas, no enviar un encabezado, o a veces imprimir_r la carga de datos para mirarlo (aunque en la mayoría de los casos, no debería ser necesario).

timdev
fuente
99
por si acaso: debe usar los comandos de encabezado () además del buffer de salida para evitar advertencias de "encabezados ya enviados"
Kevin
66
El archivo php tiene que estar codificado en UTF-8 sin BOM :)
Krzysztof Kalinowski
217
header('Content-type:application/json;charset=utf-8');
Timo Huovinen
14
@mikepote En realidad no creo que sea necesario tener el comando de encabezado en la parte superior del archivo PHP. Si accidentalmente escupe cosas y eso activa su comando de encabezado, solo necesita corregir su código porque está roto.
Halfstop
8
@KrzysztofKalinowski no, el archivo PHP no necesita ser codificado en UTF-8. la salida DEBE estar codificada en UTF-8. Esas declaraciones incorrectas no ayudan a los usuarios no experimentados a aprender cómo evitar que las cosas se rompan, pero ayuda a desarrollar mitos sobre ellos y nunca aprender qué papel juegan las codificaciones en las transmisiones y cómo funcionan.
Áxel Costas Pena
124

Una pieza completa de código PHP agradable y claro que devuelve JSON es:

$option = $_GET['option'];

if ( $option == 1 ) {
    $data = [ 'a', 'b', 'c' ];
    // will encode to JSON array: ["a","b","c"]
    // accessed as example in JavaScript like: result[1] (returns "b")
} else {
    $data = [ 'name' => 'God', 'age' => -1 ];
    // will encode to JSON object: {"name":"God","age":-1}  
    // accessed as example in JavaScript like: result.name or result['name'] (returns "God")
}

header('Content-type: application/json');
echo json_encode( $data );
aesede
fuente
44

De acuerdo con el manual sobrejson_encode el método puede devolver una no cadena ( falso ):

Devuelve una cadena codificada JSON en caso de éxito o FALSEerror.

Cuando esto sucede, echo json_encode($data)generará la cadena vacía, que no es válida JSON .

json_encodepor ejemplo fallará (y regresará false) si su argumento contiene una cadena que no es UTF-8.

Esta condición de error debe capturarse en PHP, por ejemplo, así:

<?php
header("Content-Type: application/json");

// Collect what you need in the $data variable.

$json = json_encode($data);
if ($json === false) {
    // Avoid echo of empty string (which is invalid JSON), and
    // JSONify the error message instead:
    $json = json_encode(["jsonError" => json_last_error_msg()]);
    if ($json === false) {
        // This should not happen, but we go all the way now:
        $json = '{"jsonError":"unknown"}';
    }
    // Set HTTP response status code to: 500 - Internal Server Error
    http_response_code(500);
}
echo $json;
?>

Entonces, el extremo receptor debe ser consciente de que la presencia de la propiedad jsonError indica una condición de error, que debe tratar en consecuencia.

En el modo de producción, podría ser mejor enviar solo un estado de error genérico al cliente y registrar los mensajes de error más específicos para una investigación posterior.

Lea más sobre cómo tratar los errores JSON en la documentación de PHP .

trincot
fuente
2
No hay charsetparámetro para JSON; vea la nota al final de tools.ietf.org/html/rfc8259#section-11 : "No se define ningún parámetro 'charset' para este registro. Agregar uno realmente no tiene ningún efecto en los destinatarios que cumplen con los requisitos". (JSON debe transmitirse como UTF-8 por tools.ietf.org/html/rfc8259#section-8.1 , por lo que especificar que está codificado como UTF-8 es un poco redundante).
Patrick Dark,
1
Gracias por resaltar eso, @PatrickDark. charsetParámetro redundante eliminado de la cadena del encabezado HTTP.
Trincot
38

Pruebe json_encode para codificar los datos y establecer el tipo de contenido con header('Content-type: application/json');.

thejh
fuente
15

Establezca el tipo de contenido con header('Content-type: application/json');y luego haga eco de sus datos.

Brad Mace
fuente
12

También es bueno establecer la seguridad de acceso: simplemente reemplace * con el dominio que desea para poder acceder a él.

<?php
header('Access-Control-Allow-Origin: *');
header('Content-type: application/json');
    $response = array();
    $response[0] = array(
        'id' => '1',
        'value1'=> 'value1',
        'value2'=> 'value2'
    );

echo json_encode($response); 
?>

Aquí hay más ejemplos sobre eso: ¿cómo omitir Access-Control-Allow-Origin?

Dr. Aaron Dishno
fuente
7
<?php
$data = /** whatever you're serializing **/;
header("Content-type: application/json; charset=utf-8");
echo json_encode($data);
?>
Joyal
fuente
¿Cuál es la diferencia que indica el conjunto de caracteres en el encabezado? Por favor explique, gracias.
Sanxofon
6

Como se dijo anteriormente:

header('Content-Type: application/json');

Hará el trabajo. pero ten en cuenta que:

  • Ajax no tendrá problemas para leer json incluso si no se usa este encabezado, excepto si su json contiene algunas etiquetas HTML. En este caso, debe establecer el encabezado como application / json.

  • Asegúrese de que su archivo no esté codificado en UTF8-BOM. Este formato agrega un carácter en la parte superior del archivo, por lo que su llamada de encabezado () fallará.

Tom Ah
fuente
4

Una función simple para devolver una respuesta JSON con el código de estado HTTP .

function json_response($data=null, $httpStatus=200)
{
    header_remove();

    header("Content-Type: application/json");

    http_response_code($httpStatus);

    echo json_encode($data);

    exit();
}
Dan
fuente
1
header_remove, y establecer explícitamente la respuesta http es una buena idea; aunque establecer el estado y luego http_response parece redundante. También podría querer agregar una exitdeclaración al final. Combiné tu función con la de @trincot: stackoverflow.com/a/35391449/339440
Stephen R el
Gracias por la sugerencia. Acabo de actualizar la respuesta.
Dan
3

La respuesta a tu pregunta está aquí ,

Dice.

El tipo de medio MIME para el texto JSON es application / json.

así que si configura el encabezado a ese tipo y genera su cadena JSON, debería funcionar.

Codemwnci
fuente
1

Sí, necesitarás usar echo para mostrar la salida. Mimetype: application / json

Nev Stokes
fuente
1

Si necesita obtener json de php enviando información personalizada, puede agregar esto header('Content-Type: application/json');antes para imprimir cualquier otra cosa, para que pueda imprimir su customeecho '{"monto": "'.$monto[0]->valor.'","moneda":"'.$moneda[0]->nombre.'","simbolo":"'.$moneda[0]->simbolo.'"}';

jacr1614
fuente
1

Si consulta una base de datos y necesita el conjunto de resultados en formato JSON, puede hacerlo así:

<?php

$db = mysqli_connect("localhost","root","","mylogs");
//MSG
$query = "SELECT * FROM logs LIMIT 20";
$result = mysqli_query($db, $query);
//Add all records to an array
$rows = array();
while($row = $result->fetch_array()){
    $rows[] = $row;
}
//Return result to jTable
$qryResult = array();
$qryResult['logs'] = $rows;
echo json_encode($qryResult);

mysqli_close($db);

?>

Para obtener ayuda para analizar el resultado con jQuery, eche un vistazo a este tutorial .

Eyece
fuente
1

Este es un script PHP simple para devolver la identificación masculina femenina y de usuario, ya que el valor json será cualquier valor aleatorio cuando llame al script json.php.

Espero esta ayuda gracias

<?php
header("Content-type: application/json");
$myObj=new \stdClass();
$myObj->user_id = rand(0, 10);
$myObj->male = rand(0, 5);
$myObj->female = rand(0, 5);
$myJSON = json_encode($myObj);
echo $myJSON;
?>
Bidyashish Kumar
fuente
El tipo de medio MIME para texto JSON es application / json
AA
0

Una manera fácil de formatear los objetos de su dominio a JSON es utilizar el serializador Marshal . Luego pase los datos json_encodey envíe el encabezado de tipo de contenido correcto para sus necesidades. Si está utilizando un marco como Symfony, no necesita ocuparse de configurar los encabezados manualmente. Allí puede usar el JsonResponse .

Por ejemplo, el tipo de contenido correcto para tratar con Javascript sería application/javascript.

O si necesita admitir algunos navegadores bastante antiguos, lo más seguro sería text/javascript.

Para todos los demás fines, como una aplicación móvil, utilícela application/jsoncomo Content-Type.

Aquí hay un pequeño ejemplo:

<?php
...
$userCollection = [$user1, $user2, $user3];

$data = Marshal::serializeCollectionCallable(function (User $user) {
    return [
        'username' => $user->getUsername(),
        'email'    => $user->getEmail(),
        'birthday' => $user->getBirthday()->format('Y-m-d'),
        'followers => count($user->getFollowers()),
    ];
}, $userCollection);

header('Content-Type: application/json');
echo json_encode($data);
Kingson
fuente
0

Siempre que intente devolver la respuesta JSON para API o asegúrese de tener los encabezados adecuados y también asegúrese de devolver datos JSON válidos.

Aquí está el script de muestra que le ayuda a devolver la respuesta JSON de la matriz PHP o del archivo JSON.

Script PHP (Código):

<?php

// Set required headers
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');

/**
 * Example: First
 *
 * Get JSON data from JSON file and retun as JSON response
 */

// Get JSON data from JSON file
$json = file_get_contents('response.json');

// Output, response
echo $json;

/** =. =.=. =.=. =.=. =.=. =.=. =.=. =.=. =.=. =.=. =.  */

/**
 * Example: Second
 *
 * Build JSON data from PHP array and retun as JSON response
 */

// Or build JSON data from array (PHP)
$json_var = [
  'hashtag' => 'HealthMatters',
  'id' => '072b3d65-9168-49fd-a1c1-a4700fc017e0',
  'sentiment' => [
    'negative' => 44,
    'positive' => 56,
  ],
  'total' => '3400',
  'users' => [
    [
      'profile_image_url' => 'http://a2.twimg.com/profile_images/1285770264/PGP_normal.jpg',
      'screen_name' => 'rayalrumbel',
      'text' => 'Tweet (A), #HealthMatters because life is cool :) We love this life and want to spend more.',
      'timestamp' => '{{$timestamp}}',
    ],
    [
      'profile_image_url' => 'http://a2.twimg.com/profile_images/1285770264/PGP_normal.jpg',
      'screen_name' => 'mikedingdong',
      'text' => 'Tweet (B), #HealthMatters because life is cool :) We love this life and want to spend more.',
      'timestamp' => '{{$timestamp}}',
    ],
    [
      'profile_image_url' => 'http://a2.twimg.com/profile_images/1285770264/PGP_normal.jpg',
      'screen_name' => 'ScottMili',
      'text' => 'Tweet (C), #HealthMatters because life is cool :) We love this life and want to spend more.',
      'timestamp' => '{{$timestamp}}',
    ],
    [
      'profile_image_url' => 'http://a2.twimg.com/profile_images/1285770264/PGP_normal.jpg',
      'screen_name' => 'yogibawa',
      'text' => 'Tweet (D), #HealthMatters because life is cool :) We love this life and want to spend more.',
      'timestamp' => '{{$timestamp}}',
    ],
  ],
];

// Output, response
echo json_encode($json_var);

Archivo JSON (DATOS JSON):

{
    "hashtag": "HealthMatters", 
    "id": "072b3d65-9168-49fd-a1c1-a4700fc017e0", 
    "sentiment": {
        "negative": 44, 
        "positive": 56
    }, 
    "total": "3400", 
    "users": [
        {
            "profile_image_url": "http://a2.twimg.com/profile_images/1285770264/PGP_normal.jpg", 
            "screen_name": "rayalrumbel", 
            "text": "Tweet (A), #HealthMatters because life is cool :) We love this life and want to spend more.", 
            "timestamp": "{{$timestamp}}"
        }, 
        {
            "profile_image_url": "http://a2.twimg.com/profile_images/1285770264/PGP_normal.jpg", 
            "screen_name": "mikedingdong", 
            "text": "Tweet (B), #HealthMatters because life is cool :) We love this life and want to spend more.", 
            "timestamp": "{{$timestamp}}"
        }, 
        {
            "profile_image_url": "http://a2.twimg.com/profile_images/1285770264/PGP_normal.jpg", 
            "screen_name": "ScottMili", 
            "text": "Tweet (C), #HealthMatters because life is cool :) We love this life and want to spend more.", 
            "timestamp": "{{$timestamp}}"
        }, 
        {
            "profile_image_url": "http://a2.twimg.com/profile_images/1285770264/PGP_normal.jpg", 
            "screen_name": "yogibawa", 
            "text": "Tweet (D), #HealthMatters because life is cool :) We love this life and want to spend more.", 
            "timestamp": "{{$timestamp}}"
        }
    ]
}

JSON Screeshot:

ingrese la descripción de la imagen aquí

Neeraj Singh
fuente
-1

Puedes usar esta pequeña biblioteca PHP . Envía los encabezados y le da un objeto para usarlo fácilmente.

Parece que :

<?php
// Include the json class
include('includes/json.php');

// Then create the PHP-Json Object to suits your needs

// Set a variable ; var name = {}
$Json = new json('var', 'name'); 
// Fire a callback ; callback({});
$Json = new json('callback', 'name'); 
// Just send a raw JSON ; {}
$Json = new json();

// Build data
$object = new stdClass();
$object->test = 'OK';
$arraytest = array('1','2','3');
$jsonOnly = '{"Hello" : "darling"}';

// Add some content
$Json->add('width', '565px');
$Json->add('You are logged IN');
$Json->add('An_Object', $object);
$Json->add("An_Array",$arraytest);
$Json->add("A_Json",$jsonOnly);

// Finally, send the JSON.

$Json->send();
?>
Alexis Paques
fuente