Llamar a una API REST en PHP

317

Nuestro cliente me había dado una API REST a la que necesito hacer una llamada PHP. Pero, de hecho, la documentación proporcionada con la API es muy limitada, por lo que no sé cómo llamar al servicio.

Intenté buscarlo en Google, pero lo único que surgió fue un Yahoo! tutorial sobre cómo llamar al servicio. Sin mencionar los encabezados ni nada de información detallada.

¿Hay alguna información decente sobre cómo llamar a una API REST, o alguna documentación al respecto? Porque incluso en W3schools, solo describen el método SOAP. ¿Cuáles son las diferentes opciones para hacer API de descanso en PHP?

Michiel
fuente

Respuestas:

438

Puede acceder a cualquier API REST con la cURLextensión PHP . Sin embargo, la documentación de la API (métodos, parámetros, etc.) debe ser proporcionada por su cliente.

Ejemplo:

// Method: POST, PUT, GET etc
// Data: array("param" => "value") ==> index.php?param=value

function CallAPI($method, $url, $data = false)
{
    $curl = curl_init();

    switch ($method)
    {
        case "POST":
            curl_setopt($curl, CURLOPT_POST, 1);

            if ($data)
                curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
            break;
        case "PUT":
            curl_setopt($curl, CURLOPT_PUT, 1);
            break;
        default:
            if ($data)
                $url = sprintf("%s?%s", $url, http_build_query($data));
    }

    // Optional Authentication:
    curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
    curl_setopt($curl, CURLOPT_USERPWD, "username:password");

    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

    $result = curl_exec($curl);

    curl_close($curl);

    return $result;
}
Christoph Winkler
fuente
1
@Michiel: El método de solicitud HTTP (GET, POST, PUT, etc.). Dependiendo de la API, se requieren diferentes métodos. es decir, OBTENER para leer, POST para escribir.
Christoph Winkler
2
@Michiel $dataes una matriz asociativa (datos [nombre del campo] = valor) que contiene los datos enviados al método api.
Christoph Winkler
1
¡Gracias por su gran ayuda!
Michiel
2
Tenga en curl_closecuenta que no se llama a la función, lo que podría causar un consumo de memoria adicional si se llama repetidamente a la función CallAPI.
Bart Verkoeijen
1
La respuesta de @colan a continuación es mucho mejor: le ahorra toda la molestia de crear sus propios métodos de manejo de errores y envoltorios.
Andreas
186

Si tiene una URL y su php la admite, puede llamar a file_get_contents:

$response = file_get_contents('http://example.com/path/to/api/call?param1=5');

si $ response es JSON, use json_decode para convertirlo en una matriz php:

$response = json_decode($response);

si $ response es XML, use la clase simple_xml:

$response = new SimpleXMLElement($response);

http://sg2.php.net/manual/en/simplexml.examples-basic.php

Andreas Wong
fuente
30
Si el punto final REST devuelve un estado de error HTTP (por ejemplo, 401), la file_get_contentsfunción falla con una advertencia y devuelve nulo. Si el cuerpo contiene un mensaje de error, no puede recuperarlo.
Bart Verkoeijen
3
Su principal inconveniente es que su instalación de PHP debe tener habilitados los fopen wrappers para acceder a las URL. Si fopen wrappers no está habilitado, no podrá usar file_get_contents para solicitudes de servicios web.
Oriol
2
Los contenedores fopen se encuentran entre las partes de PHP que ahora se consideran una vulnerabilidad, por lo que es probable que algunos hosts lo deshabiliten.
Marcus Downing
153

Utiliza Guzzle . Es un "cliente HTTP HTTP que facilita el trabajo con HTTP / 1.1 y elimina el dolor de consumir servicios web". Trabajar con Guzzle es mucho más fácil que trabajar con cURL.

Aquí hay un ejemplo del sitio web:

$client = new GuzzleHttp\Client();
$res = $client->get('https://api.github.com/user', [
    'auth' =>  ['user', 'pass']
]);
echo $res->getStatusCode();           // 200
echo $res->getHeader('content-type'); // 'application/json; charset=utf8'
echo $res->getBody();                 // {"type":"User"...'
var_export($res->json());             // Outputs the JSON decoded data
colan
fuente
20
Quien todavía usa cURL nunca ha examinado de cerca esta opción.
JoshuaDavid
Parece agradable. ¿Pero qué hay de buscar PNG? Para mosaicos de mapas. Solo puedo encontrar datos JSON mencionados en la página web que ha vinculado.
Henrik Erlandsson el
20

CURL es el camino más sencillo. Aquí hay una simple llamada

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "THE URL TO THE SERVICE");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, POST DATA);
$result = curl_exec($ch);


print_r($result);
curl_close($ch);
Broncha
fuente
1
well @ erm3nda El OP dice "así que realmente no sé cómo llamar al servicio" NO Consiga la mejor forma de consumir una API REST.
Broncha
44
wow, pierdes tu esfuerzo y tiempo para darme una respuesta irónica en lugar de mejorar tu comentario Buena suerte de esa manera.
m3nda
2
Me encanta lo simple que es este. Sigue así
cyber8200
@Sadik POST DATA es solo un marcador de posición, deberá enviar los datos de su publicación allí
Broncha
12

Utilice HTTPFUL

Httpful es una biblioteca PHP simple, encadenable y legible destinada a hacer que hablar HTTP sea sensato. Le permite al desarrollador concentrarse en interactuar con las API en lugar de examinar las páginas curl set_opt y es un cliente PHP REST ideal.

Httpful incluye ...

  • Soporte de método HTTP legible (GET, PUT, POST, DELETE, HEAD y OPTIONS)
  • Encabezados personalizados
  • Análisis automático "inteligente"
  • Serialización automática de la carga útil
  • Autenticación básica
  • Autenticación de certificado del lado del cliente
  • Solicitar "Plantillas"

Ex.

Enviar una solicitud GET. Obtenga una respuesta JSON analizada automáticamente.

La biblioteca nota el tipo de contenido JSON en la respuesta y analiza automáticamente la respuesta en un objeto PHP nativo.

$uri = "https://www.googleapis.com/freebase/v1/mqlread?query=%7B%22type%22:%22/music/artist%22%2C%22name%22:%22The%20Dead%20Weather%22%2C%22album%22:%5B%5D%7D";
$response = \Httpful\Request::get($uri)->send();

echo 'The Dead Weather has ' . count($response->body->result->album) . " albums.\n";
Somnath Muluk
fuente
Estoy tratando de usar HTTPFUL como solución y no estoy seguro de si puede analizar el json como a $condition = $response->weather[0]->main;menos que solo esté haciendo mal el lado PHP
weteamsteve
9

Tendrá que saber si la API REST que está llamando soportes GETo POST, o ambos métodos. El código a continuación es algo que funciona para mí, estoy llamando a mi propia API de servicio web, por lo que ya sé qué toma la API y qué devolverá. Es compatible con ambos GETy con los POSTmétodos, por lo que la información menos sensible entra en el URL (GET), y la información como nombre de usuario y contraseña se envía como POSTvariables. Además, todo pasa por la HTTPSconexión.

Dentro del código API, codifico una matriz que quiero devolver al formato json, luego simplemente uso el comando PHP echo $my_json_variablepara que esa cadena json esté disponible para el cliente.

Como puede ver, mi API devuelve datos json, pero necesita saber (o mirar los datos devueltos para averiguar) en qué formato está la respuesta de la API.

Así es como me conecto a la API desde el lado del cliente:

$processed = FALSE;
$ERROR_MESSAGE = '';

// ************* Call API:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://www.myapi.com/api.php?format=json&action=subscribe&email=" . $email_to_subscribe);
curl_setopt($ch, CURLOPT_POST, 1);// set post data to true
curl_setopt($ch, CURLOPT_POSTFIELDS,"username=myname&password=mypass");   // post data
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$json = curl_exec($ch);
curl_close ($ch);

// returned json string will look like this: {"code":1,"data":"OK"}
// "code" may contain an error code and "data" may contain error string instead of "OK"
$obj = json_decode($json);

if ($obj->{'code'} == '1')
{
  $processed = TRUE;
}else{
  $ERROR_MESSAGE = $obj->{'data'};
}

...

if (!$processed && $ERROR_MESSAGE != '') {
    echo $ERROR_MESSAGE;
}

Por cierto, también traté de usar el file_get_contents()método que sugirieron algunos de los usuarios aquí, pero eso no funciona bien para mí. Descubrí que el curlmétodo es más rápido y más confiable.

Derek Gogol
fuente
5

Hay muchos clientes en realidad. Uno de ellos es Pest . Mira esto. Y tenga en cuenta que estas llamadas REST son simples solicitudes HTTP con varios métodos: GET, POST, PUT y DELETE.

muerto
fuente
4

Puede usar file_get_contentspara emitir cualquier POST/PUT/DELETE/OPTIONS/HEADmétodo http , además del GETmétodo como sugiere el nombre de la función.

¿Cómo publicar datos en PHP usando file_get_contents?

Chuan Ma
fuente
1
file_get_content es realmente una mala idea cuando se trata de API. stackoverflow.com/questions/13004805/… Puede configurar un método personalizado como file_get_contents_curl y usarlo en lugar de una solución php simple. stackoverflow.com/questions/8540800/…
Eryk Wróbel
3

Si está utilizando Symfony, hay un excelente paquete de cliente de descanso que incluso incluye todas las ~ 100 excepciones y las arroja en lugar de devolver algún código de error + mensaje sin sentido.

Realmente deberías verificarlo: https://github.com/CircleOfNice/CiRestClientBundle

Amo la interfaz:

try {
    $restClient = new RestClient();
    $response   = $restClient->get('http://www.someUrl.com');
    $statusCode = $response->getStatusCode();
    $content    = $response->getContent();
} catch(OperationTimedOutException $e) {
    // do something
}

Funciona para todos los métodos http.

Tobias
fuente
2

como @Christoph Winkler mencionó que esta es una clase base para lograrlo:

curl_helper.php

// This class has all the necessary code for making API calls thru curl library

class CurlHelper {

// This method will perform an action/method thru HTTP/API calls
// Parameter description:
// Method= POST, PUT, GET etc
// Data= array("param" => "value") ==> index.php?param=value
public static function perform_http_request($method, $url, $data = false)
{
    $curl = curl_init();

    switch ($method)
    {
        case "POST":
            curl_setopt($curl, CURLOPT_POST, 1);

            if ($data)
                curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
            break;
        case "PUT":
            curl_setopt($curl, CURLOPT_PUT, 1);
            break;
        default:
            if ($data)
                $url = sprintf("%s?%s", $url, http_build_query($data));
    }

    // Optional Authentication:
    //curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
    //curl_setopt($curl, CURLOPT_USERPWD, "username:password");

    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

    $result = curl_exec($curl);

    curl_close($curl);

    return $result;
}

}

Entonces siempre puede incluir el archivo y usarlo, por ejemplo: any.php

    require_once("curl_helper.php");
    ...
    $action = "GET";
    $url = "api.server.com/model"
    echo "Trying to reach ...";
    echo $url;
    $parameters = array("param" => "value");
    $result = CurlHelper::perform_http_request($action, $url, $parameters);
    echo print_r($result)
d1jhoni1b
fuente
0

Si está abierto a usar herramientas de terceros, eche un vistazo a esta: https://github.com/CircleOfNice/DoctrineRestDriver

Esta es una forma completamente nueva de trabajar con API.

En primer lugar, define una entidad que define la estructura de los datos entrantes y salientes y los anota con fuentes de datos:

/*
 * @Entity
 * @DataSource\Select("http://www.myApi.com/products/{id}")
 * @DataSource\Insert("http://www.myApi.com/products")
 * @DataSource\Select("http://www.myApi.com/products/update/{id}")
 * @DataSource\Fetch("http://www.myApi.com/products")
 * @DataSource\Delete("http://www.myApi.com/products/delete/{id}")
 */
class Product {
    private $name;

    public function setName($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

Ahora es bastante fácil comunicarse con la API REST:

$product = new Product();
$product->setName('test');
// sends an API request POST http://www.myApi.com/products ...
$em->persist($product);
$em->flush();

$product->setName('newName');
// sends an API request UPDATE http://www.myApi.com/products/update/1 ...
$em->flush();
Tobias
fuente
-1

Puede utilizar POSTMAN, una aplicación que facilita las API. Rellene los campos de solicitud y luego generará código para usted en diferentes idiomas. Simplemente haga clic en el código en el lado derecho y seleccione su idioma preferido.

Xhuljo
fuente