Как создать REST API в Phalcon
В этой заметке рассматривается отправка и получение данных с помощью REST API. Рассматривается две задачи отдельно:
Документация - хорошо, а примеры никогда лишними не бывают. Итак, есть работающее веб-приложение, в котором созданы модели и контроллеры для обработки данных. Например, есть модель Sotrudniki с данными о сотрудниках.
Организация ответа на запрос с другого ресурса
Для этого необходимо создать новый контроллер. Например, ApiController.php с классом ApiController. В контроллере создать функцию подготовки и выдачи запрашиваемых данных. Данные о сотрудниках передадим только id и place.
Файл ApiController.php
// используется модель Sotrudniki
use Vokuro\Models\Sotrudniki;
class ApiController extends ControllerBase
{
public function sotrudnikiAction(){
// чтение данных из таблицы Sotrudniki
$sotrudniki = Sotrudniki::find ();
$data = [];
// помещение необходимых полей/данных в массив
foreach ($sotrudniki as $sotrudnik) {
$data[] = [
'id' => $sotrudnik->id,
'place' => $sotrudnik->place,
];
}
// перевод массива в строку json
return json_encode($data);
}
}
Стороннему ресурсу данные будут доступны по адресу https://ВАШ.ДОМЕН/api/sotrudniki/ в формате json. Пример: [{"id":"1","place":"112"},{"id":"2","place":"111"},{"id":"3","place":"113"},{"id":"4","place":"114"},{"id":"5","place":""}].
Для выдачи только строки из таблицы Sotrudniki по id создается функция sotrudnikiid в этом классе.
public function sotrudnikiidAction($id){
$sotrudnik = Sotrudniki::findFirstById($id);
$data = [];
$data[] = $sotrudnik->id;
$data[] = $sotrudnik->place;
echo json_encode($data);
}
Стороннему ресурсу данные будут доступны по адресу https://ВАШ.ДОМЕН/api/sotrudnikiid/id/ в формате json. Вместо id в конце указать запрашиваемое значение. На запрос https://ВАШ.ДОМЕН/api/sotrudnikiid/1/ будут получены данные об одном сотруднике с id=1: [{"id":"1","place":"112"}]
Организация запроса данных с другого ресурса
Для этого необходимо создать новый контроллер. Например, ApirequestController.php с классом ApirequestController. В контроллере создать функцию запроса и обработки полученных данных. Если данные предполагается выводить на страницу, то создаем шаблон с именем функции sotrudniki.volt с папкой apirequest в корневой папке views.
Файл ApirequestController.php
class ApirequestController extends ControllerBase
{
public function sotrudnikiAction()
{
// подключение шаблона
$this->view->setTemplateBefore('public');
$resource = 'sotrudniki/';
$method = 'GET';
define("BASE_URL", "https://ЧУЖОЙ.ДОМЕН/api/");
$full_url = BASE_URL . "$resource";
$options = array(
CURLOPT_URL => $full_url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => array('Content-Type: application/json', 'Accept: application/json'),
CURLOPT_CUSTOMREQUEST => $method
);
$ch = curl_init();
curl_setopt_array($ch, $options);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ( $status > 399 ) {
throw new Exception("Exception $status: $out");
}
// декодирование в ассоц массив
$content = json_decode($out, true);
// вывод в шаблон
$this->view->sotrudniki = $content;
}
}
Функция отправит запрос https://ЧУЖОЙ.ДОМЕН/api/sotrudniki/ на ресурс ЧУЖОЙ.ДОМЕН для получения данных об их сотрудниках. Ответ придет в формате json. Пример: [{"id":"1","place":"112"},{"id":"2","place":"111"},{"id":"3","place":"113"},{"id":"4","place":"114"},{"id":"5","place":""}].
В шаблоне развернем данные. Файл sotrudniki.volt
{{ content() }}
<h2 class="pager">Сотрудники</h2>
<table class="table table-bordered table-striped" align="center">
<thead>
<tr class="header_table">
<th>Сотрудник</th>
<th>Место</th>
</tr>
</thead>
<tbody>
<?php
foreach ($sotrudniki as $value) {
echo '<tr>';
foreach ($value as $k => $v) {
echo '<td>' .$v. '</td> ';
}
echo '</tr>';
}
?>
</tbody>
</table>
Шифрование данных
Чтобы защитить данные от излишних несанкционированных запросов и перехватов в процессе передачи, можно прибегнуть к одному из способов шифрования данных.
Для этого воспользуемся компонентом Phalcon\Crypt.
Файл ApiController.php будет выглядеть следующим:
// используем компонент Crypt
use Phalcon\Crypt;
use Vokuro\Models\Sotrudniki;
class ApiController extends ControllerBase
{
public function sotrudnikiAction(){
$sotrudniki = Sotrudniki::find ();
$data = [];
foreach ($sotrudniki as $sotrudnik) {
$data[] = [
'id' => $sotrudnik->id,
'place' => $sotrudnik->place,
];
}
$dataString = json_encode($data);
// кодирование строки с данными $dataString
$crypt = new Crypt();
$crypt->setCipher('aes-256-ctr');
// ключ для шифрования
$key = "T4\xb1\x8d\xa9\x98\x05\x6y\hdl\x8c\xbe\x1d\x07&[\x99\x18\xa4~Lc1\xbeW\xb3";
$encrypted = $crypt->encrypt($dataString, $key);
return $encrypted;
}
}
Файл ApirequestController.php будет выглядеть следующим:
use Phalcon\Crypt;
public function sotrudnikiAction()
{
$this->view->setTemplateBefore('public');
$resource = 'sotrudniki/';
$method = 'GET';
define("BASE_URL", "http://ЧУЖОЙ.ДОМЕН/api/");
$full_url = BASE_URL . "$resource";
$options = array(
CURLOPT_URL => $full_url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => array('Content-Type: application/json', 'Accept: application/json'),
CURLOPT_CUSTOMREQUEST => $method
);
$ch = curl_init();
curl_setopt_array($ch, $options);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ( $status > 399 ) {
throw new Exception("Exception $status: $out");
}
// раскодирование полученной строки $out
$crypt = new Crypt();
$crypt->setCipher('aes-256-ctr');
$key = "T4\xb1\x8d\xa9\x98\x05\x6y\hdl\x8c\xbe\x1d\x07&[\x99\x18\xa4~Lc1\xbeW\xb3";
$sotr = $crypt->decrypt($out, $key);
$content = json_decode($sotr, true); // true - декодирование в ассоц массив
$this->view->sotrudniki = $content;
}
Ключ шифра придумайте сами, он должен находиться на обоих ресурсах.
Об алгоритмах шифрования подробнее здесь.

