6 мая 2014 в 16:12

Правильный подход к использованию API Вконтакте из песочницы

Привет, Хабр!

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


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

Сразу необходимо сделать оговорку, помимо описания, я буду приводить куски рабочего кода к моей библиотеке, ссылку на которую я приведу в конце статьи. Библиотека работает на последней стабильной версии 5.5, если вырезать генераторы из пакетного получения, то должно работать на 5.4.

Начнём с того, как мы можем пройти авторизацию.
С точки зрения получения ключа доступа(Access Token), мы можем сделать это тремя способами:
  • Серверная авторизация(т.н. авторизация сайтов)
  • Клиентская авторизация(Standalone)
  • Авторизация сервера приложения

Самое интересное для разработчика, представляют первые два. Первый, позволяет авторизовать пользователя на сайте и получить его ключ доступа, второй позволит авторизовать ваше приложение, например Dekstop или Mobile. Забегая, вперёд, второй вариант предоставляет нам огромные возможности, а первый, лишь малую их часть.

Алгоритм получения в первом случае сводится к выполнению следующих пунктов:
  • Мы выводим ссылку для авторизации пользователя, которую форматируем в соответствии с документацией
  • Пользователь переходит по ней и авторизуется
  • Пользователя перенаправляют на REDIRECT_URI нашего приложения с GET параметром code
  • Наше приложение должно выполнить запрос к API содержащий code, чтобы получить ключ доступа пользователя
  • API отвечает, либо с объектом, содержащим ключ доступа, либо ошибкой.


Пример кода, с помощью которого можно провернуть это не хитрое дело.

$auth = getjump\Vk\Auth::getInstance();
$auth->setAppId('3470411')->setScope('SCOPE')->setSecret('SECRET CODE')->setRedirectUri('http://localhost/test.php');
$token=$auth->startCallback();
printf("<a href='%s' target='_top'>LINK</a>", $auth->getUrl());


Предполагается, что наш домен это localhost, а текущий файл test.php. Если, всё прошло хорошо, то в нашей переменной $token, будет содержаться ключ доступа пользователя, который прошёл авторизацию.

С момента, когда мы имеем ключ доступа, мы можем выполнять запросы к API. Общая логика запросов проста, вы передаёте специально сформированный запрос на URL API. Запрос должен содержать, название метода и аргументы.
api.vk.com/method/METHOD_NAME?PARAMETERS&access_token=ACCESS_TOKEN

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

При использовании библиотеки нам необходимо создать базовый объект, например так:
$vk = getjump\Vk\Core::getInstance()->apiVersion('5.5')->setToken($token);


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

Через анонимную функцию в each, пройдёт ровно 100 объектов, содержащих данные о пользователях от 1 до 100. Заметьте, если мы уберём вызов функции, то не произойдёт никакого запроса, всё потому что вернётся объект, у которого переопределены магические методы __call и __get, что позволяет нам делать запрос, когда нам это действительно необходимо.
$vk->request('users.get', ['user_ids' => range(1, 100)])->each(function($i, $v) {
        if($v->last_name == '') return;
        print $v->last_name . '<br>';
    });


Одна из вещей, что открывает, нам использование генераторов — пакетное получение. То есть, мы получаем данные только тогда, когда они нам нужны. Следующий пример, позволит нам получить ВСЕ наши сообщения, запросами по 100. Будьте внимательны, метод требует от вас прав для messages, Standalone приложения, такой-же авторизации и соответственно передачи ключа доступа.
foreach($vk->request('messages.get')->batch(100) as $data)
{
    $data->each(function($i, $m) {
        if(isset($m->body)) print $m->body . PHP_EOL;
    });
}


Хороший метод, который можно отыскать в API — execute. Он принимает параметр code в качестве аргумента, code — некий псевдо JavaScript, который позволяет нам выполнять наш код на стороне сервера, так-же он позволяет выполнять хранимые процедуры, которые мы можем создать при редактировании нашего приложения.

Эту вещь я не смог обойти стороной и реализовал её в библиотеке. В двух словах, она позволяет выполнить несколько запросов, как один. Смотрите следующий пример кода.

$js1 = $vk->request('messages.get', ['count' => 200, 'offset' =>0 * 200])->toJs(); // Вернёт объект типа VkJs
$js2 = $vk->request('messages.get', ['count' => 200, 'offset' =>1 * 200])->toJs();
$js3 = $vk->request('messages.get', ['count' => 200, 'offset' =>2 * 200])->toJs();
$js4 = $vk->request('messages.get', ['count' => 200, 'offset' =>3 * 200])->toJs();


$js1
        ->append($js2) // Мы прибавляем js2 к js1
        ->append($js3)
        ->append($js4) 
        ->execute() // Мы хотим выполнить это(на самом деле это вернёт RequestTransaction)
        ->response //Запрос исполнится только сейчас
        ->each(
            function($i, $v) //Первая анонимная функция нужна для обхода всех элементов массива полученного от execute(массив из 4 элементов, 4 запроса)
            {
                $v->each(function($c, $d) { // Следующая для прохода всех 200 сообщений в каждом массиве
                    if(isset($d->body)) print $d->body; //Выведем сообщение если такое поле присутствует
                });
            });


Как и обещал, одно из тех недоразумений, которое вы можете встретить в текущей версии API(5.21), метод users.get вернёт нам response, как массив, хотя в других местах, например friends.get, начиная с версии номер 5, нам возвращаются поля count и items, мне кажется это не совсем логичным, к тому же это требует лишнего кода при работе с API.

Так-же в библиотеке реализованы обработчики для некоторых операций, с вашей помощью их может стать больше.
С использованием библиотеки мы можем добиться довольно приятного и красивого кода, а это, самое важное в нашем не лёгком деле.
Вполне вероятно, что в коде остались какие-то недоразумения или баги, надеюсь на вашу внимательность и Pull Requests приветствуются.
Библиотека в большинстве своём отвечает стандарту PSR-0.

Надеюсь, мне удалось показать вам, что API Вконтакте не страшно, а даже приятно.

Благодарю за внимание!

Ссылка на github: github.com/getjump/VkApiPHP
Исчерпывающее руководство по API: vk.com/dev/main
PSR-0: github.com/getjump/fig-standards/blob/master/accepted/PSR-0.md
Packagist: packagist.org/packages/getjump/vk

UPDATE:
Можно установить через Composer: composer require "getjump/vk:*"

UPDATE 2:
Теперь минимальная версия 5.4, теоретически(по идее не используется большинство его функционала) может завестись и на 5.3, если не использовать короткий синтаксис для массивов.
Павел Савинов @GetJump
карма
5,0
рейтинг 0,0
Похожие публикации
Самое читаемое Разработка

Комментарии (21)

  • 0
    За«star»ил проект на гитхабе, по описанию выглядит очень привлекательно. Скажите, поддерживатеся ли загрузка изображений?
    • 0
      Пока что, не поддерживается. Загрузка изображений куда вас интересует? На самом деле, есть несколько различных мест куда их можно загрузить и каждое имеет свою специфику, за исключением конечно некоторых общих моментов. Если хотите, можете создать Issue на гитхабе и по возможности загрузки изображений будут реализованы.
      • +2
        Интересует загрузка в альбом (группы) и в посты. Посмотрю ваш код более детально, возможно сделаю pull request.
  • 0
    жду composer и psr-4(!), а не 0.
    Библиотека выглядит very sexy по сравнению с аналогами.
  • 0
    Красота — понятие очень относительное.

    Приведённые примеры не показались красивыми с точки зрения оформления.
    • 0
      Режут глаза все эти очень семантические переменные в духе $d, $f, $j, $i, $v, которые используются как параметры функции (пусть и анонимной).
      • +2
        Прошу прощения, но грешен. Те кто изучал(-ет) математику, легко поймут откуда берутся эти названия-паразиты.

        Опять таки, это просто примеры использования, никто не говорит, что это непреложная истина.
        • +1
          Те кто изучал(-ет) математику, легко поймут откуда берутся эти названия-паразиты.

          Интересно, много ли на хабре/среди разработчиков тех, кто не изучал её?
          • +2
            Здесь нужно сделать уточнение. Её можно изучать, как предмет, который преподаётся в гуманитарных науках, скажем «Высшая математика», а можно изучать, как комплекс: «Математический анализ», «Линейная алгебра», «Аналитическая геометрия», «Дифференциальные уравнения», «Комплексный анализ», «Численные методы», «Теория Групп».

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

            Я встречал много примеров, когда «разработчики» не имеют глубоких познаний в математике и это не всегда так-уж плохо, хотя знание основ той математике, что преподаётся в университетах, даже не повредит, а наоборот позволит хорошо понимать, как работает вся эта «кухня».
            • 0
              Я вот жалею, что мне не довелось изучать математику комплексно.
              Не то, что мне это нужно по профессии, нет, но для общего развития очень хочется.

              Кстати, на гитхабе есть годный проект: github.com/xHellerx/Math-tutorial — учебник по математике для начинающих на русском языке. Но сами понимаете, когда ты не студент, времени на погружение в матчасть почти нет.
              • 0
                Для общего развития достаточно читать классику вроде Стренга, Фихтенгольца и т.д., с одной стороны приходит осознание некоторых вещей, а с другой вы не полностью погружаетесь, что конечно не даёт вам постигать всё с той-же глубиной, что и студентам.

                Хотя если быть откровенным, сегодня, желание понимать тот-же мат. анализ или линейную алгебру возникает далеко не у всех студентов, так что быть студентом — не такой уж и плюс.
      • 0
        Присоединюсь к мнению Funcraft относительно названия переменных. Также добавлю, что namespace верхнего уровня с ником разработчика выглядит не сильно привлекательно. Но в остальном, код выглядит привлекательным.

        • +2
          Мне показалось разумным, что Vendor Name должен быть равен моему аккаунту на GitHub и packagist.
    • +1
      Всё сравнилось с тем, что уже существует, например github.com/vladkens/VK. Если брать в качестве знаменателя «красоты» какие-либо хорошие практики, то эта библиотека их выполняет, следовательно, допустимо назвать её красивой. При написании, я руководствовался удобством и компактностью кода для исполнения некоторых операций, чего, как мне кажется, удалось добиться. И конечно-же, если вам кажется, что ваше понимание «красоты» ближе к истине, то никто не запрещает вам сделать аналогичное решение, как некоторое время назад поступил и я.
      • 0
        В этом плане, вам огромное спасибо за проделанный труд (:

        Т.к. доправить намного легче, чем писать с нуля.
  • 0
    Зашел на ГитХаб. Смотрю ваша библиотека в топе. Думаю — наверное с Хабра. И точно. Что же, спасибо за труды. Глядишь и пригодится.
  • 0
    Ничего не сказано про лимиты запросов к API и про их зависимость от количества установок.
    • 0
      Да, очень жаль, что это в доке не указано. Там же для каждого метода своё ограничение. Недавно пробовал делать audio.add каждую минуту — через некоторое время выдавало капчу. Поставил раз в 10 минут, теперь всё хорошо.
    • 0
      От количества установок чего? Если вы про библиотеку, то никто не мешает вам создать своё приложение в Vk и получать токены через него.
  • 0
    Скажите, можно ли написать вэб-страничку, которая работает как стэндэлоун приложение?
    • 0
      Нет. По правилам использования — нельзя. И технически тоже не получится — всё действительно качественно позакрыто.

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