Бывает, что какой-то проект «вырастает из штанишек» и становится необходимым разработать сервис который будет отдавать часть своих данных, по запросу на сторонние сервера. Вот и меня возникла такая необходимость .Вот каркас, с чего начать.
В моем случае сервер защищен от «чужих» протоколом SSL и сертификатом .p12 с паролем. Соответственно для получения данных по API на сторонних ресурсах необходимы будут pem и key файлы от выданного пользователю сертификата.
Для некоторых может быть удобным получение «сессионного ключа» для авторизации и допуска к API. В принципе доработать не сложно кому нужно. Приведенные ниже примеры — не рабочие, не хватает части файлов, размещено просто для того чтобы можно было понять принцип разработки.
На сервере в корне создадим файл api.php:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
|
<?php /* * (с) 2011-2019 Грибов Павел * http://грибовы.рф * * Если исходный код найден в сети - значит лицензия GPL v.3 * * В противном случае - код собственность ГК Яртелесервис, Мультистрим, Телесервис, Телесервис плюс * */ /* Этот файл - API для получения из NOC различных данных в формате json * вход: post/get с заполненым параметром command (массив) * выход: json с результатом */ $version="1.0.0"; define('WUO_ROOT', dirname(__FILE__)); // Загружаем первоначальные настройки. Если не получилось - выходим $rez = @include_once(WUO_ROOT.'/config.php'); if ($rez == false) {die();} header('Content-Type: application/json; charset=utf-8'); // Загружаем классы include_once(WUO_ROOT.'/class/sql.php'); // Класс работы с БД include_once(WUO_ROOT.'/class/config.php'); // Класс настроек include_once(WUO_ROOT.'/inc/connect.php'); // Соединяемся с БД, получаем $mysql_base_id include_once(WUO_ROOT.'/inc/config.php'); // Подгружаем настройки из БД, получаем заполненый класс $cfg include_once(WUO_ROOT.'/inc/functions.php'); // Загружаем функции $command=_GET("command"); if ($command==""){ $command=_POST("command"); }; if ($command!=""){ if (is_file(WUO_ROOT."/api/".$command.".php")) { include_once(WUO_ROOT."/api/".$command.".php"); } else { $ret["result"]=false; $ret["message"]="Метод/команда не найдена"; die(json_encode($ret)); } } else { $ret["result"]=false; $ret["message"]="Метод/команда не задан"; die(json_encode($ret)); }; ?> |
Как мы видим — суть его, поймать на входе команду, и выполнить файл из папки /api/, совпадающий с именем команды. Так мы избавляемся от головной боли с раширением количества команд API.
В папке /api/ создадим первую команду нашего API — файл version:
|
<?php $ret["result"]=true; $ret["message"]="$version"; die(json_encode($ret)); ?> |
Теперь пример использования данного API (для удобства обернуто в класс):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
|
<?php class NocApi { var $curl_opts = array( CURLOPT_URL=>"https://куц.укамцук.ru/api.php", CURLOPT_RETURNTRANSFER => true, CURLOPT_SSL_VERIFYPEER => false, // вход по SSL CURLOPT_SSL_VERIFYHOST => false, CURLOPT_FOLLOWLOCATION => false, // редиректы CURLOPT_MAXREDIRS => 10, // максимальное количество редиректов CURLOPT_CONNECTTIMEOUT=>5, CURLOPT_CONNECTTIMEOUT=>5, CURLOPT_VERBOSE=>true, CURLOPT_SSLCERT=>"/home/уцм/укм/cert/укмцу.crt", CURLOPT_SSLKEY=>"/home/уцкму/цукм/cert/цукм.key", CURLOPT_SSLKEYPASSWD=>"123", CURLOPT_POST=>true, CURLOPT_POSTFIELDS=>"command=version" ); public function __construct(){ if (! function_exists('curl_init')) { throw new Exception('CURL модуль для PHP не установлен!'); } } public function Exec($runc=""){ $curl = curl_init(); foreach ($this->curl_opts as $opt => $val){ curl_setopt($curl, $opt, $val); }; if ($runc!=""){ curl_setopt($curl, CURLOPT_POSTFIELDS, $runc); }; $data = curl_exec($curl); if (curl_errno($curl)) { $ret["result"]=false; $ret["message"]=curl_error($curl); die(json_encode($ret)); } else { return json_decode($data); curl_close($curl); }; } } $noc=new NocApi(); $res=$noc->Exec("command=version"); var_dump($res); |
Результат выполнения:
|
object(stdClass)#2 (2) { ["result"]=> bool(true) ["message"]=> string(5) "1.0.0" } |