2011-01-13 17 views
72

Problem jest następujący: Mam aplikację internetową działającą na serwerze PHP. Chciałbym zbudować dla niego API REST.
Zrobiłem kilka badań i doszedłem do wniosku, że API REST wykorzystuje metody HTTP (GET, POST ...) dla pewnych identyfikatorów URI z kluczem uwierzytelniającym (niekoniecznie), a informacja jest przedstawiana jako odpowiedź HTTP z informacją jako XML lub JSON (wolałbym JSON).Jak zbudować RESTful API?

Moje pytanie brzmi:

  1. W jaki sposób, jako twórca aplikacji, budować te URI? Czy muszę napisać kod PHP w tym identyfikatorze URI?
  2. Jak zbudować obiekty JSON, aby zwrócić je w odpowiedzi?
+1

http://www.gen-x-design.com/archives/create-a-rest-api-with-php/ jest doskonałym źródłem informacji na ten temat. –

+0

Napisałem ten [wpis na blogu] (https://www.leaseweb.com/labs/2015/10/creating-a-simple-rest-api-in-php/) zawierający przykładowy kod i instrukcje do tego. – mevdschee

Odpowiedz

66

Oto bardzo prosty przykład w prostym php.

Istnieją 2 pliki client.php & api.php. Umieściłem oba pliki pod tym samym adresem URL: http://localhost:8888/, więc będziesz musiał zmienić link do swojego własnego adresu URL. (plik może znajdować się na dwóch różnych serwerach).

To tylko przykład, jest bardzo szybki i brudny, a od dłuższego czasu robię php. Ale to jest idea api.

client.php

<?php 

/*** this is the client ***/ 


if (isset($_GET["action"]) && isset($_GET["id"]) && $_GET["action"] == "get_user") // if the get parameter action is get_user and if the id is set, call the api to get the user information 
{ 
    $user_info = file_get_contents('http://localhost:8888/api.php?action=get_user&id=' . $_GET["id"]); 
    $user_info = json_decode($user_info, true); 

    // THAT IS VERY QUICK AND DIRTY !!!!! 
    ?> 
    <table> 
     <tr> 
     <td>Name: </td><td> <?php echo $user_info["last_name"] ?></td> 
     </tr> 
     <tr> 
     <td>First Name: </td><td> <?php echo $user_info["first_name"] ?></td> 
     </tr> 
     <tr> 
     <td>Age: </td><td> <?php echo $user_info["age"] ?></td> 
     </tr> 
    </table> 
    <a href="http://localhost:8888/client.php?action=get_userlist" alt="user list">Return to the user list</a> 
    <?php 
} 
else // else take the user list 
{ 
    $user_list = file_get_contents('http://localhost:8888/api.php?action=get_user_list'); 
    $user_list = json_decode($user_list, true); 
    // THAT IS VERY QUICK AND DIRTY !!!!! 
    ?> 
    <ul> 
    <?php foreach ($user_list as $user): ?> 
     <li> 
     <a href=<?php echo "http://localhost:8888/client.php?action=get_user&id=" . $user["id"] ?> alt=<?php echo "user_" . $user_["id"] ?>><?php echo $user["name"] ?></a> 
    </li> 
    <?php endforeach; ?> 
    </ul> 
    <?php 
} 

?> 

api.php

<?php 

// This is the API to possibility show the user list, and show a specific user by action. 

function get_user_by_id($id) 
{ 
    $user_info = array(); 

    // make a call in db. 
    switch ($id){ 
    case 1: 
     $user_info = array("first_name" => "Marc", "last_name" => "Simon", "age" => 21); // let's say first_name, last_name, age 
     break; 
    case 2: 
     $user_info = array("first_name" => "Frederic", "last_name" => "Zannetie", "age" => 24); 
     break; 
    case 3: 
     $user_info = array("first_name" => "Laure", "last_name" => "Carbonnel", "age" => 45); 
     break; 
    } 

    return $user_info; 
} 

function get_user_list() 
{ 
    $user_list = array(array("id" => 1, "name" => "Simon"), array("id" => 2, "name" => "Zannetie"), array("id" => 3, "name" => "Carbonnel")); // call in db, here I make a list of 3 users. 

    return $user_list; 
} 

$possible_url = array("get_user_list", "get_user"); 

$value = "An error has occurred"; 

if (isset($_GET["action"]) && in_array($_GET["action"], $possible_url)) 
{ 
    switch ($_GET["action"]) 
    { 
     case "get_user_list": 
     $value = get_user_list(); 
     break; 
     case "get_user": 
     if (isset($_GET["id"])) 
      $value = get_user_by_id($_GET["id"]); 
     else 
      $value = "Missing argument"; 
     break; 
    } 
} 

exit(json_encode($value)); 

?> 

nie dokonywać żadnych połączeń do bazy danych dla tego przykładu, ale zwykle to, co należy zrobić, . Powinieneś także zamienić funkcję "file_get_contents" na "curl".

+0

Simon, bardzo dziękuję za twój przykład. Po prostu chcę mieć pewność: Załóżmy, że mam zasób o nazwie Użytkownik, a następnie muszę umieścić plik API w: http://www.mydomain.com/api/user Prawidłowo? –

+0

Możesz nazwać plik, jak chcesz. Ale tak, lepiej zadzwonić do pliku z wyraźną nazwą. Zajrzyj do mojego pliku api Sprawdzam parametr get i wywołuję funkcję dzięki tej wartości. Możesz załączyć plik user.php i wywołać funkcję, która znajduje się w tym pliku, Albo możesz umieścić plik w api/user i obsługiwać parametry z tego miejsca. –

+0

Zasadniczo potrzebuję zaktualizować tabelę routingu serwera, aby odwzorować określony adres URL na określony plik PHP na serwerze. Poprawny? –

10

To prawie to samo, co stworzenie normalnej witryny.

Normalny wzór na stronie internetowej PHP:

  1. Użytkownik wprowadź adres URL
  2. Serwer dostać url, analizować je i wykonać akcję
  3. W tej akcji, można dostać/generować każdy informacje potrzebne dla strony
  4. utworzyć stronę html/php z informacją z działaniem
  5. serwer generuje całkowicie HTML strony i wysłać go z powrotem do użytkownika

Za pomocą api wystarczy dodać nowy krok między 3 a 4. Po 3, utwórz tablicę zawierającą wszystkie potrzebne informacje. Zakoduj tę tablicę w json i zakończ lub zwróć tę wartość.

$info = array("info_1" => 1; "info_2" => "info_2" ... "info_n" => array(1,2,3)); 
exit(json_encode($info)); 

To wszystko za api. Po stronie klienta można wywołać api za pomocą adresu URL. Jeśli api działa tylko z wywołaniem, myślę, że można to zrobić po prostu (aby sprawdzić, zwykle używam curl).

$info = file_get_contents(url); 
$info = json_decode($info); 

Ale częściej korzysta się z biblioteki curl, aby wykonać wywołanie get i post. Możesz mnie zapytać, czy potrzebujesz pomocy przy zwijaniu.

Po uzyskaniu informacji z api można wykonać 4 kroki: 4 &.

Zobacz dokumentację php dla funkcji json i file_get_contents.

curl: http://fr.php.net/manual/fr/ref.curl.php


EDIT

Nie, czekaj, ja nie rozumiem. "strona php API" co masz na myśli?

APi to tylko tworzenie/rekonwalescencja twojego projektu. NIGDY nie wysyłasz bezpośrednio wyniku html (jeśli tworzysz stronę internetową) wyślij api. Wywołujesz api z adresem URL, informacją zwrotną api, wykorzystujesz te informacje, aby stworzyć ostateczny wynik.

np .: chcesz napisać stronę html, która mówi "cześć xxx".Ale aby uzyskać nazwę użytkownika, musisz uzyskać informacje z api.

Załóżmy, że twoje api mają funkcję, która ma argument id_użytkownika jako argument i zwraca nazwę tego użytkownika (powiedzmy getUserNameById (id_użytkownika)), i wywołujesz tę funkcję tylko pod adresem URL takim jak/api/ulr/getUser /ID.

Function getUserNameById(user_id) 
{ 
    $userName = // call in db to get the user 
    exit(json_encode($userName)); // maybe return work as well. 
} 

Od strony klienta zrobić

$username = file_get_contents(your/api/url/getUser/15); // You should normally use curl, but it simpler for the example 
// So this function to this specifique url will call the api, and trigger the getUserNameById(user_id), whom give you the user name. 
    <html> 
    <body> 
    <p>hello <?php echo $username ?> </p> 
    </body> 
    </html> 

więc klient nigdy bezpośredni dostęp do baz danych, że rolą API.

Czy to jest bardziej wyraźne?

+0

+1. Należy również pamiętać, że interfejs API powinien ustawić odpowiedni typ zawartości dla odpowiedzi. Dla json, zobacz http://stackoverflow.com/questions/477816/the-right-json-content-type – Ben

+0

Więc powinienem mieć na serwerze jedną stronę API php, która zarządza wszystkimi żądaniami? –

+0

Nie, czekaj, nie rozumiem. "strona php API" co masz na myśli? –

0

Jak powiedział simon marc, proces przebiega podobnie jak w przypadku Ciebie lub strony internetowej. Jeśli czujesz się komfortowo w korzystaniu z Zend Framework, możesz skorzystać z łatwych w użyciu samouczków, które ułatwiają konfigurację. Najtrudniejszą częścią budowania spokojnego API jest jego konstrukcja i uczynienie go naprawdę spokojnym, pomyśl o CRUD w kategoriach baz danych.

Możliwe, że naprawdę potrzebujesz interfejsu xmlrpc lub czegoś podobnego. Co chcesz, aby ten interfejs pozwolił ci zrobić?

--edit

Oto, gdzie się zaczęło z relaksującego API i Zend Framework. Zend Framework Example

W skrócie, nie używaj serwera Zend Rest, jest przestarzały.

+0

W jaki sposób wykorzystujesz środowisko Zend do budowy RESTful API? –

+0

Jeśli jesteś zainteresowany, będę umieszczać coś na moim blogu o rozpoczęciu z ZF i RESTful usługami sieciowymi z pełnym przykładem pracy. –

31

W 2013 roku, należy użyć coś jak np Silex lub Slim

Silex:

require_once __DIR__.'/../vendor/autoload.php'; 

$app = new Silex\Application(); 

$app->get('/hello/{name}', function($name) use($app) { 
    return 'Hello '.$app->escape($name); 
}); 

$app->run(); 

Slim przykład:

$app = new \Slim\Slim(); 
$app->get('/hello/:name', function ($name) { 
    echo "Hello, $name"; 
}); 
$app->run(); 
+1

Dziękuję. Użyłem Slim i miałem nagie api działające w ciągu kilku minut. – user12345

+0

Co polecasz na bardziej skomplikowany (szczegółowy) apis? Slim jest przydatny, ale wszystkie funkcje są w jednym pliku, więc czytelność jest dość trudna. –

+2

@IlkerBaltaci Dzięki Silex możesz wyposażyć kontrolerów w klasy. Oto dobre spostrzeżenie na ten temat, a także niektóre z zalet i wad stosowania mikroukładu w stosunku do pełnego układu strony https://igor.io/2012/11/09/scaling-silex.html.Osobiście wolę Silex, ponieważ daje mi najważniejsze rzeczy i pozwala mi wybrać resztę mojego stosu. – finishingmove

2

Wiem, że to pytanie jest akceptowana i ma trochę lat, ale może to być pomocne dla niektórych ludzi, którzy jeszcze znaleźć to istotne. Chociaż wynik nie jest pełnym interfejsem RESTful API, wersja API Builder mini lib dla PHP umożliwia łatwe przekształcanie baz danych MySQL w interfejsy API JSON dostępne w Internecie.

5

(1) Jak mogę ... zbudować te URI? Czy muszę napisać kod PHP przy tym identyfikatorze URI?

Nie ma standardu dotyczącego konfiguracji schematu URI interfejsu API, ale często występują wartości rozdzielone przecinkami. W tym celu można użyć ...

$apiArgArray = explode("/", substr(@$_SERVER['PATH_INFO'], 1)); 

... aby uzyskać tablicę wartości Slash rozdzielone w URI po nazwy pliku.

Przykład: Zakładając, że masz plik API api.php w aplikacji i gdzieś trzeba zrobić wniosek o api.php/members/3, następnie $apiArgArray będzie tablica zawierająca ['members', '3']. Następnie możesz użyć tych wartości, aby wysłać zapytanie do bazy danych lub wykonać inne przetwarzanie.

(2) Jak zbudować obiekty JSON, aby zwrócić w odpowiedzi?

Możesz wziąć dowolny obiekt PHP i przekształcić go w JSON z json_encode. Będziesz także chciał ustawić odpowiedni nagłówek.

header('Content-Type: application/json'); 
$myObject = (object) array('property' => 'value'); // example 
echo json_encode($myObject); // outputs JSON text 

Wszystko to jest dobre dla API, które zwraca JSON, ale następne pytanie należy zadać brzmi:

(3) Jak zrobić mój API relaksującego?

W tym celu użyjemy $_SERVER['REQUEST_METHOD'], aby uzyskać wykorzystywaną metodę, a następnie w oparciu o to zrobić różne rzeczy. Ostateczny wynik to coś takiego ...

header('Content-Type: application/json'); 
$apiArgArray = explode("/", substr(@$_SERVER['PATH_INFO'], 1)); 
$returnObject = (object) array(); 
/* Based on the method, use the arguments to figure out 
    whether you're working with an individual or a collection, 
    then do your processing, and ultimately set $returnObject */ 
switch ($_SERVER['REQUEST_METHOD']) { 
    case 'GET': 
    // List entire collection or retrieve individual member 
    break; 
    case 'PUT':  
    // Replace entire collection or member 
    break; 
    case 'POST':  
    // Create new member 
    break; 
    case 'DELETE':  
    // Delete collection or member 
    break; 
} 
echo json_encode($returnObject); 

Źródła: https://stackoverflow.com/a/897311/1766230 i http://en.wikipedia.org/wiki/Representational_state_transfer#Applied_to_web_services

Powiązane problemy