เรียก REST API ใน PHP


317

ลูกค้าของเราให้ REST API แก่ฉันซึ่งฉันจำเป็นต้องโทรหา PHP แต่แท้จริงแล้วเอกสารที่ให้มากับ API นั้นมี จำกัด มากดังนั้นฉันจึงไม่รู้วิธีเรียกใช้บริการ

ฉันได้ลองใช้ Google แล้ว แต่สิ่งเดียวที่เกิดขึ้นคือ Yahoo! หมดอายุแล้ว การสอนเกี่ยวกับวิธีการบริการ ไม่พูดถึงส่วนหัวหรือข้อมูลเชิงลึกใด ๆ

มีข้อมูลที่เหมาะสมเกี่ยวกับวิธีเรียก REST API หรือเอกสารบางอย่างเกี่ยวกับมันหรือไม่? เพราะแม้แต่ใน W3schools พวกเขาก็อธิบายวิธีการ SOAP เท่านั้น ตัวเลือกในการสร้าง API พักผ่อนใน PHP แตกต่างกันอย่างไร

คำตอบ:


438

คุณสามารถเข้าถึง REST API ได้ด้วย PHPs cURLExtension อย่างไรก็ตามต้องมีเอกสาร API (วิธีการพารามิเตอร์ ฯลฯ ) จากลูกค้าของคุณ!

ตัวอย่าง:

// 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 (GET, POST, PUT ฯลฯ ) ขึ้นอยู่กับ API มีวิธีการต่าง ๆ ที่จำเป็น เช่นรับการอ่าน POST สำหรับการเขียน
Christoph Winkler

2
@Michiel $dataเป็นอาร์เรย์ที่เชื่อมโยง (data [fieldname] = value) ซึ่งเก็บข้อมูลที่ส่งไปยังเมธอด api
Christoph Winkler

1
ขอบคุณสำหรับความช่วยเหลือที่ดีของคุณ!
Michiel

2
หมายเหตุcurl_closeฟังก์ชั่นจะไม่ถูกเรียกใช้สิ่งที่อาจทำให้เกิดการใช้หน่วยความจำเพิ่มเติมหากเรียกใช้ฟังก์ชัน CallAPI ซ้ำ ๆ
Bart Verkoeijen

1
คำตอบจาก @colan ด้านล่างนั้นดีกว่า - ช่วยให้คุณไม่ต้องวุ่นวายกับการสร้างข้อผิดพลาดและวิธีการห่อหุ้ม
Andreas

186

หากคุณมี URL และ php ของคุณรองรับคุณสามารถโทรหา file_get_contents:

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

ถ้า $ response คือ JSON ให้ใช้ json_decode เพื่อแปลงเป็น php array:

$response = json_decode($response);

ถ้า $ response เป็น XML ให้ใช้ simple_xml class:

$response = new SimpleXMLElement($response);

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


30
หาก REST endpoint ส่งคืนสถานะข้อผิดพลาด HTTP (เช่น 401) file_get_contentsฟังก์ชันจะล้มเหลวพร้อมคำเตือนและส่งคืน null หากเนื้อหามีข้อความแสดงข้อผิดพลาดคุณจะไม่สามารถเรียกคืนได้
Bart Verkoeijen

3
ข้อเสียเปรียบหลักคือการติดตั้ง PHP ของคุณจะต้องเปิดใช้งาน wrapper เพื่อที่จะเข้าถึง URL หาก fopen wrappers ไม่ได้เปิดใช้งานคุณจะไม่สามารถใช้ file_get_contents สำหรับการร้องขอบริการเว็บ
Oriol

2
fopen wrappers เป็นส่วนหนึ่งของ PHP ที่ถูกมองว่าเป็นช่องโหว่ดังนั้นคุณอาจเห็นว่ามีบางโฮสต์ที่ปิดการใช้งาน
มาร์คัสดาวนิง

153

ใช้ล่อ มันเป็น "ไคลเอนต์ PHP HTTP ที่ทำให้ง่ายต่อการทำงานกับ HTTP / 1.1 และลดความยุ่งยากในการใช้บริการเว็บ" การทำงานกับ Guzzle นั้นง่ายกว่าการทำงานกับ cURL

นี่คือตัวอย่างจากเว็บไซต์:

$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
ใครก็ตามที่ยังใช้ cURL ไม่เคยดูตัวเลือกนี้อย่างใกล้ชิด
JoshuaDavid

ดูเหมือนว่าดี แต่สิ่งที่เกี่ยวกับการดึง PNGs? สำหรับแผนที่ย่อย ฉันสามารถค้นหาข้อมูล JSON ที่กล่าวถึงในหน้าเว็บที่คุณเชื่อมโยงเท่านั้น
Henrik Erlandsson

20

CURL เป็นวิธีที่ง่ายที่สุดในการไป นี่คือสายที่เรียบง่าย

$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 กำลังพูดว่า "ดังนั้นฉันไม่รู้วิธีการเรียกใช้บริการ" ไม่เข้าใจวิธีที่ดีที่สุดในการใช้ REST api
Broncha

4
ว้าวคุณเสียความพยายามและเวลาที่จะทำให้ฉันตอบแดกดันแทนเพื่อให้ความคิดเห็นของคุณดีขึ้น ขอให้โชคดีในทางนั้น
m3nda

2
รักอันนี้ง่ายเพียงใด ให้ทัน
cyber8200

@Sadik POST DATA เป็นเพียงเจ้าของสถานที่คุณจะต้องส่งข้อมูลโพสต์ของคุณที่นั่น
Broncha

12

ใช้HTTPFUL

Httpful เป็นไลบรารี PHP ที่ง่ายและสามารถอ่านได้และมีจุดประสงค์เพื่อใช้พูด HTTP มันช่วยให้นักพัฒนามุ่งเน้นการโต้ตอบกับ API แทนที่จะลอดผ่านหน้า curl set_opt และเป็นไคลเอนต์ PHP REST ในอุดมคติ

Httpful รวมถึง ...

  • การสนับสนุนเมธอด HTTP ที่อ่านได้ (GET, PUT, POST, DELETE, HEAD และ OPTIONS)
  • ส่วนหัวที่กำหนดเอง
  • การแยกวิเคราะห์อัตโนมัติ "อัจฉริยะ"
  • การทำให้เป็นอนุกรมของน้ำหนักบรรทุกอัตโนมัติ
  • รับรองความถูกต้องขั้นพื้นฐาน
  • ใบรับรองฝั่งไคลเอ็นต์รับรองความถูกต้อง
  • ขอ "เทมเพลต"

อดีต

ส่งคำขอ GET รับการแยกวิเคราะห์การตอบสนอง JSON โดยอัตโนมัติ

ไลบรารีสังเกตเห็นประเภทเนื้อหา JSON ในการตอบสนองและวิเคราะห์คำตอบลงในวัตถุ PHP ดั้งเดิมโดยอัตโนมัติ

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

ฉันกำลังพยายามที่จะใช้ HTTPFUL เป็นวิธีแก้ปัญหาและผมไม่แน่ใจว่ามันสามารถแยก JSON เช่น$condition = $response->weather[0]->main;ถ้าฉันกำลังเพียงแค่การทำผิดด้าน PHP
weteamsteve

9

คุณจะต้องรู้ว่า REST API ที่คุณโทรติดต่อนั้นรองรับGETหรือPOSTไม่หรือทั้งสองวิธี รหัสด้านล่างเป็นสิ่งที่ใช้งานได้สำหรับฉันฉันกำลังเรียก API บริการเว็บของฉันเองดังนั้นฉันจึงทราบแล้วว่า API ใช้เวลาอย่างไรและจะคืนอะไร มันรองรับทั้งสองGETและPOSTวิธีการดังนั้นข้อมูลที่มีความละเอียดอ่อนจะเข้าสู่URL (GET)และข้อมูลเช่นชื่อผู้ใช้และรหัสผ่านจะถูกส่งเป็นPOSTตัวแปร นอกจากนี้ทุกอย่างผ่านการHTTPSเชื่อมต่อ

ภายในโค้ด API ฉันเข้ารหัสอาร์เรย์ที่ฉันต้องการกลับสู่รูปแบบ json จากนั้นเพียงใช้คำสั่ง PHP echo $my_json_variableเพื่อสร้างสตริง json นั้นให้กับลูกค้า

ดังนั้นอย่างที่คุณเห็น API ของฉันส่งคืนข้อมูล json แต่คุณต้องรู้ (หรือดูข้อมูลที่ส่งคืนเพื่อค้นหา) รูปแบบการตอบสนองจาก API นั้นอยู่ในรูปแบบใด

นี่คือวิธีที่ฉันเชื่อมต่อกับ API จากฝั่งไคลเอ็นต์:

$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 ฉันยังลองใช้file_get_contents()วิธีการตามที่ผู้ใช้บางคนที่นี่แนะนำ แต่วิธีนี้ใช้งานไม่ได้สำหรับฉัน ฉันค้นพบcurlวิธีการที่เร็วขึ้นและน่าเชื่อถือยิ่งขึ้น


5

มีลูกค้ามากมายจริงๆ หนึ่งในนั้นคือศัตรูพืช - ลองดูสิ และโปรดทราบว่าการเรียกใช้ REST เหล่านี้เป็นคำขอ http ง่าย ๆ ด้วยวิธีการต่าง ๆ : GET, POST, PUT และ DELETE


4

คุณสามารถใช้file_get_contentsเพื่อออกPOST/PUT/DELETE/OPTIONS/HEADวิธีhttp ใด ๆนอกเหนือจากGETวิธีการตามชื่อฟังก์ชั่นแนะนำ

วิธีโพสต์ข้อมูลใน PHP โดยใช้ file_get_contents


1
file_get_content เป็นความคิดที่ไม่ดีจริง ๆ เมื่อมันมาถึง API stackoverflow.com/questions/13004805/…คุณสามารถตั้งค่าวิธีการที่กำหนดเองเช่น file_get_contents_curl และใช้แทนการแก้ปัญหา php ธรรมดา stackoverflow.com/questions/8540800/…
Eryk Wróbel

3

หากคุณกำลังใช้ Symfony มีชุดลูกค้าที่ดีซึ่งรวมถึงข้อยกเว้น ~ 100 ทั้งหมดและโยนพวกเขาแทนที่จะส่งคืนรหัสข้อผิดพลาด + ข้อความที่ไม่มีความหมาย

คุณควรตรวจสอบ: https://github.com/CircleOfNice/CiRestClientBundle

ฉันรักอินเทอร์เฟซ:

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

ใช้งานได้กับวิธี http ทั้งหมด


2

ตามที่ @Christoph Winkler กล่าวถึงนี่เป็นคลาสพื้นฐานสำหรับการบรรลุเป้าหมาย:

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

}

จากนั้นคุณสามารถรวมไฟล์และใช้งานได้เช่น: 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

หากคุณเปิดให้ใช้เครื่องมือของบุคคลที่สามคุณจะได้เห็นสิ่งนี้: https://github.com/CircleOfNice/DoctrineRestDriver

นี่เป็นวิธีใหม่ในการทำงานกับ API อย่างสมบูรณ์

ก่อนอื่นคุณต้องกำหนดเอนทิตีที่กำหนดโครงสร้างของข้อมูลขาเข้าและขาออกและใส่คำอธิบายประกอบด้วยแหล่งข้อมูล:

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

ตอนนี้มันค่อนข้างง่ายที่จะสื่อสารกับ REST API:

$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

คุณสามารถไปกับ POSTMAN แอปพลิเคชันที่ทำให้ API ง่ายขึ้น กรอกข้อมูลในช่องคำขอจากนั้นมันจะสร้างรหัสให้คุณในภาษาต่างๆ เพียงคลิกรหัสทางด้านขวาและเลือกภาษาที่คุณต้องการ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.