Простой RESTful-сервис на нативном PHP. Создание RESTful API на PHP Создание php формы для api

У семерых козлов и волк без глазу

Создание RESTful API на PHP

REST или в полной форме, Representational State Transfer стало стандартной архитектурой проектирования для разработки веб-API.

REST является очень простым интерфейсом управления информацией без использования каких-то дополнительных внутренних прослоек. Каждая единица информации однозначно определяется глобальным идентификатором, таким как URL. Каждая URL в свою очередь имеет строго заданный формат.

REST использует методы HTTP-запроса, чтобы скомпоновать себя в существующую архитектуру HTTP. Эти операции состоят в следующем:

GET - используется для базовых запросов на чтение на сервер

PUT- Используется для изменения существующего объекта на сервере

POST- Используется для создания нового объекта на сервере

DELETE - используется для удаления объекта на сервере

А теперь к сути, т.е. написанию простого API, который вы можете использовать в своих проектах.

Что такое API

В широком смысле API - это интерфейс веб-приложения, позволяет публично использовать методы для доступа и управления извне. Обычное использование API - это когда необходимо получать данные из приложения (например, статья или какие-то другие данные) без фактического посещения ресурса (например сайта). Чтобы сделать это возможным, для приложения реализуется API, который позволяет сторонним приложениям совершать запросы и возвращать указанные данные пользователю извне. В Интернете это часто делается с использованием RESTful.

В примере запроса статьи API может содержать URI:

example.com/api/v1/recipe/article

Если отправить запрос GET в этот URL, ответ может быть списком самых последних новостей, запрос PUT может добавить новость в БД.

Если запросить /article /141, то это будет определенная новость. Это примеры показывают способ взаимодействия с приложением.

Создание своего API

Создадим файл.htaccess для того чтобы GET запросы преобразовывать в понятные контроллеру параметры.

RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule api/v1/(.*)$ api/v1/api.php?request=$1

Что же означают строки этого файла?

В первой строке проверяется существование модуля rewrite. Если он запущен, выполняются следующие строки.

Далее объявляется возможность переопределять URL. Это значит, что путь api/v1/ будет перенаправлен на api/v1/index.php. Символы (.*) обозначают переменные, которые необходимо обработать а $ - это ограничитель, после которого начинается следующая логика. Также, - означает нечувствительность к регистру, - что переменные будут присоединены к новому URL, L - mod_rewrite больше не обрабатывает ничего кроме указанного.

Объявляем класс, свойства и конструктор.

abstract class API { /** * Property: method * GET, POST, PUT, DELETE */ protected $method = ""; /** * Property: endpoint * The Model requested in the URI. eg: /files */ protected $endpoint = ""; /** * Property: verb * An optional additional descriptor about the endpoint, used for things that can * not be handled by the basic methods. eg: /files/process */ protected $verb = ""; /** * Property: args * Any additional URI components after the endpoint and verb have been removed, in our * case, an integer ID for the resource. eg: //// * or // */ protected $args = Array(); /** * Property: file * Stores the input of the PUT request */ protected $file = Null; /** * Constructor: __construct * Allow for CORS, assemble and pre-process the data */ public function __construct($request) { header("Access-Control-Allow-Orgin: *"); header("Access-Control-Allow-Methods: *"); header("Content-Type: application/json"); $this->args = explode("/", rtrim($request, "/")); $this->endpoint = array_shift($this->args); if (array_key_exists(0, $this->args) && !is_numeric($this->args)) { $this->verb = array_shift($this->args); } $this->method = $_SERVER["REQUEST_METHOD"]; if ($this->method == "POST" && array_key_exists("HTTP_X_HTTP_METHOD", $_SERVER)) { if ($_SERVER["HTTP_X_HTTP_METHOD"] == "DELETE") { $this->method = "DELETE"; } else if ($_SERVER["HTTP_X_HTTP_METHOD"] == "PUT") { $this->method = "PUT"; } else { throw new Exception("Unexpected Header"); } } switch($this->method) { case "DELETE": case "POST": $this->request = $this->_cleanInputs($_POST); break; case "GET": $this->request = $this->_cleanInputs($_GET); break; case "PUT": $this->request = $this->_cleanInputs($_GET); $this->file = file_get_contents("php://input"); break; default: $this->_response("Invalid Method", 405); break; } } public function processAPI() { if (method_exists($this, $this->endpoint)) { return $this->_response($this->{$this->endpoint}($this->args)); } return $this->_response("No Endpoint: $this->endpoint", 404); } private function _response($data, $status = 200) { header("HTTP/1.1 " . $status . " " . $this->_requestStatus($status)); return json_encode($data); } private function _cleanInputs($data) { $clean_input = Array(); if (is_array($data)) { foreach ($data as $k => $v) { $clean_input[$k] = $this->_cleanInputs($v); } } else { $clean_input = trim(strip_tags($data)); } return $clean_input; } private function _requestStatus($code) { $status = array(200 => "OK", 404 => "Not Found", 405 => "Method Not Allowed", 500 => "Internal Server Error",); return ($status[$code])?$status[$code]:$status; } }

Объявив этот абстрактный класс, мы запретили PHP создавать конкретный экземпляр этого класса. Оттуда мы можем только использовать методы, унаследовав в другом классе. Защищенный метод может быть доступен только в самом классе и его потомках.

Создание класса API

Создаем классMyAPI который наследует абстрактный класс API.

require_once "API.class.php"; class MyAPI extends API { protected $User; public function __construct($request, $origin) { parent::__construct($request); // Abstracted out for example $APIKey = new Models\APIKey(); $User = new Models\User(); if (!array_key_exists("apiKey", $this->request)) { throw new Exception("No API Key provided"); } else if (!$APIKey->verifyKey($this->request["apiKey"], $origin)) { throw new Exception("Invalid API Key"); } else if (array_key_exists("token", $this->request) && !$User->get("token", $this->request["token"])) { throw new Exception("Invalid User Token"); } $this->User = $User; } /** * Example of an Endpoint */ protected function example() { if ($this->method == "GET") { return "Your name is " . $this->User->name; } else { return "Only accepts GET requests"; } } }

Использование API

// Requests from the same server don"t have a HTTP_ORIGIN header if (!array_key_exists("HTTP_ORIGIN", $_SERVER)) { $_SERVER["HTTP_ORIGIN"] = $_SERVER["SERVER_NAME"]; } try { $API = new MyAPI($_REQUEST["request"], $_SERVER["HTTP_ORIGIN"]); echo $API->processAPI(); } catch (Exception $e) { echo json_encode(Array("error" => $e->getMessage())); }

Корявый перевод этого: http://coreymaynard.com/blog/creating-a-restful-api-with-php/

Не так давно один из моих посетителей мне задал вопрос по e-mail : "". Я решил, что это будет весьма полезно другим пользователям, тем более, что на кажущуюся сложность процесса, всё очень и очень просто. Необходимо лишь обладать самыми элементарными знаниями PHP .

Если Вы вдруг не понимаете, о чём идёт речь, то прочитайте сначала статью: . Идём дальше. Давайте разберём, а для каких сайтов нужен вообще API :

Первое, что необходимо усвоить - это то, что API нужен далеко не каждому сайту (даже если он принадлежит одной из вышеуказанных групп).

Если же Вы считаете, что API на Вашем сайте необходим, то давайте разберём пример того, как он создаётся. Пусть у нас будет такая задача: есть ЭПС (как, например, WebMoney ). И мы хотим, чтобы пользователь мог из своего кода, пользуясь нашим API , узнать свой баланс на счёте.

Создадим файл (например, api.php ), который у нас будет принимать GET-запросы от пользователей на получение различной информации. Напишем в этом обработчике такой код:

if ($_GET["action"] == "getbalance") {
$balance;
//Узнаём из базы данных баланс аккаунта и записываем в переменную balance
echo $balance;
}
?>

Теперь разработчики API должны дать информацию пользователям о том, как надо отправлять запрос, чтобы пользователь мог узнать свой баланс на аккаунте:

Http://mysite.ru/api.php?action=getbalance&key=fa9sgwlgjs9gdsjlgjdsjglsdlgs

Этот запрос пользователи формируют в своих скриптах (например, через cURL ). Параметр key - это уникальный ключ каждого пользователя. И ответом этого запроса будет число, отвечающее за баланс пользователя. Аналогично создаются и все другие возможности API . Можно добавлять другие различные параметры: например, получить список операций пополнения счёта с одной даты по другую. Желательно, сами списки возвращать в формате JSON .

февраль 5 , 2017

Я не знаю ни одного php-фреймворка. Это печально и стыдно, но законом пока не запрещено. А при этом поиграться с REST API хочется. Проблема в том, что php по умолчанию поддерживает только $_GET и $_POST. А для RESTful-сервиса надобно уметь работать еще и с PUT, DELETE и PATCH. И не очень очевидно, как культурно обработать множество запросов вида GET http://site.ru/users, DELETE http://site.ru/goods/5 и прочего непотребства. Как завернуть все подобные запросы в единую точку, универсально разобрать их на части и запустить нужный код для обработки данных?

Почти любой php-фреймворк умеет делать это из коробки. Например, Laravel, где роутинг реализован понятно и просто. Но что если нам не нужно прямо сейчас заниматься изучением новой большой темы, а хочется просто быстро завести проект с поддержкой REST API? Об этом и пойдет речь в статье.

Что должен уметь наш RESTful-сервис?

1. Поддерживать все 5 основных типов запросов: GET, POST, PUT, PATCH, DELETE.
2. Разруливать разнообразные маршруты вида
POST /goods
PUT /goods/{goodId}
GET /users/{userId}/info
и прочие сколь угодно длинные цепочки.

Внимание: это статья не про основы REST API
Я предполагаю, что Вы уже знакомы с REST-подходом и понимаете, как это работает. Если нет, то в интернетах много замечательных статей по основам REST - я не хочу дублировать их, моя идея - показать, как с REST работать на практике.

Какой функционал мы будем поддерживать?

Рассмотрим 2 сущности - товары и пользователи.

Для товаров возможности следующие:

  • 1. GET /goods/{goodId} — Получение информации о товаре
  • 2. POST /goods — Добавление нового товара
  • 3. PUT /goods/{goodId} — Редактирование товара
  • 4. PATCH /goods/{goodId} — Редактирование некоторых параметров товара
  • 5. DELETE /goods/{goodId} — Удаление товара

По пользователям для разнообразия рассмотрим несколько вариантов с GET

  • 1. GET /users/{userId} — Полная информация о пользователе
  • 2. GET /users/{userId}/info — Только общая информация о пользователе
  • 3. GET /users/{userId}/orders — Список заказов пользователя

Как это заработает на нативном PHP?

Первое, что мы сделаем - это настроим.htaccess так, чтобы все запросы перенаправлялись на файл index.php. Именно он и будет заниматься извлечением данных.

Второе - определимся, какие данные нам нужны и напишем код для их получения - в index.php.
Нас интересуют 3 типа данных:

  • 1. Метод запроса (GET, POST, PUT, PATCH или DELETE)
  • 2. Данные из URL-a, например, users/{userId}/info - нужны все 3 параметра
  • 3. Данные из тела запроса
И третье, напишем код, который запускает нужные функции. Функции разбиты по файлам, все по феншую, добавить новые пути и методы для RESTful-сервиса будет очень просто.

.htaccess

Создадим в корне проекта файл.htaccess

RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.+)$ index.php?q=$1

Этими загадочными строками мы повелеваем делать так:
1 - направить все запросы любого вида на царь-файл index.php
2 - сделать строку в URL-е доступной в index.php в get-параметре q. То есть данные из URL-а вида /users/{userId}/info мы достанем из $_GET["q"].

index.php

Рассмотрим index.php строка за строкой. Для начала получим метод запроса.

// Определяем метод запроса $method = $_SERVER["REQUEST_METHOD"];

Затем данные из тела запроса

// Получаем данные из тела запроса $formData = getFormData($method);

Для GET и POST легко вытащить данные из соответствующих массивов $_GET и $_POST. А вот для остальных методов нужно чуть извратиться. Код для них вытаскивается из потока php://input , код легко гуглится, я всего лишь написал общую обертку - функцию getFormData($method)

// Получение данных из тела запроса function getFormData($method) { // GET или POST: данные возвращаем как есть if ($method === "GET") return $_GET; if ($method === "POST") return $_POST; // PUT, PATCH или DELETE $data = array(); $exploded = explode("&", file_get_contents("php://input")); foreach($exploded as $pair) { $item = explode("=", $pair); if (count($item) == 2) { $data = urldecode($item); } } return $data; }

То есть мы получили нужные данные, скрыв все детали в getFormData - ну и отлично. Переходим к самому интересному - роутингу.

// Разбираем url $url = (isset($_GET["q"])) ? $_GET["q"] : ""; $url = rtrim($url, "/"); $urls = explode("/", $url);

Выше мы узнали, что.htaccess подложит нам параметры из URL-a в q-параметр массива $_GET. То есть в $_GET["q"] попадет примерно такая строка: users/10 . Независимо от того, каким методом мы запрос дергаем.

А explode("/", $url) преобразует нам эту строку в массив, с которым уже можно работать. Таким образом, составляйте сколько угодно длинные цепочки запросов, например,
GET /goods/page/2/limit/10/sort/price_asc
И будьте уверены, получите массив

$urls = array("goods", "page", "2", "limit", "10", "sort", "price_asc");

Теперь у нас есть все данные, нужно сделать с ними что-нибудь полезное. А сделают это всего лишь 4 строки кода

// Определяем роутер и url data $router = $urls; $urlData = array_slice($urls, 1); // Подключаем файл-роутер и запускаем главную функцию include_once "routers/" . $router . ".php"; route($method, $urlData, $formData);

Улавливаете? Мы заводим папку routers, в которую складываем файлы, манипулирующие одной сущностью: товарами или пользователями. При этом договариваемся, что название файлов совпадают с первым параметром в urlData - он и будет роутером, $router. А из urlData этот роутер нужно убрать, он нам больше не нужен и используется только для подключения нужного файла. array_slice($urls, 1) и вытащит нам все элементы массива, кроме первого.

Теперь осталось подключить нужный файл-роутер и запустить функцию route с тремя параметрами. Что же это за function route? Условимся, что в каждом файле-роутере будет определена такая функция, которая по входным параметрам определит, какое действие инициировал пользователь, и выполнит нужный код. Сейчас это станет понятнее. Рассмотрим первый запрос - получение данных о товаре.

GET /goods/{goodId}

Файл routers/goods.php

// Роутер function route($method, $urlData, $formData) { // Получение информации о товаре // GET /goods/{goodId} if ($method === "GET" && count($urlData) === 1) { // Получаем id товара $goodId = $urlData; // Вытаскиваем товар из базы... // Выводим ответ клиенту echo json_encode(array("method" => "GET", "id" => $goodId, "good" => "phone", "price" => 10000)); return; } // Возвращаем ошибку header("HTTP/1.0 400 Bad Request"); echo json_encode(array("error" => "Bad Request")); }

Содержимое файла - это одна большая функция route, которая в зависимости от переданных параметров выполняет нужные действия. Если метод GET и в urlData передан 1 параметр (goodId), то это запрос о получении данных о товаре.

Внимание: пример очень упрощенный
В реале, конечно же, нужно дополнительно проверять входные параметры, например, что goodId - это число. Вместо того, чтобы писать код здесь, Вы, вероятно, подключите нужный класс. И для получения товара создадите объект оного класса и вызовете у него какой-то метод.
А может быть, передадите управление какому-то контроллеру, который уже озаботится инициализацией нужных моделей. Вариантов много, мы рассматриваем только общую структуру кода.

В ответе клиенту мы выводим нужные данные: название товара и его цену. id товара и метод в реальном приложении совершенно не обязательны. Покажем их только, чтобы убедится, что вызывается нужный метод с правильными параметрами.

Давайте попробуем на примере: откройте консоль браузера и выполните код

$.ajax({url: "/examples/rest/goods/10", method: "GET", dataType: "json", success: function(response){console.log("response:", response)}})

Код отправит запрос на сервер, где я развернул подобное приложение и выведет ответ. Убедитесь, что интересующий наш маршрут /goods/10 действительно отработал. На вкладке Network Вы заметите такой же запрос.
И да, /examples/rest - это корневой путь нашего тестового приложения на сайт

Если Вам привычнее пользоваться curl-ом в консоли, то запустите в терминале это - ответ будет тот же самый, да еще и с заголовками от сервера.

Curl -X GET https://сайт/examples/rest/goods/10 -i

В конце функции мы написали такой код.

// Возвращаем ошибку header("HTTP/1.0 400 Bad Request"); echo json_encode(array("error" => "Bad Request"));

Он значит, что если мы ошиблись с параметрами или запрашиваемый маршрут не определен, то вернем клиенту 400-ю ошибку Bad Request. Добавьте, например, к URL-у что-то вроде goods/10/another_param и увидите ошибку в консоли и ответ 400 - кривой запрос не прошел.

По http-кодам ответов сервера
Мы не будем заморачиваться с выводом разных кодов, хотя по REST-у это и стоит делать. Клиентских ошибок много. Даже в нашем простом случае уместна 405 в случае неправильно переданного метода. Намеренно не хочу усложнять.
В случае успеха сервер у нас всегда вернет 200 ОК. По хорошему, при создании ресурса стоит отдавать 201 Created. Но опять-таки в плане упрощения эти тонкости мы отбросим, а в реальном проекте Вы их легко реализуете сами.

По совести говоря, статья закончена. Думаю, Вы уже поняли подход, каким образом разруливаются все маршруты, вынимаются данные, как это протестировать, как добавлять новые запросы и т.д. Но я для завершения образа приведу реализацию оставшихся 7 запросов, которые мы обозначили в начале статьи. Попутно приведу пару интересных замечаний, а в конце выложу архив с исходниками.

POST /goods

Добавление нового товара

// Добавление нового товара // POST /goods if ($method === "POST" && empty($urlData)) { // Добавляем товар в базу... // Выводим ответ клиенту echo json_encode(array("method" => "POST", "id" => rand(1, 100), "formData" => $formData)); return; }

urlData сейчас пустой, но зато используется formData - мы ее просто выведем клиенту.

Как сделать "правильно"?
Согласно канонам REST в post-запросе следует отдавать обратно только id созданной сущности или url, по которому эту сущность можно получить. То есть в ответе будет или просто число - {goodId} , или /goods/{goodId} .
Почему я написал "правильно" в кавычках? Да потому, что REST - это набор не жестких правил, а рекомендаций. И как будете реализовывать именно Вы, зависит от Ваших предпочтений или уже принятых соглашений на конкретном проекте.
Просто имейте в виду, что другой программист, читающий код и осведомленный о REST-подходе, будет ожидать в ответе на post-запрос id созданного объекта или url, по которому можно get-запросом вытащить данные об этом объекте.

Тестим из консоли

$.ajax({url: "/examples/rest/goods/", method: "POST", data: {good: "notebook", price: 20000}, dataType: "json", success: function(response){console.log("response:", response)}})

Curl -X POST https://сайт/examples/rest/goods/ --data "good=notebook&price=20000" -i

PUT /goods/{goodId}

Редактирование товара

// Обновление всех данных товара // PUT /goods/{goodId} if ($method === "PUT" && count($urlData) === 1) { // Получаем id товара $goodId = $urlData; // Обновляем все поля товара в базе... // Выводим ответ клиенту echo json_encode(array("method" => "PUT", "id" => $goodId, "formData" => $formData)); return; }

Здесь уже все данные используются по-полной. Из urlData вытаскивается id товара, а из formData - свойства.

Тестим из консоли

$.ajax({url: "/examples/rest/goods/15", method: "PUT", data: {good: "notebook", price: 20000}, dataType: "json", success: function(response){console.log("response:", response)}})

Curl -X PUT https://сайт/examples/rest/goods/15 --data "good=notebook&price=20000" -i

PATCH /goods/{goodId}

Частичное обновление товара

// Частичное обновление данных товара // PATCH /goods/{goodId} if ($method === "PATCH" && count($urlData) === 1) { // Получаем id товара $goodId = $urlData; // Обновляем только указанные поля товара в базе... // Выводим ответ клиенту echo json_encode(array("method" => "PATCH", "id" => $goodId, "formData" => $formData)); return; }

Тестим из консоли

$.ajax({url: "/examples/rest/goods/15", method: "PATCH", data: {price: 25000}, dataType: "json", success: function(response){console.log("response:", response)}})

Curl -X PATCH https://сайт/examples/rest/goods/15 --data "price=25000" -i

К чему эти понты с PUT и PATCH?
Разве одного PUT не достаточно? Разве не выполняют они одно и то же действие - обновляют данные объекта?
Именно так - внешне действие одно. Разница в передаваемых данных.
PUT предполагает, что на сервер передаются все поля объекта, а PATCH - только измененные . Те, которые переданы в теле запроса. Обратите внимание, что в предыдущем PUT мы передали и название товара, и цену. А в PATCH - только цену. То есть мы отправили на сервер только измененные данные.
Нужен ли Вам PATCH - решайте сами. Но помните о том читающем код программисте, о котором я упоминал выше.

DELETE /goods/{goodId}

Удаление товара

// Удаление товара // DELETE /goods/{goodId} if ($method === "DELETE" && count($urlData) === 1) { // Получаем id товара $goodId = $urlData; // Удаляем товар из базы... // Выводим ответ клиенту echo json_encode(array("method" => "DELETE", "id" => $goodId)); return; }

Тестим из консоли

$.ajax({url: "/examples/rest/goods/20", method: "DELETE", dataType: "json", success: function(response){console.log("response:", response)}})

Curl -X DELETE https://сайт/examples/rest/goods/20 -i

С DELETE-запросом все понятно. Теперь давайте рассмотрим работу с пользователями - роутер users и соответственно, файл users.php

GET /users/{userId}

Получение всех данных о пользователе. Если GET-запрос вида /users/{userId} , то мы вернем всю информацию о пользователе, если дополнительно указывается /info или /orders , то соответственно, только общую информацию или список заказов.

// Роутер function route($method, $urlData, $formData) { // Получение всей информации о пользователе // GET /users/{userId} if ($method === "GET" && count($urlData) === 1) { // Получаем id товара $userId = $urlData; // Вытаскиваем все данные о пользователе из базы... // Выводим ответ клиенту echo json_encode(array("method" => "GET", "id" => $userId, "info" => array("email" => "[email protected]", "name" => "Webdevkin"), "orders" => array(array("orderId" => 5, "summa" => 2000, "orderDate" => "12.01.2017"), array("orderId" => 8, "summa" => 5000, "orderDate" => "03.02.2017")))); return; } // Возвращаем ошибку header("HTTP/1.0 400 Bad Request"); echo json_encode(array("error" => "Bad Request")); }

Тестим из консоли

$.ajax({url: "/examples/rest/users/5", method: "GET", dataType: "json", success: function(response){console.log("response:", response)}})

Curl -X GET https://сайт/examples/rest/users/5 -i

GET /users/{userId}/info

Общая информация о пользователе

// Получение общей информации о пользователе // GET /users/{userId}/info if ($method === "GET" && count($urlData) === 2 && $urlData === "info") { // Получаем id товара $userId = $urlData; // Вытаскиваем общие данные о пользователе из базы... // Выводим ответ клиенту echo json_encode(array("method" => "GET", "id" => $userId, "info" => array("email" => "[email protected]", "name" => "Webdevkin"))); return; }

Тестим из консоли

$.ajax({url: "/examples/rest/users/5/info", method: "GET", dataType: "json", success: function(response){console.log("response:", response)}})

Curl -X GET https://сайт/examples/rest/users/5/info -i

GET /users/{userId}/orders

Получение списка заказов пользователя

// Получение заказов пользователя // GET /users/{userId}/orders if ($method === "GET" && count($urlData) === 2 && $urlData === "orders") { // Получаем id товара $userId = $urlData; // Вытаскиваем данные о заказах пользователя из базы... // Выводим ответ клиенту echo json_encode(array("method" => "GET", "id" => $userId, "orders" => array(array("orderId" => 5, "summa" => 2000, "orderDate" => "12.01.2017"), array("orderId" => 8, "summa" => 5000, "orderDate" => "03.02.2017")))); return; }

Тестим из консоли

$.ajax({url: "/examples/rest/users/5/orders", method: "GET", dataType: "json", success: function(response){console.log("response:", response)}})

Curl -X GET https://сайт/examples/rest/users/5/orders -i

Итоги и исходники

Исходники из примеров статьи -

Как видим, организовать поддержку REST API на нативном php оказалось не так уж и сложно и вполне законными способами. Главное - это поддержка маршрутов и нестандартных для php методов PUT, PATCH и DELETE.

Основной код, реализовывающий эту поддержку, уместился в 3 десятка строк index.php. Остальное - это уже обвязка, которую можно реализовать как угодно. Я предложил это сделать в виде подключаемых файлов-роутеров, имена которых совпадают с сущностями Вашего проекта. Но можно подключить фантазию и найти более интересное решение.

У меня часто спрашивают, как работать с API . Наиболее, популярной задачей, связанной с API , является - работа с API ВКонтакте . В данной статье я покажу, как работать с API ВКонтакте , а, главное, покажу Вам, что все API работают по единому принципу .

Вот порядок действий , который Вам необходимо сделать, чтобы начать работать с любым API :

  1. Найти документацию по нужному API .
  2. Посмотреть примеры подключения к API . Тут могут быть разные варианты. Например, на одном сервисе потребуют секретный ключ, выдаваемый после регистрации. На втором сервисе, все запросы не требуют секретных ключей. На третьем сервисе, есть и с секретным ключом, и без варианты работы. Иногда, секретный ключ называют токеном .
  3. Скопировать простой готовый код с сайта документации и проверить его работу. Если не работает, то ищите ошибку у себя, так как едва ли она будет у сервиса.
  4. Найти в документации метод , который решает Вашу задачу.
  5. Используя примеры и описание метода, отправить правильный запрос к API .
  6. В зависимости от формата ответа, разобрать его на "составные части ", а дальше уже делать то, что требуется - вывести пользователю, сохранить в файл, отправить в базу данных и тому подобное.

А в качестве примера следования данной инструкции мы разберём API ВКонтакте . Итак:

  1. Ссылка на документацию .
  2. В данном случае есть методы, которые общедоступны, а потому не требуют токена, а есть методы, требующие его.
  3. В данном случае, примеров на конкретном языке я не нашёл. Возможно, они есть, но явно не на виду. Обычно же, у API для каждого метода есть примеры на разных языках.
  4. Мы хотим вывести 5 последних записей со стены конкретного пользователя, а затем вывести их у себя на сайте . Нужный нам метод .

Теперь мы должны отправить запрос к API , используя описание метода. Делать мы это будем через PHP :

$wall = file_get_contents("https://api.vk.com/method/wall.get?v=5.3&filter=others&domain=myrusakov&count=5");
print_r($wall);
?>

В данном случае, я использую API 5.3 (v=5.3 ), вывожу все записи независимо от автора (filter=others ) со своей страницы (domain=myrusakov ) в количестве 5 штук (count=5 ). Думаю, что здесь всё очень прозрачно.

Мы получили ответ в формате JSON , и теперь нам нужно перейти к последнему пункту - разобрать ответ на "составные части ". Дальше мы с Вами выведем записи со стены в более-менее читабельном виде на странице нашего сайта. Результирующий PHP-код :

$wall = file_get_contents("http://api.vk.com/method/wall.get?v=5.3&filter=others&domain=myrusakov&count=5"); // Отправляем запрос
$wall = json_decode($wall); // Преобразуем JSON-строку в массив
$wall = $wall->response->items; // Получаем массив комментариев
for ($i = 0; $i < count($wall); $i++) {
echo "

".($i + 1).". ".$wall[$i]->text."
".date("Y-m-d H:i:s", $wall[$i]->date)."

"; // Выводим записи
}
?>

Как видите, всё очень просто. Самая сложная часть - разобрать на составные элементы. Я предпочитаю выводить результат от API через print_r , а уже затем писать обработку этого. Хотя можно посмотреть пример ответа в описании метода, а дальше уже написать парсер.