1. Go to this page and download the library: Download visavi/rzd-api library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
visavi / rzd-api example snippets
use Rzd\Client;
use Rzd\Request\CarSearch;
use Rzd\Request\TrainSearch;
$client = new Client();
$result = $client->trains->search(new TrainSearch(
origin: '2000000', // Москва
destination: '2004000', // Санкт-Петербург
date: new DateTimeImmutable('+7 days'),
));
foreach ($result as $train) {
printf(
"%s %s → %s, мест %d, от %.2f\n",
$train->number,
$train->departure->format('d.m H:i'),
$train->arrival->format('d.m H:i'),
$train->freeSeats(),
$train->minPrice(),
);
}
// Вагоны первого поезда: параметры собираются из него самого
$cars = $client->cars->search(CarSearch::forTrain($result->trains[0]));
foreach ($cars->withSeats() as $car) {
printf("вагон %s %s, места: %s\n", $car->number, $car->typeName, $car->freePlaces);
}
use GuzzleHttp\Client as GuzzleClient;
use GuzzleHttp\Psr7\HttpFactory;
use Rzd\Client;
use Rzd\Config;
$factory = new HttpFactory();
$client = new Client(
config: new Config(),
httpClient: new GuzzleClient([
'proxy' => 'socks5://127.0.0.1:1080',
'timeout' => 30,
]),
requestFactory: $factory,
streamFactory: $factory,
);
use Rzd\Config;
use Rzd\Enum\Language;
$config = new Config(
// Язык ответов сайта
language: Language::English,
// Без User-Agent сайт отвечает 403, поэтому по умолчанию подставляется браузерный
userAgent: 'MyApp/1.0',
// Дополнительные заголовки к каждому запросу
headers: ['X-Client-ID' => '22900'],
);
$result = $client->trains->search(new TrainSearch(
origin: '2000000',
destination: '2004000',
date: new DateTimeImmutable('2026-08-01'),
adults: 2, // взрослых пассажиров
children: 1, // детей без места
fromSchedule: true, // добавлять поезда из расписания, у которых мест ещё нет
largeFamily: false, // искать места для многодетных
groupCars: false, // группировать вагоны одного типа
));
$result = $client->trains->search(TrainSearch::forStations(
$client->stations->find('Москва'),
$client->stations->find('Санкт-Петербург'),
new DateTimeImmutable('2026-08-01'),
adults: 2,
));
count($result); // сколько поездов найдено
$result->trains; // список Train
$result->withSeats(); // только поезда со свободными местами
$result->cheapest(); // самый дешёвый из тех, где есть места
$result->fastest(); // самый быстрый из тех, где есть места
$result->originName; // название станции отправления
$result->destinationName;
$result->moscowTime; // текущее московское время сайта
$result->partial; // сайт вернул не все поезда направления
$train->number; // 130Х
$train->displayNumber; // номер для показа пользователю
$train->name; // название фирменного поезда, иначе null
$train->description; // категория: СК, ПАСС, СКОР
$train->departure; // DateTimeImmutable по местному времени станции
$train->arrival;
$train->moscowDeparture; // то же по московскому времени
$train->duration; // время в пути в минутах
$train->distance; // расстояние в километрах
$train->carriers; // ['ФПК']
$train->carGroups; // группы вагонов с ценами и местами
$train->freeSeats(); // свободных мест по всем группам
$train->minPrice(); // минимальная цена по всем группам
$train->provider; // система бронирования, нужна для запроса вагонов
$train->originStationCode; // код станции, а не города — тоже нужен для вагонов
$trip = $client->trains->searchReturn($search, new DateTimeImmutable('2026-08-05'));
$trip->forward; // SearchResult туда
$trip->back; // SearchResult обратно
$trip->hasSeats(); // есть места в обе стороны
$trip->minPrice(); // минимальная стоимость поездки целиком
use Rzd\Enum\TransportProvider;
use Rzd\Request\TransferSearch;
$result = $client->transfers->search(new TransferSearch(
origin: '5a13bdc3340c745ca1e8aa54', // Новый Уренгой
destination: '5a13baab340c745ca1e7f31c', // Абакан
date: new DateTimeImmutable('2026-08-20'),
minTrips: 2, // наименьшее число рейсов в цепочке, 1 добавит прямые
maxTrips: 4, // наибольшее, то есть пересадок плюс один
maxResults: 200, // предел числа вариантов
providers: [TransportProvider::Rails], // виды транспорта в поиске
));
$request = TransferSearch::forStations(
$client->stations->find('Новый Уренгой'),
$client->stations->find('Абакан'),
new DateTimeImmutable('2026-08-20'),
);
count($result); // сколько вариантов найдено
$result->routes; // список TransferRoute
$result->withSeats(); // варианты, где места есть на всех плечах
$result->cheapest(); // самый дешёвый
$result->fastest(); // самый быстрый
$route->changes(); // число пересадок
$route->minPrice; // стоимость всей поездки по самым дешёвым местам
$route->maxPrice;
$route->duration(); // время в пути в минутах, вместе с ожиданием
$route->waits(); // ожидание на каждой пересадке, в минутах
$route->waitTotal(); // сколько всего стоять на пересадках
$route->departure(); // отправление первого рейса
$route->arrival(); // прибытие последнего
$route->origin(); // Place начала поездки
$route->destination();
$route->hasSeats(); // места есть на всех плечах
$route->trips(); // все рейсы поездки подряд, list<Trip>
$route->legs; // плечи, list<RouteLeg>
$route->transfers; // переезды между вокзалами, list<Transfer>
$trip->number; // номер поезда, например 002Э
$trip->transportType; // Train, Bus, Airplane
$trip->origin; // Place, с названием станции и города
$trip->destination;
$trip->departure;
$trip->arrival;
$trip->duration(); // время в пути в минутах
$trip->distance; // километров
$trip->freePlaces;
$trip->minPrice;
$trip->maxPrice;
$trip->products; // классы обслуживания с ценами, list<TripProduct>
$trip->train(); // Train со всеми данными обычного поиска, либо null
foreach ($route->trips() as $trip) {
foreach ($trip->train()?->carGroups ?? [] as $group) {
printf("%s %d мест от %s\n", $group->typeName, $group->places, $group->minPrice);
}
}
$transfer->origin?->name; // Ярославль (Московский вокзал)
$transfer->destination?->name; // Ярославль-Главный
$transfer->duration; // время переезда в минутах, как у рейса и поездки
$transfer->seconds; // то же без округления
$transfer->price; // стоимость
count($cars); // сколько вагонов
$cars->withSeats(); // только вагоны со свободными местами
$cars->cheapest(); // самый дешёвый из тех, где есть места
$cars->train; // данные поезда, приходят тем же ответом
$car->number; // 09
$car->typeName; // КУПЕ
$car->serviceClass; // 2Э
$car->freePlaces; // «2, 4» как отдаёт сайт
$car->placeNumbers(); // [2, 4] числами, пометки пола отброшены
$car->places; // свободных мест
$car->minPrice;
$car->maxPrice;
$car->serviceCost; // стоимость сервисных услуг, входит в цену
$car->schemeId; // идентификатор схемы вагона
$car->subType; // 64К, определяет схему
foreach ($car->compartments as $compartment) {
printf("купе %s: %s\n", $compartment->number, implode(', ', $compartment->placeNumbers()));
}
use Rzd\Enum\SchemeView;
use Rzd\Request\CarSchemeSearch;
$request = CarSchemeSearch::forCar($car, $train);
$scheme = $client->cars->scheme($request);
$scheme->schemeId; // 567
$scheme->isTwoStorey();
$scheme->has(SchemeView::DesktopSecondStorey);
// Чертёж вагона в SVG
$svg = $client->cars->schemeImage($scheme->schemeId, SchemeView::DesktopFirstStorey);
// Фотографии салона
foreach ($client->cars->images($request) as $image) {
printf("%s %s\n", $image->title, $image->content);
}
// Поиск по части названия, повторяющиеся коды отбрасываются
$stations = $client->stations->suggest('ЧЕБ');
// Первая подходящая станция или null: подсказки отсортированы по близости
// к запросу, поэтому для готового названия города разбирать список незачем
$station = $client->stations->find('Чебоксары');
$station->name; // Чебоксары
$station->code; // 2060620, он нужен для поиска поездов
$station->nodeId; // идентификатор узла нового сайта, нужен для пересадок
$station->cityId; // узел города станции, у самого города равен nodeId
$station->isCity(); // узел города, а не отдельного вокзала
$station->region; // Российская Федерация
$station->type; // Город, Станция, Поселок
$station->timezone; // Europe/Moscow
$station->codes; // ['Railway' => ..., 'Cbdpr' => ..., 'Bus' => ..., 'Avia' => ...]
$station->stationCodes; // коды всех вокзалов города
// Популярные города
$client->stations->popular();
// Популярные направления: готовые пары станций
foreach ($client->stations->directions() as $direction) {
printf("%s → %s\n", $direction->origin?->name, $direction->destination?->name);
}
// Город или станция по идентификатору узла
$client->stations->byNodeId('5a323c29340c7441a0a556bb');
// Даты, на которые между станциями есть поезда с местами
$dates = $client->prices->availability(
'2000000',
'2004000',
new DateTimeImmutable('+1 day'),
new DateTimeImmutable('+21 days'),
);
// Минимальные цены по датам отправления
foreach ($client->prices->calendar('2000000', '2004000', new DateTimeImmutable('+1 day')) as $day) {
printf("%s от %.2f\n", $day->date->format('d.m.Y'), $day->minPrice);
$day->byCarType(); // ['Compartment' => 2037.30, 'Luxury' => 9043.30]
$day->carriers(); // ['ФПК', 'ДОСС']
}
foreach ($client->prices->saleCalendar('2000000', '2004000') as $month) {
printf("%d-%02d: дней в продаже %d\n", $month->year, $month->month, count($month->saleDays));
$month->availableDays; // числа месяца, на которые есть поезда
$month->saleDays; // числа месяца, на которые открыта продажа
$month->isOnSale(15); // открыта ли продажа на 15-е
$month->dates(); // те же дни объектами DateTimeImmutable
}
foreach ($client->references->cards() as $card) {
printf("%s %s %.2f\n", $card->code, $card->name, $card->price);
$card->discount; // скидка в процентах
$card->tripQuantity; // число поездок у абонемента
$card->activeDays; // срок действия в днях
$card->carTypes; // ['Compartment', 'Sedentary']
$card->serviceClasses;
$card->isPass(); // абонемент на поездки, а не скидочная карта
$card->fitsCarType('Compartment');
}
foreach ($client->aeroexpress->tariffs(new DateTimeImmutable('+7 days')) as $tariff) {
printf("%s %.2f\n", $tariff->name, $tariff->price);
$tariff->type; // Standard, Business
$tariff->description; // условия применения
$tariff->maxTickets; // сколько билетов можно купить одним заказом
$tariff->guaranteedSeat;
$tariff->documentTypes;
}
use Rzd\Exception\ApiException;
use Rzd\Exception\ForbiddenException;
use Rzd\Exception\InvalidArgumentException;
use Rzd\Exception\MalformedResponseException;
use Rzd\Exception\RzdException;
use Rzd\Exception\TransportException;
try {
$client->trains->search($search);
} catch (TransportException $e) {
// Сайт недоступен: таймаут, обрыв соединения, ошибка прокси.
// Вне РФ самая частая ошибка
} catch (ForbiddenException $e) {
// Запрос отбит защитой сайта, обычно из-за пустого User-Agent
} catch (ApiException $e) {
// Сайт ответил ошибкой
$e->statusCode(); // 500
$e->errorCode(); // INTERNAL_ERROR
$e->body(); // тело ответа целиком
} catch (MalformedResponseException $e) {
// Ответ успешный, но это не JSON
} catch (InvalidArgumentException $e) {
// Некорректные параметры, обнаружены до обращения к сайту
} catch (RzdException $e) {
// Любая ошибка библиотеки
}
$train->get('TrainBrandCode'); // 3033
$train->get('BoardingSystemTypes');
$train->raw; // весь ответ сайта по этому поезду
$result->raw; // весь ответ целиком
sh
php examples/index.php # список примеров
php examples/index.php search_trains # запустить один
php examples/search_trains.php # то же напрямую
RZD_PROXY=socks5://127.0.0.1:1080 php examples/index.php search_trains
Loading please wait ...
Before you can download the PHP files, the dependencies should be resolved. This can take some minutes. Please be patient.