О насБлогКонтакты
Веб-разработка14 июля 2015 г. 5 мин 360Обновлено: 22 июня 2026 г.

Как работать с API ВКонтакте на PHP: авторизация, посты, статистика (2015)

AunimedaAunimeda
📋 Содержание

Коротко: Создайте приложение на vk.com/dev, получите app_id и app_secret. Для авторизации - OAuth 2.0 через https://oauth.vk.com/authorize, получите access_token, используйте https://api.vk.com/method/METHOD_NAME для вызовов API. Версия API в 2015: 5.37.


Создание VK приложения

  1. vk.com/dev → «Создать приложение»
  2. Тип: «Веб-сайт»
  3. Адрес сайта: https://mysite.ru
  4. Базовый домен: mysite.ru
  5. Получаем: app_id и app_secret

Авторизация через VK Login

<?php
// VkAuth.php

class VkAuth {
    private string $appId;
    private string $appSecret;
    private string $redirectUri;

    public function __construct(string $appId, string $appSecret, string $redirectUri) {
        $this->appId       = $appId;
        $this->appSecret   = $appSecret;
        $this->redirectUri = $redirectUri;
    }

    /**
     * Сгенерировать URL для авторизации
     * Permissions scope: https://vk.com/dev/permissions
     */
    public function getAuthUrl(array $scope = ['email']): string {
        $params = [
            'client_id'     => $this->appId,
            'redirect_uri'  => $this->redirectUri,
            'scope'         => implode(',', $scope),
            'response_type' => 'code',
            'v'             => '5.37',  // Версия API
            'state'         => bin2hex(random_bytes(16)),  // CSRF-защита
        ];

        $_SESSION['vk_state'] = $params['state'];
        return 'https://oauth.vk.com/authorize?' . http_build_query($params);
    }

    /**
     * Обменять code на access_token
     * Вызывается на redirect_uri после авторизации
     */
    public function handleCallback(string $code, string $state): array {
        // Проверить CSRF state
        if ($state !== ($_SESSION['vk_state'] ?? '')) {
            throw new RuntimeException('Invalid state - possible CSRF');
        }

        $response = file_get_contents('https://oauth.vk.com/access_token?' . http_build_query([
            'client_id'     => $this->appId,
            'client_secret' => $this->appSecret,
            'redirect_uri'  => $this->redirectUri,
            'code'          => $code,
        ]));

        $data = json_decode($response, true);

        if (isset($data['error'])) {
            throw new RuntimeException('VK OAuth error: ' . $data['error_description']);
        }

        // $data содержит: access_token, user_id, email (если запрошен)
        return $data;
    }
}

VK API клиент

<?php
// VkApi.php

class VkApi {
    private string $accessToken;
    private string $apiVersion = '5.37';
    private string $baseUrl    = 'https://api.vk.com/method/';

    public function __construct(string $accessToken) {
        $this->accessToken = $accessToken;
    }

    public function call(string $method, array $params = []): array {
        $params['access_token'] = $this->accessToken;
        $params['v']            = $this->apiVersion;

        $url      = $this->baseUrl . $method;
        $ch       = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POSTFIELDS     => http_build_query($params),
            CURLOPT_POST           => true,
            CURLOPT_TIMEOUT        => 10,
            CURLOPT_SSL_VERIFYPEER => true,
        ]);

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($httpCode !== 200) {
            throw new RuntimeException("VK API HTTP error: $httpCode");
        }

        $data = json_decode($response, true);

        if (isset($data['error'])) {
            throw new RuntimeException(
                'VK API error ' . $data['error']['error_code'] . ': ' . $data['error']['error_msg']
            );
        }

        return $data['response'];
    }

    // Получить данные пользователя
    public function getUser(int $userId): array {
        $result = $this->call('users.get', [
            'user_ids' => $userId,
            'fields'   => 'photo_100,city,bdate,sex',
        ]);
        return $result[0];
    }

    // Опубликовать пост на стене сообщества
    public function wallPost(int $ownerId, string $message, string $attachments = ''): int {
        // ownerId для сообщества - отрицательный ID: -GROUP_ID
        $result = $this->call('wall.post', [
            'owner_id'    => $ownerId,
            'message'     => $message,
            'attachments' => $attachments,  // 'photo-1234_5678,https://mysite.ru/article/1'
            'from_group'  => 1,             // От имени сообщества (не пользователя)
        ]);
        return $result['post_id'];
    }
}

VK Login в контроллере

<?php
// routes: GET /auth/vk → login, GET /auth/vk/callback → callback

class AuthController {
    public function vkLogin(): void {
        $vkAuth  = new VkAuth(VK_APP_ID, VK_APP_SECRET, 'https://mysite.ru/auth/vk/callback');
        $authUrl = $vkAuth->getAuthUrl(['email']);
        header('Location: ' . $authUrl);
        exit;
    }

    public function vkCallback(): void {
        $code  = $_GET['code'] ?? '';
        $state = $_GET['state'] ?? '';

        try {
            $vkAuth  = new VkAuth(VK_APP_ID, VK_APP_SECRET, 'https://mysite.ru/auth/vk/callback');
            $tokens  = $vkAuth->handleCallback($code, $state);
            $vkApi   = new VkApi($tokens['access_token']);
            $vkUser  = $vkApi->getUser($tokens['user_id']);

            // Найти или создать пользователя в БД
            $user = UserRepository::findOrCreateByVk([
                'vk_id'      => $tokens['user_id'],
                'email'      => $tokens['email'] ?? null,
                'first_name' => $vkUser['first_name'],
                'last_name'  => $vkUser['last_name'],
                'avatar'     => $vkUser['photo_100'],
            ]);

            $_SESSION['user_id'] = $user['id'];
            header('Location: /dashboard');

        } catch (Exception $e) {
            error_log('VK Auth error: ' . $e->getMessage());
            header('Location: /login?error=vk_auth_failed');
        }
        exit;
    }
}

Автопостинг новостей в группу VK

<?php
// Публикация новой статьи блога автоматически в VK-группу
// Запускается из cron после публикации

class VkPublisher {
    private VkApi $api;
    private int   $groupId;  // ID группы без минуса

    public function publishArticle(array $article): void {
        $message = $article['title'] . "\n\n"
                 . mb_substr(strip_tags($article['excerpt']), 0, 200) . "...\n\n"
                 . "Читать полностью: https://mysite.ru/blog/" . $article['slug'];

        // Прикрепить ссылку как attachment
        // VK автоматически загружает превью при публикации URL
        $postId = $this->api->wallPost(
            -$this->groupId,
            $message,
            'https://mysite.ru/blog/' . $article['slug']
        );

        error_log("Published to VK, post_id: $postId");

        // Сохранить post_id для статистики
        ArticleRepository::update($article['id'], ['vk_post_id' => $postId]);
    }
}

Получение статистики группы

<?php
// Статистика сообщества за последние 7 дней
$stats = $vkApi->call('stats.get', [
    'group_id'   => GROUP_ID,
    'date_from'  => date('Y-m-d', strtotime('-7 days')),
    'date_to'    => date('Y-m-d'),
]);

foreach ($stats as $day) {
    echo $day['day'] . ': ';
    echo 'Охват: ' . ($day['reach'] ?? 0) . ', ';
    echo 'Подписчики+: ' . ($day['subscribers']['joined'] ?? 0) . ', ';
    echo 'Подписчики-: ' . ($day['subscribers']['left'] ?? 0) . "\n";
}

Rate Limits VK API 2015

ВКонтакте ограничивал: 3 запроса в секунду с одного access_token. При превышении - ошибка code: 6, Too many requests per second.

// Простой throttle через sleep
class ThrottledVkApi extends VkApi {
    private float $lastRequest = 0;

    public function call(string $method, array $params = []): array {
        $elapsed = microtime(true) - $this->lastRequest;
        if ($elapsed < 0.34) {  // 3 req/sec = 333ms между запросами
            usleep((int)((0.34 - $elapsed) * 1_000_000));
        }
        $this->lastRequest = microtime(true);
        return parent::call($method, $params);
    }
}

ВКонтакте оставался самой важной соцсетью для продвижения в России до 2018-2019, когда Instagram начал вытеснять его у молодёжной аудитории.

Читайте также

IT аутсорсинг в Кыргызстан для российских компаний: как это работает в 2026aunimeda
Веб-разработка

IT аутсорсинг в Кыргызстан для российских компаний: как это работает в 2026

Почему российские компании всё чаще заказывают разработку у кыргызских студий: ценовое преимущество, общий язык, часовой пояс. Как организовать работу с командой из Бишкека.

Разработка интернет-магазина в 2026 году: технологии, стоимость, подводные камниaunimeda
Веб-разработка

Разработка интернет-магазина в 2026 году: технологии, стоимость, подводные камни

Сколько стоит разработка интернет-магазина в 2026 году, какие технологии выбрать (Next.js, WooCommerce, кастомный бэкенд), как избежать типичных ошибок и что нужно знать до начала разработки.

Micro-SaaS в России: как запустить прибыльный продукт командой 2-3 человека в 2026aunimeda
Веб-разработка

Micro-SaaS в России: как запустить прибыльный продукт командой 2-3 человека в 2026

Micro-SaaS - это узкий SaaS-продукт для конкретной ниши, который можно построить и поддерживать маленькой командой. В 2026 году ИИ-инструменты сделали это реальным для разработчиков без венчурного финансирования.

Нужна IT-разработка для вашего бизнеса?

Разрабатываем сайты, мобильные приложения и AI-решения для бизнеса в России. Бесплатная консультация.

Разработка сайтов

Получить консультацию Все статьи