Сайт на Laravel. Урок 6. Vk API

vkapi

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

VK API

Сначала разберемся, что такое API. Расшифровывается это как программный интерфейс приложения или интерфейс прикладного программирования (англ. application programming interface) Подробно можно прочитать в википедии.

В нашем случае Api можно понять как способ получить нужные данные от другого сайта или приложения. Например, мы хотим получать информацию о подписчиках сообщества каждую минуту и использовать в логике нашего сервиса. Мы бы могли написать парсер для группы в вк. И заходить на страницу как обычный пользователь, искать нужную информацию и копировать ее. Мы бы так и сделали, если бы у вк не было более удобного апи. Однако, такой подход имеет много недостатков. Если верстка страницы изменится, то парсер придется переписывать. Вместе с нужной информацией нам придется обработать очень много лишнего. Из-за этого возрастает количество памяти в приложении и время обработки. Да и сам вконтакте был бы против использования парсеров.

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

Чтобы получить информацию о подписчиках нашей группы через апи необходим ключ доступа. Создать его можно в самом сообществе в разделе настроек.

API Ключ для работы с сообществом
API Ключ для работы с сообществом

Подписчики сообщества

Когда ключ для VK API создан, мы можем написать метод для обращения к апи. Сразу создадим специальный класс для laravel, в котором соберем функции для работы с вк.

Создадим в каталоге app новый подкаталог Library. В этом подкаталоге будем хранить файлы php которые будут содержать наши вспомогательные классы. Обращаться к ним мы будем из контроллеров, а доступа к ним от маршрутизатора не требуется.

В этом подкаталоге создадим файл VKAPI.php с несколькими закрытыми свойствами и методом конструктора.

<?php
namespace App\Library;
class VKAPI {
    private $v = '5.130';    
    private $groupId;    
    private $token;

    public function __construct($groupId, $token){
        $this->token = $token;
        $this->groupId = $groupId;
    }
}

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

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

private function apiRequest($method, $data = array()) {
        $data['v'] = $this->v;
        $data['access_token'] = $this->token;

        $string = http_build_query($data);
        $url = 'https://api.vk.com/method/'.$method.'?';
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url.urldecode($string));
        curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
        curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false );
        curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );
        $response = curl_exec($ch);
        curl_close($ch);
        return json_decode($response, true);
}

Здесь мы используем библиотеку curl для формирования get запроса к апи и передаем название метода и наши идентификационные данные.

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

public function setSubscribers(){
        $data = [
            'group_id' => $this->groupId,
            'sort' => 'time_desc',
            'fields' => 'photo_max'
        ];
        $members = $this->apiRequest('groups.getMembers', $data);
        foreach($members['response']['items'] as $member){
            $this->subscribers[] = $member;
            $this->subscribersId[] = $member['id'];
        }
}
public function getSubscribers(){
        return $this->subscribers;
}    
public function getSubscribersId(){
        return $this->subscribersId;
}

Не забудем добавить свойства subscribers и subscriberId в начало класса.

Класс VKAPI.php

В итоге наш класс для доступа к апи имеет такой вид.

<?php
namespace App\Library;
class VKAPI {
    private $v = '5.130';
    private $groupId;
    private $token;

    private $subscribers = [];
    private $subscribersId = [];

    public function __construct($groupId, $token){
        $this->token = $token;
        $this->groupId = $groupId;
    }

    public function setSubscribers(){
        $data = [
            'group_id' => $this->groupId,
            'sort' => 'time_desc',
            'fields' => 'photo_max'
        ];
        $members = $this->apiRequest('groups.getMembers', $data);

        foreach($members['response']['items'] as $member){
            $this->subscribers[] = $member;
            $this->subscribersId[] = $member['id'];
        }

    }
    public function getSubscribers(){
        return $this->subscribers;
    }
    public function getSubscribersId(){
        return $this->subscribersId;
    }

    private function apiRequest($method, $data = array()) {
        $data['v'] = $this->v;
        $data['access_token'] = $this->token;

        $string = http_build_query($data);
        $url = 'https://api.vk.com/method/'.$method.'?';

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url.urldecode($string));
        curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
        curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false );
        curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );        
        $response = curl_exec($ch);
        curl_close($ch);
        return json_decode($response, true);
    }

}

Клиентский код

Теперь мы можем использовать класс доступа в нашем контроллере. Для этого изменим контроллер cover таким образом.

<?php

namespace App\Http\Controllers;
use App\Library\VKAPI;

class Cover extends Controller
{
    public function index(){
        $cover = new VKAPI('97974818','1b47****6dea5');
        $cover->setSubscribers();
        return $cover->getSubscribers();
    }
}

Здесь мы подключаем файл класса. Создаем экземпляр и передаем id группы и ключ. А после этого выполняем сеттер и геттер. Когда мы обратимся к странице из браузера, то получим json объект со всеми подписчиками сообщества.

json response
json response

Настройка Apache в Docker

Теперь осталось настроить вебсервер, чтобы корень сайта ссылался на правильный каталог нашего фреймворка.

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

docker ps
docker ps
docker ps

Зайдем внутрь контейнера с вебсервером с помощью команды exec и вызовем командную оболочку.

docker exec -it anonymous_www_1 /bin/bash
docker exec -it
docker exec -it

Нам нужен файл настроек сервера apache. Он находится в папке /etc/. Отредактируем его.

nano /etc/apache2/sites-enabled/000-default.conf

Найдем строку DocumentRoot и добавим каталог public

DocumentRoot /var/www/html/public

Сохраним файл и выйдем из контейнера командой exit.

Возможные проблемы

Во-первых, в нашем контейнере вебсервера не установлены программы nano и mc. Установить их можно выполнив команды apt внутри контейнера.

apt-get update
apt-get install mc -y
apt-get install nano-y

Во-вторых, возможно наш класс VKAPI.php не будет найдем фреймворком. Тогда необходимо исправить файл composer.json, а именно добавить наш каталог с классами в раздел autoload.

"autoload": {
        "psr-4": {
            "App\\": "app/",
            "Database\\Factories\\": "database/factories/",
            "Database\\Seeders\\": "database/seeders/"
        }
},

И обновить информацию внутри фрейвморка выполнив команду composer внутри каталога фреймворка.

composer dump-autoload

Заключение

Мы написали класс для работы с апи вконтакте и научились его использовать. Настроили вебсервер для более удобной работы. И теперь мы можем использовать данные о нашем сообществе, чтобы закончить приложение.

До того, как вы уйдете, посмотрите наши статьи и уроки про Ардуино. Например, подключение OLED дисплея к Ардуино.

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

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