С помощью данного PHP класса можно быстро определить курс валюты с официального сайта ЦБ РФ.
Ниже сам класс для получения данных.
/**
* Получение курсов валют с сайта Центробанка РФ.
*
* Работает с официальным XML:
* https://www.cbr.ru/scripts/XML_daily.asp
*
* Пример с сайта V-Blog.ru
*
* PHP 8.4+
*/
final class CbrCurrencyRate
{
private const CBR_DAILY_URL = 'https://www.cbr.ru/scripts/XML_daily.asp';
/**
* Получить все курсы валют.
*
* @param DateTimeInterface|null $date Дата курса. Если null — последняя доступная дата.
* @return array<string, array<string, mixed>>
* @throws RuntimeException
*/
public static function getRates(?DateTimeInterface $date = null): array
{
$url = self::CBR_DAILY_URL;
if ($date !== null) {
$url .= '?date_req=' . urlencode($date->format('d/m/Y'));
}
$xmlString = self::loadXml($url);
libxml_use_internal_errors(true);
$xml = simplexml_load_string($xmlString);
if ($xml === false) {
$errors = libxml_get_errors();
libxml_clear_errors();
throw new RuntimeException('Не удалось разобрать XML от ЦБ РФ.');
}
$rates = [];
foreach ($xml->Valute as $valute) {
$charCode = (string) $valute->CharCode;
$nominal = (int) $valute->Nominal;
$value = self::parseCbrNumber((string) $valute->Value);
$rates[$charCode] = [
'id' => (string) $valute['ID'],
'num_code' => (string) $valute->NumCode,
'char_code'=> $charCode,
'nominal' => $nominal,
'name' => (string) $valute->Name,
'value' => $value,
// Удобно: курс за 1 единицу валюты.
// Например, если Nominal = 100, то делим курс на 100.
'rate_for_one' => $value / $nominal,
];
}
return $rates;
}
/**
* Получить одну валюту по буквенному коду: USD, EUR, CNY и т.д.
*
* @throws RuntimeException
*/
public static function getRate(string $code, ?DateTimeInterface $date = null): array
{
$code = strtoupper(trim($code));
$rates = self::getRates($date);
if (!isset($rates[$code])) {
throw new RuntimeException("Валюта {$code} не найдена в ответе ЦБ РФ.");
}
return $rates[$code];
}
/**
* Загрузка XML через cURL.
*
* @throws RuntimeException
*/
private static function loadXml(string $url): string
{
$ch = curl_init($url);
if ($ch === false) {
throw new RuntimeException('Не удалось инициализировать cURL.');
}
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_CONNECTTIMEOUT => 20,
CURLOPT_TIMEOUT => 50,
CURLOPT_USERAGENT => 'Mozilla/5.0 PHP CBR Parser',
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_SSL_VERIFYHOST => 2,
]);
$response = curl_exec($ch);
if ($response === false) {
$error = curl_error($ch);
curl_close($ch);
throw new RuntimeException('Ошибка cURL: ' . $error);
}
$httpCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 200) {
throw new RuntimeException('ЦБ РФ вернул HTTP-код: ' . $httpCode);
}
return $response;
}
/**
* ЦБ РФ в XML отдает числа с запятой:
* 90,1234
*
* PHP нужен формат с точкой:
* 90.1234
*/
private static function parseCbrNumber(string $value): float
{
return (float) str_replace(',', '.', $value);
}
}
Пример получения нескольких валют:
try {
$usd = CbrCurrencyRate::getRate('USD');
$eur = CbrCurrencyRate::getRate('EUR');
$cny = CbrCurrencyRate::getRate('CNY');
echo 'USD: ' . $usd['rate_for_one'] . ' руб.' . PHP_EOL;
echo 'EUR: ' . $eur['rate_for_one'] . ' руб.' . PHP_EOL;
echo 'CNY: ' . $cny['rate_for_one'] . ' руб.' . PHP_EOL;
} catch (Throwable $e) {
echo 'Ошибка: ' . $e->getMessage();
}
Пример получения курса на конкретную дату:
try {
$date = new DateTimeImmutable('2025-12-30');
$usd = CbrCurrencyRate::getRate('USD', $date);
echo 'USD на ' . $date->format('d.m.Y') . ': ';
echo $usd['rate_for_one'] . ' руб.';
} catch (Throwable $e) {
echo 'Ошибка: ' . $e->getMessage();
}
Красивый вывод с округлением
try {
$usd = CbrCurrencyRate::getRate('USD');
echo '1 USD = ' . number_format($usd['rate_for_one'], 2, '.', ' ') . ' руб.';
// если надо 4 знака после запятой то number_format($usd['rate_for_one'], 4, '.', ' ')
} catch (Throwable $e) {
echo 'Ошибка: ' . $e->getMessage();
}
Пример таблицы валют
try {
$rates = CbrCurrencyRate::getRates();
$neededCurrencies = ['USD', 'EUR', 'CNY', 'GBP'];
echo '<table border="1" cellpadding="8" cellspacing="0">';
echo '<tr>';
echo '<th>Валюта</th>';
echo '<th>Название</th>';
echo '<th>Курс за 1 единицу</th>';
echo '</tr>';
foreach ($neededCurrencies as $code) {
if (!isset($rates[$code])) {
continue;
}
$currency = $rates[$code];
echo '<tr>';
echo '<td>' . htmlspecialchars($currency['char_code']) . '</td>';
echo '<td>' . htmlspecialchars($currency['name']) . '</td>';
echo '<td>' . number_format($currency['rate_for_one'], 4, '.', ' ') . ' руб.</td>';
echo '</tr>';
}
echo '</table>';
} catch (Throwable $e) {
echo 'Ошибка: ' . $e->getMessage();
}
Как сделать конвертер валют
// Например, нужно посчитать, сколько рублей будет за 100 долларов:
try {
$usd = CbrCurrencyRate::getRate('USD');
$amount = 100;
$rubles = $amount * $usd['rate_for_one'];
echo $amount . ' USD = ';
echo number_format($rubles, 2, '.', ' ');
echo ' руб.';
} catch (Throwable $e) {
echo 'Ошибка: ' . $e->getMessage();
}
Конвертер из рублей в валюту
// Например, есть 10 000 рублей, нужно узнать сколько это долларов:
try {
$usd = CbrCurrencyRate::getRate('USD');
$rubles = 10000;
$dollars = $rubles / $usd['rate_for_one'];
echo $rubles . ' руб. = ';
echo number_format($dollars, 2, '.', ' ');
echo ' USD';
} catch (Throwable $e) {
echo 'Ошибка: ' . $e->getMessage();
}
Не делайте слишком много запросов к сервису, так как ЦБ РФ может временно заблокировать ваш IP.