Работа с Яндекс API из PHP: эффективные решения
Основные подходы к интеграции с Яндекс API в PHP
Как подключиться к Яндекс API с помощью официального PHP SDK?
Официальный SDK от Яндекса - yandex-php-library - предоставляет единый интерфейс для работы с Диском, Метрикой, Картами и другими сервисами. Этот метод наиболее надёжен, поскольку SDK берёт на себя обработку токенов, повторные попытки при сбоях и сериализацию данных.
Установка через Composer:
composer require yandex/yandex-php-libraryYandex 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 для каждого чанка.