Курс валют в базу и на сайт

Главные вкладки

Аватар пользователя digital_sword digital_sword 24 сентября 2011 в 13:24

Добрый день. Вот этот кусок кода берет курс валюты с сайта центробанка.

<?php
if ($fp = fopen("http://www.rbc.ru/out/802.csv", "r")){
    while (!feof($fp)) {
        $buffer = fgets($fp, 4096);
    if (strchr($buffer,mb_convert_encoding("USD ЦБ РФ","Windows-1251","UTF-8"))){
        list($usd,,$dat,$rate,$ism)=explode(',',$buffer);
$curs='<span>USD</span> = '.round($rate, 2).$ism;
echo $curs;

Но видимо оттуда часто шлют не то, или замусоренно, так что периодически выходит ошибка. (А в целом все нормально).
Я хочу записывать курс по крону в базу, а потом просто брать его из базы.
Как этого добиться? Куда его поместить?

Или может просто с другого сайта курс брать?

Комментарии

Аватар пользователя bsyomov bsyomov 24 сентября 2011 в 15:57

Сайт ЦБ РФ http://www.cbr.ru/ Там есть выгрузка курсов в xml. Естественно на каждый запрос неразумно ходить, грузить файл и парсить. Проще всего делать это по крону раз в день и показывать результаты. Данные, кстати, не обязательно хранить в БД.

Аватар пользователя Ch Ch 10 ноября 2015 в 11:47

Вот кстати, вспомнил. В прошлом году делал такой модуль для 6-ки. Он как раз так и работает, по крону загружает данные из ЦБР в базу и потом отображает в блоке. Скинул себе в песочницу, может потом пригодится. Если хочешь потестировать, см. вложенный файл.

Аватар пользователя bsyomov bsyomov 24 сентября 2011 в 19:51

"digital_sword" wrote:
Да, действительно, есть http://www.cbr.ru/scripts/XML_daily.asp .
А как оттуда дернуть курс доллара и евро, и как узнать каково изменение?

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

Аватар пользователя Ch Ch 24 сентября 2011 в 20:07

"bsyomov" wrote:
Парсить xml, есть разные способы - поможет гугл, потом выбирать данные по по коду валюты.

Да не нужен гугл, там же есть готовые сниппеты
http://www.ecb.int/stats/exchange/eurofxref/html/index.en.html#dev
"bsyomov" wrote:
Чтобы отображать изменения, надо иметь 2 файла, вчерашний и сегодняшний, точнее последний и предпоследний, учитывая выходные.

Можно и без этого, если в xml уже есть такая информация.
http://bank-ua.com/export/currrate.xml

Аватар пользователя bsyomov bsyomov 24 сентября 2011 в 22:44

Речь шла о ЦБ РФ, насколько я понимаю, так что смысл в ваших ссылках?
Как парсить xml во-первых полезно почитать, хотя бы для саморазвития, во-вторых есть готовые примеры, как распарсить именно тот xml который отдаёт cbr.ru, если постараться и немного поискать.

У меня где-то был готовый модуль, можно было бы поискать и поделиться, конечно. Но мне кажется, что такую штуку написать, легче, чем найти в завалах, а главное полезно.
Это, кстати хорошая идея, для своего первого модуля, например - вспоминается изречение про рыбу и удочку, знаете-ли.

Если у автора возникнут какие-нибудь вопросы в процессе, я с удовольствием подскажу, что и как. Smile

Аватар пользователя direqtor direqtor 25 сентября 2011 в 1:14

Уже несколько дней готовлю заметку по парсерам валют разных банков.
Код для ЦБР:

function currency_cbr_get_rates() {
  $url = 'http://www.cbr.ru/scripts/XML_daily.asp';
  $result = array();
  if (($datafetch = drupal_http_request($url)) && ($xml = simplexml_load_string($datafetch->data)) && ($xml->getName()=='ValCurs')) {
    $date = date('Ymd');
    foreach($xml->attributes() as $n=>$v) if($n=='Date') $date = implode('', array_reverse(explode('.', $v)));
    foreach ($xml->Valute as $cur)
      if ($cur->getName()=='Valute' && isset($cur->CharCode, $cur->Nominal, $cur->Value))
        $result[] = array(
          'country' => 'RU',
          'bank' => 'CBR',
          'fromvalue' => str_replace (',', '.', (string) $cur->Nominal),
          'fromcurrency' => (string) $cur->CharCode,
          'tovalue' => str_replace(',', '.', (string) $cur->Value),
          'tocurrency' => 'RUB',
          'date' => $date
        );
  }
  return $result;
}

С форматом выдачи думаю разберетесь. А обвязку для блока с курсами, кеширования, запуска по крону легко напишете сами.

Если кому надо курсы одного из этих банков - обращайтесь http://currency.servisator.ru/
На днях думаю выложу коды всех парсеров этого сайта одним файлом в блоге.

Аватар пользователя bsyomov bsyomov 25 сентября 2011 в 8:57

Как идея для указанного выше сайта - было бы нагядно и красиво выводить колебания курса в виде графика, например в разделах "за месяц".
Также, наверное, была бы интересна динамика за квартал и год.
И, возможно, имело бы смысл немного иначе построить навигацию, т.е. из таблицы переходить в раздел "подробнее" а там, например, сделать вкладки день-месяц-квартал-год, а возможно сделать просто как фильтр, с началом и концом временного отрезка. Получилось бы намного функциональние и удобнее.

Аватар пользователя digital_sword digital_sword 25 сентября 2011 в 9:01

Хмм... direqtor , что-то не получается у меня ваш код в блоке вывести:

<?php
  $url = 'http://www.cbr.ru/scripts/XML_daily.asp';
  $result = array();
  if (($datafetch = drupal_http_request($url)) && ($xml = simplexml_load_string($datafetch->data)) && ($xml->getName()=='ValCurs')) {
    $date = date('Ymd');
    foreach($xml->attributes() as $n=>$v) if($n=='Date') $date = implode('', array_reverse(explode('.', $v)));
    foreach ($xml->Valute as $cur)
      if ($cur->getName()=='Valute' && isset($cur->CharCode, $cur->Nominal, $cur->Value))
        $result[] = array(
          'country' => 'RU',
          'bank' => 'CBR',
          'fromvalue' => str_replace (',', '.', (string) $cur->Nominal),
          'fromcurrency' => (string) $cur->CharCode,
          'tovalue' => str_replace(',', '.', (string) $cur->Value),
          'tocurrency' => 'RUB',
          'date' => $date
        );
  }
ehco $result['$tovalue'];
?>

ничего не выводится.
и после print_r($result); тоже ничего...

Аватар пользователя bsyomov bsyomov 25 сентября 2011 в 9:12

А это не надо выводить в блоке. Т.к. делать запрос, парсить данные, и.т.п. на каждый запрос страницы не разумно, да и cbr за такое дёрганье api по головке не погладит.
Этот код, надо запускать по крону и сохранять куда-нибудь данные, а оттуда доставать уже их для показа в блоке.
Причём блок неплохо бы кешировать целиком, т.к. он будет меняться только раз в сутки.

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

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

В модуле надо реализовать две вещи:
-Прицепиться к крону, для периодической загрузки информации. (hook_cron - http://api.drupal.org/api/drupal/developer--hooks--core.php/function/hoo...)
-Выводить блок (hook_block http://api.drupal.org/api/drupal/developer--hooks--core.php/function/hoo...).

Откройте для себя написание модулей, это сильно расширит ваши возможности.

Аватар пользователя digital_sword digital_sword 25 сентября 2011 в 9:26

"bsyomov" wrote:
код, надо запускать по крону и сохранять куда-нибудь данные, а оттуда доставать уже их для показа в блоке.

Вернулись к началу вопроса :).
"bsyomov" wrote:
В модуле надо реализовать две вещи:
-Прицепиться к крону, для периодической загрузки информации. (hook_cron - http://api.drupal.org/api/drupal/developer--hooks--core.php/function/hoo...)
-Выводить блок (hook_block http://api.drupal.org/api/drupal/developer--hooks--core.php/function/hoo...).

В общем-то это и есть ответ на мой первоначальный вопрос. Только как этим хуком пользоваться? Есть пример?

Аватар пользователя bsyomov bsyomov 25 сентября 2011 в 9:47

"digital_sword" wrote:
В общем-то это и есть ответ на мой первоначальный вопрос. Только как этим хуком пользоваться? Есть пример?

Естественно есть, например, на drupal.org есть руководство по созданию модулей с примерами. Есть и тут и информация по применению и примеры, если взять на себя труд поискать, ведь что искать, я вам подсказал...
В рамках форума сложно дать необходимый для понимания объём информации, для этого есть соответствующие материалы - пользуйтесь.

"digital_sword" wrote:
Вернулись к началу вопроса :).

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

Аватар пользователя Ch Ch 25 сентября 2011 в 11:32

"digital_sword" wrote:
Только как этим хуком пользоваться? Есть пример?

См. модуль, который я прикладывал. Под 7-ку его переделать можно за полчаса.
"bsyomov" wrote:
-Прицепиться к крону, для периодической загрузки информации
Можно и без крона. Главное чтобы кэшировалось на определённый срок.

Аватар пользователя bsyomov bsyomov 25 сентября 2011 в 13:17

Там устаревшая инфа, но в общем-то полезная. А если поискать и покопаться, есть темы про создания модулей, и из них можно вытащить нужное.

П.С. Я не посмотрел, что под d7, ссылки которые я дал, по d6, надо смотреть аналогичные разделы по d7. Работа с блоками там отличается.

Аватар пользователя direqtor direqtor 25 сентября 2011 в 13:38

А я как-то почти сразу на руссодокументо забил. Пасусь в основном на дорге в доках и issues. Либо код, код уже сделанных кем-то модулей - это источник знаний...

Аватар пользователя direqtor direqtor 18 октября 2011 в 3:22

Итак, если кому интересно. Парсеры текущих курсов валют центральных банков разных стран мира.

Всего одиннадцать стран: Россия, Китай, Европа, Израиль, Украина, Казахстан, Белоруссия, Грузия, Армения, Канада, Австралия. Принимаю заявки на всякую экзотику, скрипт построен шаблонно.

GPL. Пару вспомогательных функций стырил в Друпале. Так что если кто будет использовать это в модулях, то currency_http_request() и currency_convert_to_utf8().

И не забывайте о кешировании данных. Банк Израиля, например банит сразу, если между запросами менее 10-15 сек.

И вопрос - может мне это в виде модулей оформить?

Аватар пользователя bsyomov bsyomov 18 октября 2011 в 18:18

Имеет смысл сделать модуль создающий блок информера. В админке модуля сделать выбор нужной страны и валют.

Аватар пользователя direqtor direqtor 19 октября 2011 в 8:05

Все страны и все валюты отдельному проекту редко нужны. Я подумывал в виде модуля с блоком на страну. Какие надо, такие выбрал и поставил.

Аватар пользователя bsyomov bsyomov 22 октября 2011 в 7:37

Я собственно это и имел в виду - выбор страны, и набора валют для неё. Более одной страны обычно не нужно.