Разрабатываю сайты

БЛОГ ПРО WEB

Рассказываю о web-разработке
и помогаю создавать сайты

Простой API для Вашего сайта

75322-1

 

Возникла ситуация, когда необходимо использовать 2 БД MySQL на разных серверах для снижения нагрузки.

1 БД для основных задач и 2 БД для хранения различной статистики по всем модулям. А Статистика, как всем известно, — это куча цифр, которыми не хочется засорять основную БД.

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

Oauth использовать решил не стоит, да и было интересно как выйдет API своими руками.

API, ну или Парсер

Да, действительно, способ проще чем кажется. Можно данный способ организации назвать как Парсер, ведь будем использовать @file_get_contents()

Но мне важен результат!

Поехали…

Качаем исходники тут и разбираем что к чему

Собираем функционал API

У нас в итоге получится 2 части.

1 — Клиентская

2 — Серверная (API)

 

Файлы клиентской части


-- api.php // Соединение клиента с API

-- class.a.php // Класс запросов

-- config.php // Конфигурация MySQL сервера

И Серверная


-- index.php // Тестирование

-- function.api.php // Обработка и отправка запроса к API

Совсем не много…

А теперь по порядку каждый файл

Клиентская часть


-- function.api.php // Обработка и отправка запроса к API

<? 
function ApiQuery($data){ if($data){ 
$uid = '118'; // ID пользователя 
$key = '0d50GthZoEpoqGlskDkfWsNRqsHuTO4F'; // Ключ 
if(!$data)exit("Неправильный запрос"); 
$url = 'http://api.site.ru/api.php'; 
foreach($data as $k=>$item):
 $gets[$k] = $item;
 endforeach;
 
 $get = $url . '?' . urldecode(http_build_query($gets)) . '&uid=' . $uid . '&key=' . $key; // URL для парсера
 $r = json_decode(@file_get_contents($get));
 return $r;
 }
 
 }
 
?>

Так как задача у меня, создать API для хранения статистики по каждому пользователю, добавил параметр $uid. По нему и будет работать SELECT, INSERT, UPDATE и DELETE.

Чтобы пользователь не имел прав управлять строками других пользователей, создан параметр $key, который можно генерировать при регистрации пользователя и сделать проверку на совпадения $key и $uid у определенного пользователя. и $key и $uid соответственно должны быть уникальными!

$url — это адрес к нашему серверу, а точнее к файлу api.php (о нем читать ниже).

Дальше мы отправляем запрос @file_get_contents($get); к серверу и получаем ответ с результатом в формате json_decode()

Начал с клиентской части потому что, мне кажется интереснее посмотреть что получится, а не то как это сделано. И поэтому, вот как использовать MySQL удаленно

<? 
include('function.api.php'); // Функция для отправки запроса в API 

$data = ApiQuery([ // Вывод строк из БД "query" => "select",
 "table" => "scripts"
 ]);

 $datai = ApiQuery([ // Добавление строки в БД
 "query" => "insert",
 "table" => "scripts",
 "values" => [
 "script" => "222",
 "step" => "333"
 ]
 ]);
 
 $datau = ApiQuery([ // Редактирование строки в БД
 "query" => "update",
 "table" => "scripts",
 "where" => "id=5",
 "values" => [
 "script" => "987654321",
 "step" => "555111"
 ]
 ]);

 $datad = ApiQuery([ // Удаление строки в БД
 "query" => "delete",
 "table" => "scripts",
 "where" => "id=5"
 ]);
 
 if($data){ // Выводим все что мы получили через API
 foreach($data as $item){
 echo $item -> id . ') ' . $item -> script . ' => ' . $item -> step . '
';
 }
 }
 
?>

Подключаем function.api.php на нужных страницах для связи с API сервера со статистикой к примеру.

А остальное все итак понятно. Там написал все 4 функции для примера, используя таблицу в бд следующего вида


CREATE TABLE IF NOT EXISTS `scripts` (
 `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
 `script` int(11) NOT NULL,
 `step` int(11) NOT NULL,
 `uid` int(11) NOT NULL,
 PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251 AUTO_INCREMENT=1 ;

И тут логично понятные параметры

query — запрос (SELECT, UPDATE, INSERT или DELETE)

table — таблица в бд (в моем случае ‘scripts’)

where — условия обычного формата (тут не стал что то изобретать. Типа, [id=5 OR id=6])

а так же…

order — ORDER by

limit — LIMIT

values — и тут передаем параметры для добавления и редактирования в следующем формате

[ "script" => "222", "step" => "333" ]

Мне кажется, просто и понятно…

Серверная часть API

Конечно же config.php

<? $dbl = "localhost"; // Имя сервера 
$dbu = ""; // Имя пользователя 
$dbp = ""; // Пароль 
$dbn = ""; // Имя базы данных 
$db = mysql_connect ("$dbl","$dbu","$dbp"); 
mysql_select_db("$dbn",$db); 
?>

Проверка и отправка запроса в БД через класс API


 <? if($_GET['key'] == '0d50GthZoEpoqGlskDkfWsNRqsHuTO4F'){ 
include('config.php'); 
include('class.a.php'); 
$Api = new Api; 

$VALUES = $_GET['values']; 
if($_GET['uid']){ $uid = $_GET['uid'];
 
if($_GET['where']){ 
$WHERE = "(" . $_GET['where'] . ") AND uid='".$_GET['uid']."'"; 
}else{ 
$WHERE = "uid='".$_GET['uid']."'"; 
} 
$VALUES['uid'] = $_GET['uid']; 
}else{ 
$WHERE = $_GET['where']; 
} 
$data = array( 'key' => $_GET['key'],
 'table' => $_GET['table'],
 'where' => $WHERE,
 'values' => $VALUES,
 'order' => $_GET['order'],
 'limit' => $_GET['limit']
 );
 
 if($_GET['query']){
 switch($_GET['query']){
 case 'select':
 $D = $Api -> select($data);
 break;
 case 'insert':
 $D = $Api -> insert($data);
 break;
 case 'update':
 $D = $Api -> update($data);
 break;
 case 'delete':
 $D = $Api -> delete($data);
 break;
 }
 echo json_encode( $D );
 }
 
 
 
 }
?>

Конечно как вы понимаете, проверка такого рода


if($_GET['key'] == '0d50GthZoEpoqGlskDkfWsNRqsHuTO4F'){}


лишь как пример. Тут надо делать проверку ключа и ID пользователя на соответствие. Тут проблем думаю не будет.

И файл class.a.php для разных запросов и возвращения результата


<?

class Api {

 public function select($data){
 
 $t = $data['table'];
 $w = $data['where'] != '' ? ' WHERE ('.$data['where'].')' : '';
 $o = $data['order'] != '' ? ' ORDER by '.$data['order'] : '';
 $l = $data['limit'] != '' ? ' LIMIT '.$data['limit'] : '';
 
 if($t){
 $q = mysql_query("SELECT * FROM `$t` $w $o $l"); 
 if(mysql_num_rows($q)>0){
 while ($r = mysql_fetch_assoc ($q)){
 $b[] = $r;
 }
 }
 return $b;
 }
 }
 
 public function insert($data){
 
 $t = $data['table'];
 $p = $data['values'];
 if($t == true AND $p == true){
 foreach($p as $k=>$i){
 $col[] = $k;
 $val[] = $i;
 }
 if($col) $cols = implode(',', $col);
 if($val) $vals = implode(',', $val);
 
 $b = mysql_query("INSERT INTO `$t` ($cols) VALUES ($vals)"); 
 return $b;
 }
 }
 
 public function update($data){
 
 $t = $data['table'];
 $w = $data['where'] != '' ? ' WHERE '.$data['where'] : '';
 $p = $data['values'];
 if($t == true AND $p == true){
 foreach($p as $k=>$i){
 $value[] = $k . "='" . $i . "'";
 }
 if($value)$values = implode(',', $value);
 
 $b = mysql_query("UPDATE $t SET $values $w"); 
 return $b;
 }
 
 }
 
 public function delete($data){
 
 $t = $data['table'];
 $w = $data['where'] != '' ? ' WHERE '.$data['where'] : '';

 if($t){ 
 $b = mysql_query("DELETE FROM $t $w"); 
 return $b;
 }
 }

}
 
?>

местами требуются некоторые проверки для защиты, но не критичны. Даю код, чтобы смысл был понятен. Дальше уже сами дорабатывайте)

Расписывать не буду, итак ясно что делает данный файл…

Всем удачи в сайтостроении!


Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *