Llamar a una API REST en PHP

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 realmente no sé cómo llamar al servicio.

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

¿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 una API de descanso en PHP?

preguntado el 21 de marzo de 12 a las 10:03

12 Respuestas

Puede acceder a cualquier API REST con PHP cURL Extensión. Sin embargo, la Documentación 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;
}

Respondido 22 Jul 14, 09:07

@Michiel: el método de solicitud HTTP (GET, POST, PUT, etc.). Dependiendo de la API, se requieren diferentes métodos. es decir, GET para leer, POST para escribir. - Christoph Winkler

@Michiel $data es una matriz asociativa (data[fieldname] = value) que contiene los datos enviados al método api. - Christoph Winkler

¡Gracias por su gran ayuda! - Michiel

Nota la curl_close no se llama a la función, lo que podría causar un consumo adicional de memoria si se llama repetidamente a la función CallAPI. - Bart Verkoeijen

La respuesta de @colan a continuación es mucho mejor: le ahorra toda la molestia de crear su propio manejo de errores y métodos de envoltura. - Andreas

Si tiene una URL y su php lo admite, simplemente 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

respondido 21 mar '12, 10:03

Si el extremo REST devuelve un estado de error HTTP (p. ej., 401), el file_get_contents la función falla con una advertencia y devuelve nulo. Si el cuerpo contiene un mensaje de error, no podrá recuperarlo. - Bart Verkoeijen

Su principal inconveniente es que su instalación de PHP debe tener habilitados los envoltorios fopen para poder acceder a las URL. Si fopen wrappers no está habilitado, no podrá usar file_get_contents para solicitudes de servicios web. - Oriol

Los envoltorios fopen se encuentran entre las partes de PHP que ahora se ven como una vulnerabilidad, por lo que es probable que vea que algunos hosts lo deshabilitan. - marcus downing

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

He aquí 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

contestado el 06 de mayo de 14 a las 15:05

Cualquiera que todavía esté usando cURL nunca ha mirado de cerca esta opción. - Joshua David

Se ve bien. Pero, ¿qué pasa con la obtención de PNG? Para mosaicos de mapas. Solo puedo encontrar datos JSON mencionados en la página web que vinculó. - henrik erlandsson

@HenrikErlandsson, una búsqueda rápida en Google reveló lo que parece ser una solución decente. stackoverflow.com/questions/55881436/… - ChrisH

CURL es la forma más sencilla de hacerlo. 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);

respondido 21 mar '12, 10:03

Utiliza HTTPFUL

Httpful es una biblioteca PHP simple, encadenable y legible destinada a hacer que hablar HTTP sea sensato. Permite que el desarrollador se concentre en interactuar con las API en lugar de revisar las páginas curl set_opt y es un cliente PHP REST ideal.

Httpful incluye...

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

Ex.

Envíe 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";

Respondido el 08 de diciembre de 15 a las 07:12

Estoy tratando de usar HTTPFUL como solución y no estoy seguro de si puede analizar el json como $condition = $response->weather[0]->main; a menos que esté haciendo mal el lado de PHP - weteamsteve

Deberá saber si la API REST a la que está llamando admite GET or POST, o ambos métodos. El siguiente código es algo que funciona para mí, estoy llamando a mi propia API de servicio web, por lo que ya sé lo que toma la API y lo que devolverá. Es compatible con ambos GET y POST métodos, por lo que la información menos confidencial va al URL (GET), y la información como nombre de usuario y contraseña se envía como POST variables Además, todo pasa por encima HTTPS conexión.

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

Entonces, 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 file_get_contents() método como algunos de los usuarios aquí sugirieron, pero eso no funcionó bien para mí. descubrí el curl método para ser más rápido y más fiable.

respondido 20 nov., 18:15

Hay un montón de clientes en realidad. Uno de ellos es Plaga - mira esto. Y tenga en cuenta que estas llamadas REST son solicitudes http simples con varios métodos: GET, POST, PUT y DELETE.

Respondido 26 Jul 17, 05:07

como @Christoph Winkler mencionó, 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: cualquier.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)

contestado el 01 de mayo de 18 a las 00:05

Puede usar el file_get_contents para emitir cualquier http POST/PUT/DELETE/OPTIONS/HEAD métodos, además de los GET método como sugiere el nombre de la función.

¿Cómo publicar datos en PHP usando file_get_contents?

respondido 20 nov., 18:14

file_get_content es realmente una mala idea cuando se trata de API. stackoverflow.com/questions/13004805/… Puede establecer 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

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

respondido 13 nov., 18:09

Esta es la respuesta más subestimada en stackoverflow: maki kevin

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 un código de error + mensaje sin sentido.

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

Me encanta 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.

contestado el 07 de mayo de 15 a las 20:05

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 las API.

En primer lugar, define una entidad que define la estructura de los datos entrantes y salientes y la 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();

Respondido 02 ago 16, 10:08

Descargo de responsabilidad: usted es el autor si este paquete - Jonas Stensved

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.