Главная > PHP > Парсер курса валют на PHP

Парсер курса валют на PHP

cursПриветствую! После небольшого перерыва, продолжаю публиковать статьи для начинающих PHP программистов. На этот раз решил поделиться решением распространенной задачи — отображение текущего курса валют на сайте.

С начала, как обычно, постановка задачи:
Нам нужно отображать текущий курс доллара и евро относительно рубля, а также разницу между текущем курсом и вчерашним. Для простоты интеграции скрипта с различными сайтами, сделаем его без использования баз данных, курсы валют будут храниться в файле.

Реализация:
Получать текущий курс валюты будем с сайта ЦБРФ. Курс доступен в XML формате по адресу http://www.cbr.ru/scripts/XML_daily.asp. Для парсинга данных воспользуемся расширением PHP под названием SimpleXML (посмотрите phpinfo(), чтобы узнать установлено он или нет).

Стоит отметить, что XML на сайте центробанка обновляется раз в день, с понедельника по пятницу.

Алгоритм работы следующий: Читаем файл с данными. Если данные актуальны, то выводим информацию пользователю. В противном случае парсим XML с сайта ЦБРФ, сохраняем данные в файл и выводим пользователю. Данные в файле будем хранить в сериализованом виде, причем текущий курс и курс за прошедший день (для того чтобы показывать разницу).

Теперь можно написать сам класс для парсинга куса валют:

  1. class curs
  2. {
  3.  const REFRESH_INTERVAL=3600;
  4.  private $dataFile;
  5.  private $source = "http://www.cbr.ru/scripts/XML_daily.asp";
  6.  private $refreshTime;
  7.  public $cursNew;
  8.  public $cursOld;
  9.  
  10.  private $error;
  11.  
  12.  public function __construct($dataFile)
  13.  {
  14.   $this->dataFile=$dataFile;
  15.  
  16.   if(!$f=fopen($this->dataFile, "r")) {
  17.    $this->refresh();
  18.    $this->error=true;
  19.    return false;
  20.   }
  21.   $data=fread($f, filesize($this->dataFile));
  22.   fclose($f);
  23.   $data=unserialize($data);
  24.   $this->refreshTime=$data['refresh_time'];
  25.   $this->cursNew=$data['curs']['new'];
  26.   $this->cursOld=$data['curs']['old'];
  27.   $this->refresh();
  28.  }
  29.  
  30.  public function save()
  31.  {
  32.   $data=array(
  33.    "refresh_time"=>$this->refreshTime,
  34.    "curs" => array(
  35.     "new"=>$this->cursNew,
  36.     "old"=>$this->cursOld
  37.    )
  38.   );
  39.  
  40.  
  41.   if(!$f=fopen($this->dataFile, "w+")) return false;
  42.   fwrite($f, serialize($data));
  43.   fclose($f);
  44.  }
  45.  
  46.  public function refresh()
  47.  {
  48.   if((time()-self::REFRESH_INTERVAL)$this->refreshTime) return true;
  49.  
  50.   if(isset($this->cursNew['date']) && $this->cursNew['date']>=$this->get_timestamp(date("d.m.y"))) return true;
  51.  
  52.   $new_data=$this->readFromCbr();
  53.   $this->refreshTime=time();
  54.   if(is_array($new_data)){
  55.    if($new_data['date']>$this->cursNew['date']){
  56.     $this->cursOld=$this->cursNew;
  57.     $this->cursNew=$new_data;
  58.     $this->save();
  59.    } else {
  60.     return true;
  61.    }
  62.   } else {
  63.    return false;
  64.   }
  65.  }
  66.  
  67.  private function readFromCbr()
  68.  {
  69.   if(!$xml=simplexml_load_file($this->source)) return false;
  70.   $curs['date']=self::get_timestamp($xml->attributes()->Date);
  71.   foreach($xml->Valute as $m){
  72.    if($m->CharCode=="USD" || $m->CharCode=="EUR"){
  73.     $curs[(string)$m->CharCode]=(float)str_replace(",", ".", (string)$m->Value);
  74.    }
  75.   }
  76.   return $curs;
  77.  }
  78.  
  79.  public static function get_timestamp($date)
  80.  {
  81.      list($d, $m, $y) = explode('.', $date);
  82.      return mktime(0, 0, 0, $m, $d, $y);
  83.  }
  84. }

Немного о том как пользоваться классом. Конструктор принимает один параметр — путь к файлу, в котором будут хранится данные парсинга валют (файл должен быть доступен для записи).

  1. $curs=new curs('./cursData.txt'); //Задаем файл для хранения данных
  2. $curs->cursNew["date"]; //Актуальая дата курса
  3. $curs->cursNew["USD"]; //Курс евро текущий
  4. $curs->cursNew["EUR"]; //Курс доллара текущий
  5. $curs->cursOld["USD"]; //Курс евро вчерашний
  6. $curs->cursOld["EUR"]; //Курс доллара вчерашний

Скачать пример можно здесь

Categories: PHP Tags: , ,
Комментарии (18) Уведомления (0) Написать комментарий Уведомление
  1. Эльвира
    22 Июнь 2009 в 19:19 | #1
    Ответить | Цитата

    А у меня почему-то вот что получилось.
    Parse error: syntax error, unexpected ‘&’ in … on line 16.
    $this->dataFile=$dataFile;
    С чем связано возникновение ошибки?
    Подскажите пожалуйста.

  2. Roman
    22 Июнь 2009 в 20:33 | #2
    Ответить | Цитата

    Скачайте код примера здесь. При копировании кода со страницы, он может не работать из-за HTML тегов.

  3. Эльвира
    23 Июнь 2009 в 06:14 | #3
    Ответить | Цитата

    Теперь вот что говорит
    Warning: fread() []: Length parameter must be greater than 0 in ….\curs.php on line 29
    $data=fread($f, filesize($this->dataFile));
    Может быть это связано с версиями программ которыми я пользуюсь? У вас ведь все работает…

  4. Эльвира
    23 Июнь 2009 в 06:29 | #4
    Ответить | Цитата

    Закачала на сервер три файла (curs.php, curs.dat, curs.dat) в одну директорию выдает:
    Parse error: syntax error, unexpected T_CONST, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or ‘}’ in /home/vipcentr/i/p/k/ipkapitonov/public_html/curs.php on line 11
    const REFRESH_INTERVAL=3600;
    Что же я не так делаю?

  5. Эльвира
    23 Июнь 2009 в 06:32 | #5
    Ответить | Цитата

    Извиняюсь третий файл не правильно указала, cursData.txt

  6. Roman
    23 Июнь 2009 в 08:50 | #6
    Ответить | Цитата

    @Эльвира
    Это нормально, при первом запуске скрипта. Он предупреждает, что файл с данными пустой. Запустите скрипт еще раз и ошибка исчезнет.
    P.S. Файл с данными должен быть доступен для записи

  7. Roman
    23 Июнь 2009 в 08:53 | #7
    Ответить | Цитата

    @Эльвира
    Parse error: syntax error, unexpected T_CONST, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR Это, вероятно, из-за того что пропустили скобку, ‘;’ или что-то в этом духе.

  8. Эльвира
    24 Июнь 2009 в 10:46 | #8
    Ответить | Цитата

    Roman :@Эльвира Это нормально, при первом запуске скрипта. Он предупреждает, что файл с данными пустой. Запустите скрипт еще раз и ошибка исчезнет.P.S. Файл с данными должен быть доступен для записи

    :)Верно всё исчезло, на локальном сервере пустая страница отбражается, а на удаленном все та же ошибка со скобками, подсветкой проверила как бы все на месте, а потом я ничего не меняла внутри скрипта, только вот теперь чмод добавила 777, в трех файлах, правильно? а все равно почему-то не работает?

  9. Roman
    24 Июнь 2009 в 19:06 | #9
    Ответить | Цитата

    @Эльвира
    Возможно на сервере версия PHP ниже 5.2

  10. Roman
    24 Июнь 2009 в 19:12 | #10
    Ответить | Цитата

    @Эльвира
    То что отображается пустая страница, это правильно. Для вывода информации нужно прописать:
    echo $curs->cursNew["USD"]; //Выведет курс евро
    echo $curs->cursNew["EUR"]; //Выведет курс доллара
    и т. д.

  11. Эльвира
    25 Июнь 2009 в 05:37 | #11
    Ответить | Цитата

    Получилось, здорово, php это просто чудо какое-то. Спасибо большое, Вам Роман.

  12. punkWJ
    2 Июль 2009 в 10:24 | #12
    Ответить | Цитата

    Спасибо большое, я давно искал ссылочку на xml курса валют!
    Парсер напишу сам! И еще: подскажите где хороший xml c погодой, а то на gismeteo платный стал! =(

  13. Gataffort
    2 Июль 2009 в 19:58 | #13
    Ответить | Цитата

    Нет ничего проще :).

  14. Евгений
    13 Ноябрь 2009 в 15:18 | #14
    Ответить | Цитата

    Постоянно пишет-
    Подключение не установлено, т.к. конечный компьютер отверг запрос на подключение

    Может сталкивались с этим?

  15. 13 Ноябрь 2009 в 15:36 | #15
    Ответить | Цитата

    @Евгений
    Возможно, виноват файрвол.

  16. Евгений
    13 Ноябрь 2009 в 15:47 | #16
    Ответить | Цитата

    Огромнейшее спасибо Roman, так заработался, что о файрволе и не подумал.
    Все отлично работает!

  17. d.pavel.555
    23 Декабрь 2009 в 01:02 | #17
    Ответить | Цитата

    Уважаемый Роман!

    Очень понравился парср, но вот что-то непонятка нарисовалась:
    include «curs.php»;
    $curs=new curs(‘./cursData.txt’);
    $curs->cursNew["date"];
    $curs->cursNew["USD"];
    $curs->cursNew["EUR"];
    $curs->cursOld["USD"];
    $curs->cursOld["EUR"];

    echo $curs->cursOld["USD"];
    echo $curs->cursNew["USD"];

    ужас в том, что файл cursData.txt не изменился и, соответственно, cursOld не выводится. Но если удалить текстовый файл и запустить скрипт — он появляеся уже обновленный, с новыми данными… Что не так?

  18. axel
    11 Май 2010 в 21:46 | #18
    Ответить | Цитата

    прикольно будем пользоваться…..

  1. Пока что нет уведомлений.