Получение курсов валют с сайта Центробанка
При разработке интернет-магазинов или различных информеров для сайтов часто приходится реализовывать получение актуальных курсов валют. Не все разработчики знают, что достаточно удобно получать курсы на любую дату используя API сайта Центрального банка РФ.
Курсы на сутки вперёд доступны в формате XML по адресу
http://www.cbr.ru/scripts/XML_daily.asp
Для получения данных на любую прошедшую дату нужно воспользоваться параметром date_req
http://www.cbr.ru/scripts/XML_daily.asp?date_req=12.07.2012
Теперь на нашем сайте нам достаточно распарсить XML файл и выбрать нужные валюты. Для выбора элементов из дерева можно использовать DOM или другие расширения для работы с XML.
Напишем класс, загружающий данные о курсах валют:
/** * @author ElisDN <mail@elisdn.ru> * @link https://elisdn.ru */ class CBRAgent { protected $list = array(); public function load() { $xml = new DOMDocument(); $url = 'http://www.cbr.ru/scripts/XML_daily.asp?date_req=' . date('d.m.Y'); if (@$xml->load($url)) { $this->list = []; $root = $xml->documentElement; $items = $root->getElementsByTagName('Valute'); foreach ($items as $item) { $code = $item->getElementsByTagName('CharCode')->item(0)->nodeValue; $curs = $item->getElementsByTagName('Value')->item(0)->nodeValue; $this->list[$code] = floatval(str_replace(',', '.', $curs)); } return true; } return false; } public function get($cur) { return isset($this->list[$cur]) ? $this->list[$cur] : 0; } }
Теперь мы можем загружать и считывать значения курса любой валюты относительно рубля:
$cbr = new CBRAgent(); if ($cbr->load()) { $usd_curs = $cbr->get('USD'); }
Обновление курсов нескольких валют в Yii Framework может, например, выглядеть так:
public function updateCurrencies() { $cbr = new CBRAgent(); if ($cbr->load()) { $models = Currency::model()->findAll() foreach ($models as $model) { $model->curs = $cbr->get($model->name); $model->save(); } } }
или так:
public function updateCurrencies() { $cbr = new CBRAgent(); if ($cbr->load()) { $currencies = array('USD', 'EUR'); foreach($currencies as $currency) { Yii::app()->config->set('SHOP.CURS_' . $currency, $cbr->get($currency)); } } }
если хранение курсов производится в каком-либо компоненте.
Этот метод можно поместить в контроллер магазина и вызывать по таймауту или поместить в консольную команду и вызывать по Cron.
ВиталийНе могу понять, какого хрена http://www.cbr.ru/scripts/XML_daily.asp возвращает контент 1 раз из 20-и... Пробовал через file_get_contents, через curl, через сокеты, теперь вот напрямую с помощью DOMDocument...
Через браузер вроде все ок. Иногда сбрасываются соединения, но не так безбожно.
Это руки у меня кривые или это фаервол такой?
Дмитрий ЕлисеевТоже не открывается. Значит админы уже Новый Год празднуют.
АндрейПодскажите как выдернуть дату из ответа <valcurs date="10.04.2014" name="Foreign Currency Market" />
Дмитрий Елисеев$valcurs = $root->getElementsByTagName('valcurs'); echo $valcurs[0]->getAttribute('date');
АндрейСпасибо, но
Fatal error: Call to undefined method DOMNodeList::getAttribute()
не работает(
Еще замечено, что очень часто попытка загрузки через php url http://www.cbr.ru/scripts/XML_daily.asp выводит пустой ответ, на локалке лечится открытием этого урла в браузере, на хостинге - урла через wget.
Как побороть кто знает? Curl?
Дмитрий ЕлисеевТогда можно попробовать что-то вроде:
echo $valcurs->item(0)->getAttribute('date');В общем, выцепить из массива первый элемент.
Akejа как запустить контроллер по таймауту??
AkejВернее запустить метод контроллера по таймауту?
Дмитрий ЕлисеевОформить как консольную команду и настроить её запуск по Cron (должен быть в панели управления хостинга) как здесь.
Дмитрий – vk.comот 06.11.2014
class CBRAgent{ protected $list = array(); public function load(){ $url = 'http://www.cbr.ru/scripts/XML_daily.asp?date_req='.date('d.m.Y', time()); $xml = simplexml_load_file($url); if($xml){ foreach ($xml as $item){ $code = strval($item->CharCode); $curs = $item->Value; $this->list[$code] = floatval(str_replace(',', '.', $curs)); } return true; }else{ return false; } } public function get($cur){ return isset($this->list[$cur]) ? $this->list[$cur] : 0; } } $cbr = new CBRAgent(); if ($cbr->load()){ $usd_curs = $cbr->get('USD'); }
Евгенийпростое кэширование на диске(public_html) раз в день по запросу без всяких кронов
class CBRAgent { protected $list = array(); public function load() { $xml = new \DOMDocument(); $filepath = 'curs_valute_'.date('d.m.Y').'.xml'; if(file_exists($filepath)){ $tosave = false; $path = $filepath; } else { $tosave = true; $path = 'http://www.cbr.ru/scripts/XML_daily.asp?date_req=' . date('d.m.Y'); } if (@$xml->load($path)) { if($tosave){ array_map('unlink', glob('curs_valute_*.xml')); @$xml->save($filepath); } $this->list = array(); $root = $xml->documentElement; $items = $root->getElementsByTagName('Valute'); foreach ($items as $item) { $code = $item->getElementsByTagName('CharCode')->item(0)->nodeValue; $curs = $item->getElementsByTagName('Value')->item(0)->nodeValue; $this->list[$code] = floatval(str_replace(',', '.', $curs)); } return true; } else return false; } public function get($cur) { return isset($this->list[$cur]) ? $this->list[$cur] : 0; } }
ВладДобрый день Дмитрий. Помогите создать 2 информера курса валют: евро и доллара. Я далек от программирования. Буду признателен.
Дмитрий ЕлисеевСкопируйте себе HTML-код готовых вроде этих.
kursvaliut – www.kursvaliut.rukursvaliut.ru позволяет взять бесплатный ежедневный обновленный курс валют ЦБ или в том числе конвертер валют включив простой JavaScript :)
Александрболее универсальный api для получения курсов валют чем cbr currate.ru