В интернете описано множество решений по получению актуальных курсов валют. Большинство решений основано на бесплатном сервисе Центробанка (подробнее о сервисе на сайте Центробанка).
Казалось бы, хороший и удобный интерфейс от главного экономического регулятора РФ, однако у него есть несколько неприятных особенностей. Самый значительный его минус в том, что IP, с которого вы будете парсить их сервис курсов валют может, быть заблокирован в любой момент совершенно неожиданно для вас. В моем случае я обновлял курс через сервис ЦБ РФ около 2 месяцев, каждый день каждые два часа (для организации очень важно иметь актуальные данные по курсу валют). Причем на сайте не указано никаких ограничений по использованию данного сервиса, более того, они предлагают свой скрипт для получения актуального курса. Если вас заблокировали, с данного IP вы даже не сможете зайти на сайт регулятора. Для заблокированных пользователей они выводят страницу с бесконечной переадресацией. Обычно блокировка длится не более 24 часов, однако нет никаких гарантий, объяснений причин и т. п. В общем и целом предоставляемый ЦБ РФ сервис ненадежен.
Еще один небольшой минус сервиса в том что приходится парсить XML, а это расход ресурсов и потеря быстродействия. Конечно, можно так настроить, что можно будет парсить всего 4-5 строк, однако в идеале и их бы сократить до одной.
В результате поиска альтернатив пришел к выводу, что достойных сервисов предоставляющих курс валюты в удобном формате, соответствующих критериям (надежность, скорость работы, простота использования), просто нет. Кто-то скажет, что можно парсить сервис Европейского ЦБ, ссылку приводить не буду, скажу лишь, что сервис почти такой же как у ЦБ РФ. Однако курсы Европейского ЦБ значительно отличаются от курсов ЦБ РФ и не подходят для использования в России.
Единственным достойным конкурентом сервису нашего ЦБ, является сервис cbrates.rbc.ru. В программе 1С уже давно используют данный сервис и за время использования он доказал свою надежность. Использовать его проще простого: если нужно получить динамику курса, используем следующую ссылку — cbrates.rbc.ru/tsv/cb/Код_курса валюты.tsv. Например, для доллара это будет ссылка cbrates.rbc.ru/tsv/cb/840.tsv В результате получаем пары дата курс, разделенных табуляцией. Разобрать такие пары на массивы проще простого.
Для получения конкретного курса на конкретную дату используется ссылка cbrates.rbc.ru/tsv/Код_валюта/год/месяц/день.tsv, например, для долара это будет cbrates.rbc.ru/tsv/840/2014/11/07.tsv. По ссылке выдается всего одна строка с порядковым номером 1 и курсом на эту дату. Парсить такую строку намного проще, чем XML — сервис нашего ЦБ, а надежность и быстродействие будут выше. Для получения курса я написал простенький класс:
class rbc{
private $url = 'http://cbrates.rbc.ru/tsv/';
private $file = '.tsv';
private $date = 0;
public function __construct($date = null){
if ($date == null){
$date = time();
}
$this -> date = $date;
}
public function get_curs($currency_code){
$url = $this -> url;
$curs = 0;
try{
if (!is_int($currency_code)){
throw new Exception('Передан неверный код валюты');
}
$url .= $currency_code . '/';
if ($this -> date <= 0){
throw new Exception('Передана неверная дата');
}
$url .= date('Y/m/d', $this -> date);
$url .= $this -> file;
$page = file_get_contents($url);
$curs = $this -> parse($page);
}
catch (Exception $e) {
echo 'Не удалось получить курс валюты. ', $e -> getMessage();
}
return $curs;
}
private function parse($file){
if (empty($file)){
throw new Exception('Возможно указан неверный код валюты, также возможно на указанную дату еще не установлен курс валюты, либо сервер "cbrates.rbc.ru" недоступен.');
}
$curs = explode(' ', $file);
if (!empty($curs[1])){
return $curs[1];
}
else{
throw new Exception('Сервер не выдал результатов по данной валюте на указнную дату');
}
}
}
Использовать можно следующим образом:
$curs_today = new rbc(); //Курс сегодня
echo $curs_today -> get_curs(840); //Курс долара, в скобках официальный код валюты
$curs_tommorow= new rbc(strtotime("+1 day")); //Курс на завтра
echo $curs_tommorow -> get_curs(840);
При создании класса передается дата в формате unix time, если нужно получить курс на дату отличную от текущей. Важно вводить код валюты в числовом виде, а не в виде текста. Можно ввести проверку кодов валют, но я не стал усложнять класс.
Автор: kosar91