Работа с Яндекс API из PHP: эффективные решения

Раздел: Работа с API -> Яндекс API

Основные подходы к интеграции с Яндекс API в PHP

Как подключиться к Яндекс API с помощью официального PHP SDK?

Официальный SDK от Яндекса - yandex-php-library - предоставляет единый интерфейс для работы с Диском, Метрикой, Картами и другими сервисами. Этот метод наиболее надёжен, поскольку SDK берёт на себя обработку токенов, повторные попытки при сбоях и сериализацию данных.

Установка через Composer:

composer require yandex/yandex-php-library

Yandex php (интеграция с яндекс в php)

Для начала работы потребуется OAuth-токен, полученный в кабинете разработчика. После получения токена можно инициализировать клиент:


use Yandex\Disk\DiskClient;

$token = 'ваш_токен';
$client = new DiskClient($token);
$client->setServiceScheme(DiskClient::HTTPS_SCHEME);
  

Пример получения списка файлов на Диске:


$disk = new \Yandex\Disk\DiskClient($token);
$disk->setServiceScheme(\Yandex\Disk\DiskClient::HTTPS_SCHEME);
$files = $disk->directoryContents();
print_r($files);
  

Типичные проблемы: Токен может истечь (срок жизни OAuth-токена - 1 год). При ошибке 401 необходимо обновить токен через рефреш. В SDK нет встроенного механизма обновления, поэтому нужно реализовать его самостоятельно. Также возможны лимиты запросов (5 запросов в секунду для Диска). При превышении возвращается ошибка 429 Too Many Requests.

Цель этого подхода - быстрая разработка типовых интеграций без написания HTTP-обёрток. Используется в проектах, где требуется доступ к нескольким сервисам Яндекса.

Как отправить запрос к Яндекс API через cURL?

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

Пример получения информации о пользователе Яндекс.Паспорта:


$token = 'ваш_токен';
$ch = curl_init('https://login.yandex.ru/info?format=json');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: OAuth ' . $token
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($httpCode === 200) {
    $data = json_decode($response, true);
    // работа с данными
}
  

Проблемы: При использовании кириллицы в параметрах нужно кодировать URL (urlencode). Ошибка 403 означает недостаточные права токена. Для отправки файлов на Диск требуется multipart/form-data, что усложняет код.

Цель - лёгкая интеграция без дополнительных зависимостей. Рекомендуется для простых скриптов или микросервисов.

Как использовать Guzzle для работы с Яндекс API?

Guzzle - мощная HTTP-библиотека, которая упрощает отправку запросов, обработку Promise и повторные попытки. Интеграция с Яндекс API через Guzzle удобна, если проект уже использует Composer и PSR-7.

Пример получения списка файлов с Яндекс.Диска:


use GuzzleHttp\Client;

$client = new Client([
    'base_uri' => 'https://cloud-api.yandex.net/v1/disk/',
    'headers' => [
        'Authorization' => 'OAuth ' . $token
    ]
]);

$response = $client->get('resources', [
    'query' => ['path' => '/']
]);

$body = $response->getBody()->getContents();
$data = json_decode($body, true);
  

Guzzle автоматически выбрасывает исключения при HTTP-ошибках, что упрощает отладку.

Типичные ошибки: Неправильное указание base_uri (без слеша в конце) приводит к 404. При работе с загрузкой файлов на Диск нужно использовать multipart-запросы. Guzzle версии 7+ обрабатывает их встроенными средствами.

Этот вариант используют в приложениях, где требуется высокая гибкость (например, параллельные запросы через Guzzle Pool).

Как интегрироваться с Яндекс.Диском через API?

Для работы с Яндекс.Диском (загрузка, создание папок, скачивание) можно использовать как SDK, так и прямой REST API. Ниже пример загрузки файла через cURL с использованием токена.


$token = 'ваш_токен';
$filePath = '/путь/к/файлу.txt';
$ch = curl_init('https://cloud-api.yandex.net/v1/disk/resources/upload?path=file.txt');
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: OAuth ' . $token]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$data = json_decode($response, true);
if (isset($data['href'])) {
    // Получена ссылка для загрузки
    $uploadUrl = $data['href'];
    // Далее отправляем файл на этот URL
}
  

Проблемы: Для больших файлов (более 10 МБ) требуется использовать chunked upload. В SDK это реализовано, при прямом использовании API нужно писать логику разбиения.

Цель - гибкое управление файлами: резервное копирование, бэкапы баз данных, синхронизация.

Как получить координаты через Яндекс.Карты (геокодирование)?

API Яндекс.Карт предоставляет геокодер - преобразование адреса в координаты. Для запросов нужен API-ключ (не токен, а ключ для сервиса «Геокодер»).


$apiKey = 'ваш_ключ';
$address = urlencode('Москва, Кремль');
$url = "https://geocode-maps.yandex.ru/1.x/?format=json&apikey=$apiKey&geocode=$address";

$response = file_get_contents($url);
$data = json_decode($response, true);
$pos = $data['response']['GeoObjectCollection']['featureMember'][0]['GeoObject']['Point']['pos'];
list($lon, $lat) = explode(' ', $pos);
  

Ошибки: Неверный API-ключ (код 403). Превышение лимита запросов - в бесплатном тарифе 250 запросов в сутки.

Цель - отображение объектов на карте, расчёт расстояний, автоматическое заполнение адресов.

Как получить статистику Яндекс.Метрики через API?

API Метрики позволяет получать данные счётчиков: посещения, источники трафика, цели. Для авторизации используется OAuth-токен с правами на чтение статистики.


$token = 'ваш_токен';
$counterId = 123456;
$url = "https://api-metrika.yandex.net/stat/v1/data?ids=$counterId&metrics=ym:s:visits,ym:s:users";

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: OAuth ' . $token]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$data = json_decode($response, true);
print_r($data['data']);
  

Проблемы: Разные версии API (v1, v2) требуют разные пути. Ошибка 403 может означать, что у токена нет доступа к счётчику. Также нужно учитывать ограничение на количество запросов: 10 запросов в секунду.

Цель - построение отчётов, выгрузка данных в BI-системы, мониторинг трафика.

Расширенные примеры интеграции с Яндекс API на PHP

Полноценный класс для работы с Яндекс.Диском

Класс инкапсулирует авторизацию, загрузку и скачивание файлов, обработку ошибок и обновление токена.

Пример

class YandexDiskClient
{
    private $token;
    private $baseUrl = 'https://cloud-api.yandex.net/v1/disk/';

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

    public function getFiles(string $path = '/'): array
    {
        $url = $this->baseUrl . 'resources?path=' . urlencode($path);
        $response = $this->request('GET', $url);
        return json_decode($response, true)['_embedded']['items'] ?? [];
    }

    public function uploadFile(string $localPath, string $remotePath): bool
    {
        // 1. Получаем ссылку для загрузки
        $url = $this->baseUrl . 'resources/upload?path=' . urlencode($remotePath);
        $response = json_decode($this->request('GET', $url), true);
        if (!isset($response['href'])) {
            throw new Exception('Cannot get upload URL');
        }
        $uploadUrl = $response['href'];

        // 2. Загружаем файл
        $ch = curl_init($uploadUrl);
        curl_setopt($ch, CURLOPT_PUT, true);
        curl_setopt($ch, CURLOPT_INFILE, fopen($localPath, 'r'));
        curl_setopt($ch, CURLOPT_INFILESIZE, filesize($localPath));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $body = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        return $httpCode === 201;
    }

    public function downloadFile(string $remotePath, string $localPath): bool
    {
        $url = $this->baseUrl . 'resources/download?path=' . urlencode($remotePath);
        $response = json_decode($this->request('GET', $url), true);
        if (!isset($response['href'])) {
            throw new Exception('Cannot get download URL');
        }
        $downloadUrl = $response['href'];

        $ch = curl_init($downloadUrl);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $content = curl_exec($ch);
        curl_close($ch);

        file_put_contents($localPath, $content);
        return true;
    }

    private function request(string $method, string $url): string
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Authorization: OAuth ' . $this->token
        ]);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
        $result = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($httpCode === 401) {
            // Требуется обновление токена
            throw new Exception('Token expired');
        }
        if ($httpCode >= 400) {
            throw new Exception("HTTP error $httpCode: " . substr($result, 0, 200));
        }
        return $result;
    }
}

Пример использования:

Пример

$client = new YandexDiskClient('ваш_токен');
$files = $client->getFiles('/');
print_r($files);
$client->uploadFile('/tmp/test.txt', 'test.txt');
$client->downloadFile('test.txt', '/tmp/downloaded.txt');

Результат вывода для getFiles (сокращён):

Array
(
    [0] => Array
        (
            [name] => test.txt
            [type] => file
            [size] => 1234
            ...
        )
)

Геокодирование с помощью Яндекс.Карт с обработкой пагинации

Пример, когда адрес может дать несколько результатов (например, улица в разных городах).

Пример

function geocode(string $address, string $apiKey, int $page = 0): array
{
    $params = [
        'format' => 'json',
        'apikey' => $apiKey,
        'geocode' => $address,
        'results' => 10,
        'skip' => $page * 10
    ];
    $url = 'https://geocode-maps.yandex.ru/1.x/?' . http_build_query($params);
    $response = file_get_contents($url);
    $data = json_decode($response, true);
    $members = $data['response']['GeoObjectCollection']['featureMember'];
    $results = [];
    foreach ($members as $member) {
        $pos = $member['GeoObject']['Point']['pos'];
        list($lon, $lat) = explode(' ', $pos);
        $results[] = [
            'address' => $member['GeoObject']['metaDataProperty']['GeocoderMetaData']['text'],
            'lat' => $lat,
            'lon' => $lon
        ];
    }
    return $results;
}

$apiKey = 'ваш_ключ';
$addresses = geocode('Ленина', $apiKey);
foreach ($addresses as $place) {
    echo $place['address'] . ' -> ' . $place['lat'] . ',' . $place['lon'] . PHP_EOL;
}

Результат (пример):

Россия, Москва, улица Ленина -> 55.756, 37.621
Россия, Санкт-Петербург, проспект Ленина -> 59.934, 30.296

Получение данных из Яндекс.Метрики с фильтрацией по дате

Пример

function getMetrikaStat(string $token, int $counterId, string $date1, string $date2): array
{
    $url = 'https://api-metrika.yandex.net/stat/v1/data?' . http_build_query([
        'ids' => $counterId,
        'metrics' => 'ym:s:visits,ym:s:pageviews',
        'date1' => $date1,
        'date2' => $date2,
        'dimensions' => 'ym:s:date',
        'sort' => 'ym:s:date'
    ]);
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: OAuth ' . $token]);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($ch);
    curl_close($ch);
    $data = json_decode($response, true);
    return $data['data'] ?? [];
}

$stats = getMetrikaStat('ваш_токен', 123456, '2024-01-01', '2024-01-07');
foreach ($stats as $row) {
    echo $row['dimensions'][0]['name'] . ': visits=' . $row['metrics'][0] . ', pageviews=' . $row['metrics'][1] . PHP_EOL;
}

Результат (сокращён):

2024-01-01: visits=120, pageviews=340
2024-01-02: visits=98, pageviews=280

Пакетная загрузка файлов на Яндекс.Диск с прогрессом

Для больших файлов используется chunked upload. Пример с разбиением на части по 5 МБ.

Пример

function uploadLargeFile(string $token, string $localPath, string $remotePath): void
{
    $baseUrl = 'https://cloud-api.yandex.net/v1/disk/';
    // Получаем ссылку для загрузки
    $ch = curl_init($baseUrl . 'resources/upload?path=' . urlencode($remotePath));
    curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: OAuth ' . $token]);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $response = json_decode(curl_exec($ch), true);
    curl_close($ch);

    $uploadUrl = $response['href'];
    $handle = fopen($localPath, 'rb');
    $chunkSize = 5 * 1024 * 1024; // 5 MB
    $part = 1;
    while (!feof($handle)) {
        $chunk = fread($handle, $chunkSize);
        $curlFile = curl_file_create_from_data($chunk);
        $ch = curl_init($uploadUrl);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, ['file' => $curlFile]);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        if ($httpCode !== 201) {
            throw new Exception("Chunk $part failed with code $httpCode");
        }
        $part++;
    }
    fclose($handle);
}

uploadLargeFile('ваш_токен', '/path/to/bigfile.iso', 'backup.iso');

Результат: Файл успешно загружен на Диск. Код возврата 201 для каждого чанка.

Интеграция с Яндекс в PHP - comments

En
Yandex php (php)