Создаём валютный информер с помощь PHP и JavaScript

Владимир | | Ajax, HTML, JavaScript, PHP, Web разработка.

exchange rates

В этой статье я хочу обсудить подход к добавлению различных информеров на страницы сайта, и показать один из вариантов решения данной задачи.

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

Результат, который должен получиться, можно посмотреть на демонстрационной страничке или запустив пример из архива.

Source

Подключение информера


Существует два основных варианта.

1) Ресурс, который является источником информации, предоставляет код для вставки на вашем сайте. Обычно это JS код, который подгружает данные и формирует внешний вид информера. При этом, иногда владельцы запрещают менять оформление и содержимое информера. В этом случае выбор у вас небольшой: либо пользоваться тем, что дают, либо нет.

2) Данные можно получить в XML или JSON формате. Этот вариант гораздо интереснее, т.к. вы полностью контролируете внешний вид информера и можете выводить только те данные, которые вам нужны. Кроме того, появляется выбор между вариантами загрузки данных.

Т.к. по первому варианту обсуждать, в общем-то, нечего, остановимся на втором.

Получение данных

Тут тоже два варианта.

1) Отправить запрос из PHP скрипта при формировании страницы.

В этом случае не нужно использовать JavaScript, но могут возникнуть задержки при получении данных, которые увеличат общее время формирования страницы. Частично устранить эту проблему можно с помощью кеширования.

2) Получать данные с помощью AJAX запроса.

При этом поддержка JavaScript на стороне клиента обязательна, а время формирования страницы немного уменьшится. Точнее данные в информер будут загружаться после того как посетитель увидит основное содержимое страницы.

Сразу хочу отметить, что оба подхода имеют много общего.

Дело в том, что запрос к стороннему серверу в любом случае придётся отправлять из PHP скрипта. Причина – Same Origin Policy, которую используют все современные браузеры. Эта политика не позволяет JS коду получить доступ к данным, загруженным с другого домена.

Обойти это ограничение можно с помощью JSONP, но реализовать его поддержку должны разработчики сервиса, от которого вы хотите получить данные. Подробнее на эту тему вы можете почитать здесь, здесь и здесь.

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

Источник данных

Для этого примера используем данные о курсах валют, которые предоставляет ресурс pfsoft.com.ua в XML формате. Посмотреть их можно здесь.

Разметка информера

Тут всё просто.

<ul id="rates"><li>Загрузка данных...</li></ul>

Т.к. данные будут загружаться с помощью AJAX запроса, то показываем посетителю сообщение о том, что загрузка начата. Когда данные будут загружены, мы вставим их в список.

Клиентский скрипт

Принцип работы следующий. После загрузки страницы отправляем AJAX запрос на свой сервер. PHP скрипт получает данные от сервера pfsoft.com.ua и отправляет их браузеру.

JS код получает XML строку с данными, находит в ней нужные элементы и добавляет их в список (исходные данные содержат курсы примерно двух десятков валют, но вряд ли имеет смысл выводить их все).

var curCodes = ['RUB', 'USD', 'EUR'];
$(document).ready(function() {
	$.get('getrates.php', function(data) {
		if (data != 'ERR') {
			var rates = '';
			$(data).find('Valute').each(function(key, value) {
				var curCode = $(value).find('CharCode').html();
				if (-1 != $.inArray(curCode, curCodes)) {
					rates += '<li>' + $(value).find('Nominal').html()
						+ ' ' + curCode
						+ ' = ' + $(value).find('Value').html() + ' грн.' + '</li>';
				}
				$('#rates').html(rates);
			});
		}
		else {
			$('#rates').html('<li>Данные не доступны</li>');
		}
	});
});

Прежде всего, создаём массив с кодами валют, которые нужно показать в информере.

Затем, отправляем AJAX запрос (строка 3). PHP скрипт, который выполняет загрузку данных, называется getrates.php.

Если при получении данных возникли ошибки, выводим соответствующее сообщение (строка 17), в противном случае – начинаем обработку XML строки.

Обратите внимание! Мы можем работать с XML данными точно так же, как и с HTML страницей.

Просто создаём объект jQuery ($(data)) и получаем возможность использовать методы find, html, each и т.д.

Здесь мы находим все теги Valute, которые содержат данные об отдельной валюте, а затем из них выбираем код валюты, её курс и формируем элемент списка.

При этом проверяем, указана ли данная валюта в массиве curCodes (строка 8). Кстати, обратите внимание, метод $.inArray возвращает -1 если указанный элемент отсутствует в массиве.

После этого вставляем данные в список (строка 13).

Серверная часть

Рассмотрим скрипт getrates.php.

require_once('ratescache.php');

$rCache = new RatesCache();
//$rCache->expired = 30;

//пробуем получить данные из кеша
if (FALSE === ($data = $rCache->get())) {
	//если данные в кеше устарели, пытаемся получить их от сервера pfsoft.com.ua
	$data = @file_get_contents('http://pfsoft.com.ua/service/currency/');
	//если сервер недоступен, пробуем получить данные из устаревшего кеша
	if (FALSE === $data) {
		$data = $rCache->get(TRUE);
	}
	else {
		//обновляем данные в кеше, предварительно изменяем кодировку на UTF-8
		$rCache->save(iconv('windows-1251','utf-8',$data));
	}
}

if (FALSE !== $data) {
	//отправляем данные
	echo $data;
	exit;
}
//отправляем сообщение об ошибке
echo 'ERR';

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

Прежде всего, хочу объяснить зачем нужен кеш.

Во-первых, его использование сокращает время загрузки данных.

Во-вторых, если у вас посещаемый сайт, и вы будете запрашивать данные для каждого посетителя, то администраторы источника данных могут вас просто забанить (за нагрузку).

В-третьих, кеш позволит получить данные для информера даже если pfsoft.com.ua не доступен.

Итак, алгоритм работы следующий.

1) Создаём экземпляр класса кеша (строка 3) и пробуем получить данные из него (строка 7).

2) Если данные в нём устарели, пробуем получить их от сервера pfsoft.com.ua (строка 9).

3) Если и сервер не отвечает, пытаемся получить данные из устаревшего кеша (строка 12). Кстати, это единственная причина, из-за которой я написал собственную реализацию кеша. Класс RatesCache содержит два метода get и set, причем вызов get(true) вернёт данные, даже если кеш устарел.

4) Если сервер pfsoft.com.ua вернул данные, то обновляем кеш и отправляем их браузеру (строка 16).

5) Если данные получить не удалось (кеш не существует и сервер не отвечает), отправляем сообщение об ошибке (строка 26).

Приводить класс кеша здесь я не буду. Вы всегда можете посмотреть его в исходниках (там, на мой взгляд, достаточно комментариев). К тому же класс довольно простой и написан в основном для этого примера. Если вы используете какой-нибудь фреймворк, то проще будет использовать встроенную библиотеку кеширования.

Результаты

На мой взгляд, показанный здесь вариант создания информера один из самых удобных. С одной стороны он не замедляет формирование страницы (за счет AJAX загрузки), с другой – формируется достаточно быстро (за счет использования кеша).

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

Как всегда, я буду рад ответить на ваши вопросы и замечания!

Интересно почитать

Необычный пример рекламы ресторана от практичных японцев.

Пять способов привлечения клиентов для фирм на b2b-рынке