Gọi API REST trong PHP


317

Khách hàng của chúng tôi đã cho tôi một API REST mà tôi cần để thực hiện cuộc gọi PHP tới. Nhưng vì thực tế, tài liệu được cung cấp với API rất hạn chế, vì vậy tôi không thực sự biết cách gọi dịch vụ.

Tôi đã thử Google, nhưng điều duy nhất xuất hiện là một Yahoo! hướng dẫn cách gọi dịch vụ. Không đề cập đến các tiêu đề hoặc bất cứ điều gì trong thông tin chuyên sâu.

Có bất kỳ thông tin phù hợp nào về cách gọi API REST hoặc một số tài liệu về nó không? Bởi vì ngay cả trên W3schools, họ chỉ mô tả phương pháp SOAP. Các tùy chọn khác nhau để tạo API còn lại trong PHP là gì?

Câu trả lời:


438

Bạn có thể truy cập bất kỳ API REST nào với cURLTiện ích mở rộng PHP . Tuy nhiên, Tài liệu API (Phương thức, Thông số, v.v.) phải được Khách hàng của bạn cung cấp!

Thí dụ:

// 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: Phương thức yêu cầu HTTP (GET, POST, PUT, v.v.). Tùy thuộc vào API, có các phương pháp khác nhau được yêu cầu. tức là NHẬN để đọc, POST để viết.
Christoph Winkler

2
@Michiel $datalà một mảng kết hợp (data [fieldname] = value) chứa dữ liệu được gửi đến phương thức api.
Christoph Winkler

1
Cảm ơn sự giúp đỡ tuyệt vời của bạn!
Michiel

2
Lưu ý, curl_closechức năng này không được gọi, điều gì có thể gây ra tiêu thụ thêm bộ nhớ nếu chức năng CallAPI được gọi liên tục.
Bart Verkoeijen

1
Câu trả lời từ @colan dưới đây là cách tốt hơn - nó giúp bạn tiết kiệm toàn bộ rắc rối với việc xây dựng các phương thức xử lý lỗi và trình bao bọc của riêng bạn.
Andreas

186

Nếu bạn có một url và php của bạn hỗ trợ nó, bạn có thể gọi file_get_contents:

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

nếu $ reply là JSON, hãy sử dụng json_decode để biến nó thành mảng php:

$response = json_decode($response);

nếu $ reply là XML, hãy sử dụng lớp Simple_xml:

$response = new SimpleXMLElement($response);

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


30
Nếu điểm cuối REST trả về trạng thái lỗi HTTP (ví dụ: 401), file_get_contentschức năng sẽ thất bại với cảnh báo và trả về null. Nếu phần thân chứa thông báo lỗi, bạn không thể truy xuất nó.
Bart Verkoeijen

3
Hạn chế chính của nó là cài đặt PHP của bạn phải bật trình bao bọc fopen để truy cập URL. Nếu trình bao bọc fopen không được bật, bạn sẽ không thể sử dụng file_get_contents cho các yêu cầu dịch vụ Web.
Oriol

2
Các trình bao bọc fopen là một trong những phần của PHP hiện được xem là một lỗ hổng, vì vậy bạn có thể thấy một số máy chủ vô hiệu hóa nó.
Marcus xuống

153

Sử dụng Gạc . Đó là "Máy khách HTTP PHP giúp dễ dàng làm việc với HTTP / 1.1 và giảm bớt việc sử dụng các dịch vụ web". Làm việc với Guheads dễ dàng hơn nhiều so với làm việc với cURL.

Đây là một ví dụ từ trang 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

20
Bất cứ ai vẫn đang sử dụng cURL chưa bao giờ xem xét kỹ về tùy chọn này.
JoshuaDavid

Có vẻ tốt đẹp. Nhưng những gì về tìm nạp PNG? Đối với gạch bản đồ. Tôi chỉ có thể tìm thấy dữ liệu JSON được đề cập tại trang web bạn liên kết.
Henrik Erlandsson

20

CURL là cách đơn giản nhất để đi. Đây là một cuộc gọi đơn giản

$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 đang nói "vì vậy tôi thực sự không biết cách gọi dịch vụ" KHÔNG cho tôi cách tốt nhất để sử dụng api REST.
Broncha

4
wow, thay vào đó bạn lãng phí công sức và thời gian của mình để trả lời tôi một cách mỉa mai để làm cho nhận xét của bạn tốt hơn. Chúc may mắn theo cách đó.
m3nda

2
Tình yêu này đơn giản làm sao. Giữ nó lên
cyber8200

@Sadik POST DATA chỉ là một người giữ chỗ, bạn sẽ cần gửi dữ liệu bài đăng của mình ở đó
Broncha

12

Sử dụng HTTPFUL

Httpful là một thư viện PHP đơn giản, có thể xâu chuỗi, có thể đọc được nhằm mục đích tạo ra tiếng nói HTTP lành mạnh. Nó cho phép nhà phát triển tập trung vào việc tương tác với các API thay vì sàng lọc thông qua các trang set_opt và là một ứng dụng PHP REST lý tưởng.

Httpful bao gồm ...

  • Hỗ trợ phương thức HTTP có thể đọc được (NHẬN, PUT, POST, XÓA, ĐẦU và TÙY CHỌN)
  • Tiêu đề tùy chỉnh
  • Phân tích cú pháp "thông minh" tự động
  • Tự động hóa tải tuần tự
  • Xác thực cơ bản
  • Chứng chỉ phía khách hàng Auth
  • Yêu cầu "Mẫu"

Ví dụ.

Gửi một yêu cầu NHẬN. Nhận phản hồi JSON được phân tích tự động.

Thư viện thông báo Kiểu nội dung JSON trong phản hồi và tự động phân tích cú pháp phản hồi thành một đối tượng PHP gốc.

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

Tôi đang cố gắng sử dụng HTTPFUL như một giải pháp và tôi không chắc liệu nó có thể phân tích cú pháp như thế $condition = $response->weather[0]->main;không trừ khi tôi chỉ làm sai về phía PHP
weteamsteve

9

Bạn sẽ cần biết API REST mà bạn đang gọi hỗ trợ GEThoặc POSThoặc cả hai phương thức. Mã dưới đây là một cái gì đó phù hợp với tôi, tôi đang gọi API dịch vụ web của riêng tôi, vì vậy tôi đã biết API lấy gì và nó sẽ trả về cái gì. Nó hỗ trợ cả hai GETPOSTphương thức, vì vậy thông tin ít nhạy cảm đi vào URL (GET)và thông tin như tên người dùng và mật khẩu được gửi dưới dạng POSTbiến. Ngoài ra, tất cả mọi thứ đi qua HTTPSkết nối.

Bên trong mã API, tôi mã hóa một mảng mà tôi muốn trở về định dạng json, sau đó chỉ cần sử dụng lệnh PHP echo $my_json_variableđể làm cho chuỗi json đó có sẵn cho máy khách.

Vì vậy, như bạn có thể thấy, API của tôi trả về dữ liệu json, nhưng bạn cần biết (hoặc nhìn vào dữ liệu được trả về để tìm hiểu) định dạng phản hồi từ API là gì.

Đây là cách tôi kết nối với API từ phía khách hàng:

$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, tôi cũng đã thử sử dụng file_get_contents()phương pháp như một số người dùng ở đây đã đề xuất, nhưng điều đó không hiệu quả với tôi. Tôi tìm ra curlphương pháp để nhanh hơn và đáng tin cậy hơn.


5

Có rất nhiều khách hàng thực sự. Một trong số đó là Pest - hãy kiểm tra điều này. Và hãy nhớ rằng các cuộc gọi REST này là yêu cầu http đơn giản với nhiều phương thức khác nhau: GET, POST, PUT và DELETE.


4

Bạn có thể sử dụng file_get_contentsđể phát hành bất kỳ POST/PUT/DELETE/OPTIONS/HEADphương thức http nào , ngoài GETphương thức như tên hàm gợi ý.

Làm cách nào để đăng dữ liệu trong PHP bằng file_get_contents?


1
file_get_content thực sự là ý tưởng tồi khi nói đến API. stackoverflow.com/questions/13004805/ đá Bạn có thể đặt phương thức tùy chỉnh như file_get_contents_curl và sử dụng nó thay vì giải pháp php đơn giản. stackoverflow.com/questions/8540800/
Mạnh

3

Nếu bạn đang sử dụng Symfony, có một gói ứng dụng khách tuyệt vời thậm chí bao gồm tất cả ~ 100 ngoại lệ và ném chúng thay vì trả về một số thông báo mã + lỗi vô nghĩa.

Bạn thực sự nên kiểm tra nó: https://github.com/CircleOfNice/CiRestClientBundle

Tôi thích giao diện:

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

Hoạt động cho tất cả các phương pháp http.


2

như @Christoph Winkler đã đề cập đây là lớp cơ sở để đạt được nó:

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

}

Sau đó, bạn luôn có thể bao gồm tệp và sử dụng nó, ví dụ: 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

Nếu bạn đang mở để sử dụng các công cụ của bên thứ ba, bạn sẽ xem cái này: https://github.com/CircleOfNice/DoctrineRestDriver

Đây là một cách hoàn toàn mới để làm việc với các API.

Trước hết, bạn xác định một thực thể xác định cấu trúc dữ liệu đến và đi và chú thích nó với các nguồn dữ liệu:

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

Bây giờ thật dễ dàng để giao tiếp với 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();

-1

Bạn có thể đi với POSTMAN, một ứng dụng giúp API dễ dàng. Điền vào các trường yêu cầu và sau đó nó sẽ tạo mã cho bạn bằng các ngôn ngữ khác nhau. Chỉ cần nhấp vào mã ở phía bên phải và chọn ngôn ngữ ưa thích của bạn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.