PHP'de bir REST API'sini çağırma


317

Müşterimiz bana bir PHP çağrı yapmak için gereken bir REST API vermişti. Ama aslına bakılırsa, API ile verilen belgeler çok sınırlıdır, bu yüzden servisi nasıl arayacağımı gerçekten bilmiyorum.

Google'a denedim, ancak ortaya çıkan tek şey zaten süresi dolmuş bir Yahoo! servisi nasıl arayacağınıza dair öğretici. Başlıklardan veya derinlemesine bilgi içeren herhangi bir şeyden bahsetmemek.

Bir REST API'sini nasıl arayacağınız veya bununla ilgili bazı belgeler hakkında iyi bilgiler var mı? Çünkü W3schools'ta bile, sadece SOAP yöntemini tanımlarlar. PHP'de dinlenme API'si yapmak için farklı seçenekler nelerdir?

Yanıtlar:


438

PHP cURLUzantısı ile herhangi bir REST API'sine erişebilirsiniz . Ancak, API Belgeleri (Yöntemler, Parametreler vb.) Müşteriniz tarafından sağlanmalıdır!

Misal:

// 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;
}

1
@Michiel: HTTP İstek Yöntemi (GET, POST, PUT vb.). API'ya bağlı olarak farklı yöntemler gerekir. yani okuma için GET, yazma için POST.
Christoph Winkler

2
@Michiel $data, api yöntemine gönderilen verileri tutan ilişkilendirilebilir bir dizidir (data [fieldname] = değer).
Christoph Winkler

1
Büyük yardımınız için teşekkürler!
Michiel

2
Not, curl_closeişlev çağrılmaz, CallAPI işlevi tekrar tekrar çağrılırsa fazladan bellek tüketimine neden olabilir.
Bart Verkoeijen

1
Aşağıdaki @colan'ın cevabı çok daha iyi - kendi hata işleme ve sarma yöntemlerini oluştururken tüm zorluklardan kurtarır.
Andreas

186

Bir url'niz varsa ve php'niz destekliyorsa, sadece file_get_contents'ı arayabilirsiniz:

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

$ response JSON ise, php dizisine dönüştürmek için json_decode kullanın:

$response = json_decode($response);

$ response XML ise, simple_xml sınıfını kullanın:

$response = new SimpleXMLElement($response);

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


30
REST uç noktası bir HTTP hata durumu döndürüyorsa (örn. 401), file_get_contentsişlev bir uyarı ile başarısız olur ve null değerini döndürür. Gövde bir hata mesajı içeriyorsa, geri alamazsınız.
Bart Verkoeijen

3
Ana dezavantajı, PHP kurulumunuzda URL'lere erişmek için fopen sarmalayıcılarının etkinleştirilmiş olmasıdır. Fopen sarmalayıcıları etkinleştirilmezse, Web hizmetleri istekleri için file_get_contents öğesini kullanamazsınız.
Oriol

2
fopen sarmalayıcıları PHP'nin şu anda bir güvenlik açığı olarak görülen bölümleri arasındadır, bu nedenle bazı ana bilgisayarların devre dışı bıraktığını görebilirsiniz.
Marcus Downing

153

Guzzle kullanın . "HTTP / 1.1 ile çalışmayı kolaylaştıran ve web hizmetlerini tüketen acıyı ortadan kaldıran bir PHP HTTP istemcisi". Guzzle ile çalışmak cURL ile çalışmaktan çok daha kolaydır.

Web sitesinden bir örnek:

$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

20
Hâlâ cURL kullanan herkes bu seçeneğe asla yakından bakmadı.
JoshuaDavid

Hoş görünüyor. Peki PNG'leri getirmeye ne dersiniz? Harita döşemeleri için. Yalnızca bağlandığınız web sayfasında belirtilen JSON verilerini bulabilirim.
Henrik Erlandsson

20

CURL, gitmenin en basit yoludur. İşte basit bir çağrı

$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);

1
well @ erm3nda OP diyor ki "gerçekten nasıl servis çağırmak bilmiyorum" DEĞİL Bana bir REST api tüketmek için en iyi yolu alın.
Broncha

4
wow, yorumunuzu daha iyi hale getirmek için bana ironik bir cevap vermek için çaba ve zamanınızı boşa harcıyorsunuz. Bu şekilde iyi şanslar.
m3nda

2
Bunun ne kadar basit olduğunu seviyorum. Keep it up
cyber8200

@Sadik POST DATA sadece bir yer tutucudur, posta bilgilerinizi buraya göndermeniz gerekir
Broncha

12

HTTPFUL kullan

Httpful, konuşan HTTP aklı başında olmayı amaçlayan basit, zincirlenebilir, okunabilir bir PHP kütüphanesidir. Geliştiricinin set_opt sayfalarını kıvırmak yerine API'larla etkileşime odaklanmasını sağlar ve ideal bir PHP REST istemcisidir.

Httpful içerir ...

  • Okunabilir HTTP Yöntemi Desteği (GET, PUT, POST, DELETE, HEAD ve OPTIONS)
  • Özel Başlıklar
  • Otomatik "Akıllı" Ayrıştırma
  • Otomatik Yükü Dizileştirme
  • Temel Yetkilendirme
  • İstemci Tarafı Sertifika Yetkilendirmesi
  • "Şablonlar" isteyin

Ör.

Bir GET isteği gönderin. Otomatik olarak ayrıştırılmış JSON yanıtı alın.

Kitaplık, yanıtta JSON İçerik Türü'nü fark eder ve yanıtı otomatik olarak yerel bir PHP nesnesine ayrıştırır.

$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";

Ben bir çözüm olarak HTTPFUL kullanmaya çalışıyorum ve ben $condition = $response->weather[0]->main;sadece PHP tarafı yanlış yapmıyoruz gibi json ayrıştırabilirsiniz emin değilim
weteamsteve

9

Sen destekleri aradığınız REST API olmadığını bilmek gerekir GETya POST, ya her iki yöntem. Aşağıdaki kod benim için çalışan bir şey, kendi web hizmeti API çağırıyorum, bu yüzden zaten API ne alır ve ne döneceğini biliyorum. Hem destekler GETve POSTaz hassas bilgileri girer, böylece yöntemleri URL (GET)ve kullanıcı adı ve şifre gibi bilgileri olarak gönderildiğinden POSTdeğişkenler. Ayrıca, her şey HTTPSbağlantı üzerinden geçer .

API kodunun içinde, json formatına dönmek istediğim bir diziyi kodluyorum, sonra sadece PHP komutunu kullanıyorum echo $my_json_variable json dizesini istemciye sunmak için .

Gördüğünüz gibi, API'm json verilerini döndürüyor, ancak API'dan yanıtın hangi formatta olduğunu bilmeniz (veya döndürülen verilere bakmanız) gerekiyor.

İstemci tarafından API'ye şu şekilde bağlanırım:

$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;
}

BTW, ben de file_get_contents()burada bazı kullanıcıların önerdiği gibi yöntemi kullanmaya çalıştım , ama bu benim için iyi çalışmıyor. Daha curlhızlı ve daha güvenilir bir yöntem buldum .


5

Aslında pek çok müşteri var. Bunlardan biri Pest - şuna bir bak . Ve bu REST çağrıları çeşitli yöntemler ile basit http isteği olduğunu unutmayın: GET, POST, PUT ve DELETE.


4

Buna ek olarak, file_get_contentsherhangi bir http POST/PUT/DELETE/OPTIONS/HEADyöntemini yayınlamak için kullanabilirsiniz .GET işlev adından da anlaşılacağı gibi yöntemle.

PHP'de file_get_contents kullanarak veri nasıl gönderilir?


1
API söz konusu olduğunda file_get_content gerçekten kötü bir fikirdir. stackoverflow.com/questions/13004805/… file_get_contents_curl gibi özel bir yöntem ayarlayabilir ve bunu düz php çözümü yerine kullanabilirsiniz. stackoverflow.com/questions/8540800/…
Eryk Wróbel

3

Symfony kullanıyorsanız, ~ 100 istisnaların tümünü bile içeren ve bazı anlamsız hata kodu + mesajı döndürmek yerine bunları atan harika bir dinlenme istemci paketi var.

Gerçekten kontrol etmelisiniz: https://github.com/CircleOfNice/CiRestClientBundle

Arayüzü seviyorum:

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

Tüm http yöntemleri için çalışır.


2

@Christoph Winkler'den bahsettiği gibi, bunu başarmak için bir temel sınıf:

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;
}

}

Daha sonra dosyayı her zaman dahil edebilir ve kullanabilirsiniz, örneğin: 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)

0

Üçüncü taraf araçlarını kullanmaya açıksanız, buna bir göz atabilirsiniz : https://github.com/CircleOfNice/DoctrineRestDriver

Bu, API'larla çalışmanın tamamen yeni bir yoludur.

Her şeyden önce, gelen ve giden verilerin yapısını tanımlayan ve veri kaynaklarıyla açıklama ekleyen bir varlık tanımlarsınız:

/*
 * @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;
    }
}

Şimdi REST API ile iletişim kurmak oldukça kolay:

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

-1

API'leri kolaylaştıran bir uygulama olan POSTMAN ile gidebilirsiniz. İstek alanlarını doldurun, ardından sizin için farklı dillerde kod oluşturur. Sağ taraftaki kodu tıklamanız ve tercih ettiğiniz dili seçmeniz yeterlidir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.