четверг, февраля 4

Получаем курсы валют (класс для PHP)



В очередном проекте встала тривиальная задача вывода курсов валют на страницах сайта. Но стандартные информеры курсов валют очень портили дизайн сайта, вследствие чего я решил написать парсер курсов валют с сайта Центрального Банка Российской Федерации.

В последнее время, я перешел на разработку проектов на Zend Framework, поэтому представленная реализация заточена для использования в PHP приложениях на ZF.

Итак, начнем с самого класса. Здесь все просто:
  • есть public метод getValuta, который принимает буквенный код валюты и выдает ее курс относительно рубля
  • он обращается к защищенному методу getXML, который инициализирует объект класса Zend_Rest_Client для обработки XML данных с курсами валют
  • getXML проверяет наличие закэшированной копии данных и в зависимости от результата проверки создает новый кэш данных и читает оттуда курсы, либо обращается к существующему; делается это с помощью методов getNewXML и getOldXML соответственно.
Исходный код файла Kursi.php
  1. /**
  2. *
  3. * @author Jacob Akulov (Яков Акулов)
  4. * @desc Модель получения курсов валют по данным ЦБ РФ
  5. *
  6. */
  7. class Kursi {
  8. protected $_name = 'Kursi';
  9. protected $valutaClient;
  10. // определяем допустимые коды валют
  11. protected $valutaCodes = array(
  12. 'R01235'=>'USD',
  13. 'R01239'=>'EUR',
  14. 'R01035'=>'GBP',
  15. 'R01090'=>'BYR',
  16. 'R01335'=>'KZT',
  17. 'R01375'=>'CNY',
  18. 'R01720'=>'UAH'
  19. );
  20. //контруктор класса
  21. public function __construct() {}
  22. // получение курса вылют по коду
  23. public function getValuta($code) {
  24. self::getXML(); // получаем данные в виде XML (заносятся в объект Zend_Rest_Client, $this->valutaClient)
  25. // проверяем допустимость кода валюты
  26. if (!in_array($code, $this->valutaCodes)) {return false;}
  27. else {
  28. if($this->valutaClient) {
  29. $values = $this->valutaClient->key('Valute')->get()->Value(); // получаем значения курсов всех валют
  30. $codes = $this->valutaClient->key('Valute')->get()->CharCode(); // получаем их коды
  31. $currency = array_combine($codes, $values); // совемещаем все это в один масссив
  32. return $currency[$code]; // и выдаем результата
  33. }
  34. else {
  35. return false;
  36. }
  37. }
  38. }
  39. // создание клиента для обработки XML с курсами валют
  40. private function getXML() {
  41. // проверяем наличие кэшированной XML
  42. if(file_exists('public/kursi/valuta-'.date('Y-m-d').'.xml') && file_exists('public/kursi/metall-'.date('Y-m-d').'.xml')) {
  43. self::getOldXML(); // берем данные из кэша
  44. }
  45. else {
  46. self::getNewXML(); // иначе загружаем данные с сайта ЦБ РФ и кэшируем их
  47. }
  48. }
  49. // получение данных с сайта ЦБ РФ и создание локального кэша
  50. private function getNewXML() {
  51. $val = file_get_contents('http://www.cbr.ru/scripts/XML_daily.asp'); // читаем данные из ЦБ РФ и пишем их в кэш
  52. file_put_contents('public/kursi/valuta-'.date('Y-m-d').'.xml', $val);
  53. // создаем REST клиента и получаем данныые
  54. $this->valutaClient = new Zend_Rest_Client('http://sitename/public/kursi/valuta-'.date('Y-m-d').'.xml');
  55. }
  56. // получение данных из кэша
  57. private function getOldXML() {
  58. $this->valutaClient = new Zend_Rest_Client('http://sitename/public/kursi/valuta-'.date('Y-m-d').'.xml');
  59. }
  60. }
* This source code was highlighted with Source Code Highlighter.


В данной реализации время обновление кэша будет в полночь по времени веб-сервера. Я не знаю, когда там Центробанк обновляет курсы, поэтому решил оставить так. Также в моем классе не предусмотрено удаления старых кэш копий XML файлов, т.к. в моем проекте есть сборщик мусорных файлов, который запускается по cron-у.

Дальше, после создания модели (класса) в реализации на Zend Framework мы создаем контроллер и вьюху (просто для наглядног представления результата). Они очень простые и не требует дополнительных пояснений:

Контроллер:
  1. class KursiController extends Zend_Controller_Action
  2. {
  3. function init() {
  4. $this->config = Zend_Registry::get('config');
  5. // загружаем класс для получения курсов
  6. Zend_Loader::loadClass('Kursi', $this->config->path->models_dir);
  7. // создаем его объект
  8. $this->kursi = new Kursi();
  9. }
  10. // экшн
  11. function indexAction() {
  12. // передаем во view сразу значения валют
  13. $this->view->assign('USD',$this->kursi->getValuta('USD'));
  14. $this->view->assign('EUR',$this->kursi->getValuta('EUR'));
  15. }
  16. }
* This source code was highlighted with Source Code Highlighter.





View:
  1. <ul class="kursi">
  2. <h3>Курсы валютh3>
  3. <li><span>$ Доллар СШАspan> <b>=$this->USD?>b>li>
  4. <li><span> ЕВРОspan> <b>=$this->EUR?>b>li>
  5. ul>
* This source code was highlighted with Source Code Highlighter.




В результате при обращении к созданному контроллеру получаем такой вывод:


Вы также можете скачать класс Kursi.php. С удовольствием приму ваши замечания и улучшения для описанного скрипта.

Реализация получения и вывода курсов валют (дополненная курсами драгоценных металлов) мою использована на сайте самарских ломбардов.

Постоянные читатели