RReverser's

Ingvar Stepanyan

JavaScript developer, speaker and reverse engineer. D2D programmer. Sometimes human.


Автоматизация разработки API сайта

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

Проблема состояла в том, что мне попался довольно объемный проект, уже готовый, налаженный и работающий. Задача состояла в разработке API для этого проекта, с помощью которого можно было бы получить доступ к основным функциям сайта с помощью вызова через URL. Так как я по природе довольно ленив и не хотел добавлять каждую фичу вручную, то было решено немножко упростить и автоматизировать данный процесс.

Что же получилось.

Для начала необходимо было определиться — что именно мы будем пихать в API. Понятно, что такими обработчиками могут выступать глобальные функции и методы классов (в т.ч. статические). Очевидно, что мы должны каким-то образом их регистрировать под некоторыми именами, за которыми впоследствии сможем обращаться. Таким образом, имеем первоначальный макет класса:

class QAPI  
{
    private $methods = array();

    function registerFunction($funcName, $name = null)
    {
        // ...
    }

    function registerMethod($object, $methodName, $name = null)
    {
        // ...
    }

    function registerStatic($className, $methodName, $name = null)
    {
        // ...
    }
}

Что дальше? Дальше неплохо бы добавить методы registerObject и registerClass для автоматического добавления всех публичных методов данного объекта/класса (с опциональными префиксами для названий, дабы не плутать методы с таким же названием от разных классов):

function registerObject($object, $prefix = '')  
{
    // ...
}

function registerClass($className, $prefix = '')  
{
    // ...
}

Ну и, наконец, было б совсем хорошо, если бы можно было регистрировать все найденные объекты и классы. «Стоп-стоп. Как это все?! Ты что, ***?» — скажет читатель и будет прав. Необходимо сделать какой-то маркер, который будет обозначать какие именно классы мы можем обрабатывать, а какие — нет. Используем для этого интерфейсы:

interface QAPI_Interface {}

Таким образом, у нас будет интерфейс, который ни до чего не обязывает (в смысле изменения структуры класса), но который можно обнаружить и таким образом он будет служить нашей «меткой». Все, теперь достаточно обозначить в проекте необходимые нам классы с помощью implements QAPI_Interface и реализовать обмен данными (параметры-возвращаемые значения).

Работать с QuickAPI предельно просто. Помечаете нужные вам классы, включаете их вместе с данным в php-шку, которая будет отвечать за обработку API-запросов и пишете:

$QAPI = new QAPI;  
$QAPI->register();

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

$QAPI->registerObjects(); // все глобальные объекты "меченных" классов  
$QAPI->register($object);
$QAPI->register('MyClass');
$QAPI->register(array($object, 'MethodName')); // или $QAPI->registerMethod($object, 'MethodName');
$QAPI->register('GlobalFuncName');
$QAPI->register('ClassName::MethodName'); // или $QAPI->registerStatic('ClassName', 'MethodName');

Также вы можете переназначить методы dataToString, который приводит возвращаемые значения в строку для отдачи клиенту и getParams для получения массива параметров для передачи в метод (сейчас — $_GET['params']). Вызов должен происходить с помощью метода call с передачей названия метода:

$QAPI->call($_GET['method']);

Полученный в результате класс можно скачать здесь (там же лежит пример с документацией, а также можно проголосовать за него для Innovation Award :) ): www.phpclasses.org/package/6675.html

В общем, все. С интересом выслушаю любые замечания по улучшению и доработке.

comments powered by Disqus