Panggil API REST dalam PHP

317

Klien kami telah memberi saya API REST ke mana saya harus menelepon PHP. Tetapi kenyataannya dokumentasi yang diberikan dengan API sangat terbatas, jadi saya tidak benar-benar tahu cara menelepon layanan.

Saya sudah mencoba ke Google, tetapi satu-satunya yang muncul adalah Yahoo! tutorial tentang cara memanggil layanan. Tidak menyebutkan header atau informasi mendalam apa pun.

Apakah ada informasi yang layak seputar cara memanggil REST API, atau dokumentasi tentangnya? Karena bahkan pada W3schools, mereka hanya menjelaskan metode SOAP. Apa sajakah pilihan berbeda untuk membuat API sisanya di PHP?

Michiel
sumber

Jawaban:

438

Anda dapat mengakses API REST dengan cURLEkstensi PHP . Namun, Dokumentasi API (Metode, Parameter, dll.) Harus disediakan oleh Klien Anda!

Contoh:

// 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
sumber
1
@Michiel: Metode Permintaan HTTP (GET, POST, PUT dll.). Bergantung pada API, ada beberapa metode yang diperlukan. yaitu GET untuk membaca, POST untuk menulis.
Christoph Winkler
2
@ Michael $dataadalah array asosiatif (data [fieldname] = nilai) yang menyimpan data yang dikirim ke metode api.
Christoph Winkler
1
Terima kasih atas bantuan Anda!
Michiel
2
Catatan, curl_closefungsi tidak dipanggil, apa yang bisa menyebabkan konsumsi memori tambahan jika fungsi CallAPI dipanggil berulang kali.
Bart Verkoeijen
1
Jawaban dari @colan di bawah ini jauh lebih baik - ini menyelamatkan Anda dari kerumitan dengan membangun metode penanganan dan pembungkus kesalahan Anda sendiri.
Andreas
186

Jika Anda memiliki url dan php Anda mendukungnya, Anda bisa memanggil file_get_contents:

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

jika $ response adalah JSON, gunakan json_decode untuk mengubahnya menjadi array php:

$response = json_decode($response);

jika $ response adalah XML, gunakan kelas simple_xml:

$response = new SimpleXMLElement($response);

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

Andreas Wong
sumber
30
Jika titik akhir REST mengembalikan status kesalahan HTTP (misalnya 401), file_get_contentsfungsi gagal dengan peringatan dan mengembalikan nol. Jika isi pesan kesalahan, Anda tidak dapat mengambilnya.
Bart Verkoeijen
3
Kerugian utamanya adalah instalasi PHP Anda harus mengaktifkan pembungkus fopen agar dapat mengakses URL. Jika pembungkus fopen tidak diaktifkan, Anda tidak akan dapat menggunakan file_get_contents untuk permintaan layanan Web.
Oriol
2
pembungkus fopen adalah bagian dari PHP yang sekarang dianggap sebagai kerentanan, sehingga Anda mungkin melihat beberapa host menonaktifkannya.
Marcus Downing
153

Gunakan Guzzle . Ini adalah "klien HTTP PHP yang membuatnya mudah untuk bekerja dengan HTTP / 1.1 dan menghilangkan rasa sakit karena mengkonsumsi layanan web". Bekerja dengan Guzzle jauh lebih mudah daripada bekerja dengan CURL.

Berikut ini contoh dari situs 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
sumber
20
Siapa pun yang masih menggunakan cURL tidak pernah melihat dari dekat opsi ini.
JoshuaDavid
Sepertinya bagus. Tapi bagaimana dengan mengambil PNG? Untuk ubin peta. Saya hanya dapat menemukan data JSON yang disebutkan di halaman web yang Anda tautkan.
Henrik Erlandsson
20

CURL adalah cara termudah untuk pergi. Ini panggilan sederhana

$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
sumber
1
well @ erm3nda OP mengatakan "jadi saya tidak benar-benar tahu bagaimana memanggil layanan" BUKAN cara terbaik untuk mengkonsumsi api REST.
Broncha
4
wow, Anda membuang-buang usaha dan waktu Anda untuk memberi saya balasan yang ironis sebagai gantinya untuk membuat komentar Anda lebih baik. Semoga beruntung dengan cara itu.
m3nda
2
Cinta betapa sederhananya ini. Pertahankan
cyber8200
@Sadik POST DATA hanyalah pemegang tempat, Anda harus mengirim data pos Anda di sana
Broncha
12

Gunakan HTTPFUL

Httpful adalah pustaka PHP yang sederhana, mudah dibaca, dan dapat dibaca yang dimaksudkan untuk membuat berbicara HTTP menjadi waras. Ini memungkinkan pengembang fokus pada interaksi dengan API alih-alih menyaring halaman set_opt curl dan merupakan klien PHP REST yang ideal.

Httpful termasuk ...

  • Dukungan Metode HTTP yang Dapat Dibaca (DAPATKAN, PUT, POST, HAPUS, KEPALA, dan OPSI)
  • Header Khusus
  • Parsing "Cerdas" otomatis
  • Serialisasi muatan otomatis
  • Auth dasar
  • Sertifikat Sisi Klien Auth
  • Minta "Templat"

Ex.

Kirim permintaan GET. Dapatkan respons JSON yang diuraikan secara otomatis.

Perpustakaan memperhatikan Tipe Konten JSON dalam respons dan secara otomatis mem-parsing respons ke objek PHP asli.

$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
sumber
Saya mencoba menggunakan HTTPFUL sebagai solusi dan saya tidak yakin apakah itu dapat mem-parsing json seperti $condition = $response->weather[0]->main;kecuali saya hanya melakukan kesalahan pada sisi PHP
weteamsteve
9

Anda perlu tahu apakah REST API yang Anda panggil mendukung GETatau POST, atau kedua metode tersebut. Kode di bawah ini adalah sesuatu yang berfungsi untuk saya, saya memanggil API layanan web saya sendiri, jadi saya sudah tahu apa yang API ambil dan apa yang akan kembali. Ini mendukung keduanya GETdan POSTmetode, sehingga info yang kurang sensitif masuk ke URL (GET), dan info seperti nama pengguna dan kata sandi dikirimkan sebagai POSTvariabel. Juga, semuanya berjalan melalui HTTPSkoneksi.

Di dalam kode API, saya menyandikan larik yang ingin saya kembalikan ke format json, kemudian cukup gunakan perintah PHP echo $my_json_variableuntuk membuat string json itu tersedia untuk klien.

Jadi seperti yang Anda lihat, API saya mengembalikan data json, tetapi Anda perlu tahu (atau melihat data yang dikembalikan untuk mengetahui) apa format respons dari API.

Inilah cara saya terhubung ke API dari sisi klien:

$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, saya juga mencoba menggunakan file_get_contents()metode seperti yang disarankan beberapa pengguna di sini, tapi itu tidak berfungsi dengan baik untuk saya. Saya menemukan curlmetode menjadi lebih cepat dan lebih dapat diandalkan.

Derek Gogol
sumber
5

Sebenarnya ada banyak klien. Salah satunya adalah Pest - lihat ini. Dan perlu diingat bahwa panggilan REST ini adalah permintaan http sederhana dengan berbagai metode: GET, POST, PUT dan DELETE.

deadrunk
sumber
4

Anda dapat menggunakan file_get_contentsuntuk mengeluarkan POST/PUT/DELETE/OPTIONS/HEADmetode http apa pun , selain GETmetode seperti yang disarankan nama fungsi.

Bagaimana cara mengirim data dalam PHP menggunakan file_get_contents?

Chuan Ma
sumber
1
file_get_content adalah ide yang buruk ketika datang ke API. stackoverflow.com/questions/13004805/… Anda dapat mengatur metode khusus seperti file_get_contents_curl dan menggunakannya sebagai pengganti solusi php biasa. stackoverflow.com/questions/8540800/…
Eryk Wróbel
3

Jika Anda menggunakan Symfony, ada bundel klien yang sangat bagus yang bahkan menyertakan semua ~ 100 pengecualian dan melemparkannya alih-alih mengembalikan beberapa pesan + kode kesalahan yang tidak berarti.

Anda harus benar-benar memeriksanya: https://github.com/CircleOfNice/CiRestClientBundle

Saya suka antarmuka:

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

Bekerja untuk semua metode http.

Tobias
sumber
2

seperti @Christoph Winkler sebutkan ini adalah kelas dasar untuk mencapainya:

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

}

Maka Anda selalu dapat memasukkan file dan menggunakannya misalnya: 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
sumber
0

Jika Anda terbuka untuk menggunakan alat pihak ketiga, Anda akan melihatnya di sini: https://github.com/CircleOfNice/DoctrineRestDriver

Ini adalah cara yang sepenuhnya baru untuk bekerja dengan API.

Pertama-tama Anda mendefinisikan entitas yang mendefinisikan struktur data yang masuk dan keluar dan membubuhi keterangan dengan sumber data:

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

Sekarang cukup mudah untuk berkomunikasi dengan 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
sumber
-1

Anda dapat menggunakan POSTMAN, aplikasi yang memudahkan API. Isi kolom permintaan dan kemudian akan menghasilkan kode untuk Anda dalam berbagai bahasa. Cukup klik kode di sisi kanan dan pilih bahasa pilihan Anda.

Xhuljo
sumber