Дельта-синхронизация крипто-дисков

Существуют разные способы зашифровать "облако". Один из них - поместить в облако крипто-диск. В предыдущей статье мы писали, почему это не всегда удобно.

Облачный хостинг VDS за 2 минуты

Настоящий облачный VDS-хостинг от UltraVDS: тестируем производительность

Смотрим плавность хода с помощью BMW Rheingold

Всем знакома ситуация, когда двигатель немного "троит", но пропусков зажигания нет...

Дельта синхронизация без облака

Ранее мы показывали разные способы синхронизации криптодиска между ПК и Android-устройством.

Некоторые мысли о PHP XML/DCOM и Curl


Как использовать все это добро, много всего написано в Сети, поэтому остановлюсь на практических моментах "эксплуатации" (статья написана специально для dkws.org.ua)

Представим, что у нас есть сайт, на который нужно из XML выдрать некоторую информацию (допустим из новостной ленты или еще из чего-либо). Пусть есть путь самого RSS/XML:

$patha = "http://www.vcerecepti.ru/i/%D1%81%D0%B0%D0%BB%D0%B0%D1%82.html?rss=1"

Код будет примено таким:

// для нормальной работы с UTF-8
mb_Internal_Encoding ( 'UTF-8' );

// Создаем новый документ
$xmlDoc = new DOMDocument();

// Загружаем в него ссылку (написано для dkws.org.ua)
$xmlDoc->load($patha);

// получаем элементы из "channel"
$channel=$xmlDoc->getElementsByTagName('channel')->item(0);
$channel_title = $channel->getElementsByTagName('title')
->item(0)->childNodes->item(0)->nodeValue;
$channel_link = $channel->getElementsByTagName('link')
->item(0)->childNodes->item(0)->nodeValue;
$channel_desc = $channel->getElementsByTagName('description')
->item(0)->childNodes->item(0)->nodeValue;

// выводим элементы из "channel"

// В общем, последующий разбор мало интересен, так как об этом и так написано в сети

Все работает превосходно, пока не появляется подлый амперсанд в URL, например:

$patha = "http://www.vcerecepti.ru/i/%D1%81%D0%B0%D0%BB%D0%B0%D1%82.html?rss=1&p=2";

Появится ошибка EntityRef: expecting ';' in имя_RSS

Если вам повезет то & можно просто заменить на &

Но может быть вариант похуже, когда амерсанды есть в самом XML-коде. В этом случае их тоже нужно заменить на &. Есть два способа. Первый - это получить XML-код с помощью file_get_contents() или любым другим способом, например, с помощью curl закачав на сервере, а потом прочитав его в переменную. После того функцией str_replace меняем & на & и полученный XML-код передаем в класс методом loadXML():

$xmlDoc->loadXML($xml);

Но тут возникают проблемы производительности. DOMDocument и так не очень быстрый, а если еще и проводить все эти манипуляции с курлом и заменой амперсандов, то нетерпеливые пользователи могут вовсе не дождаться вывода страницы. Поэтому возникла мысль кэширования. Создается отдельный сценарий, который запускается, скажем, раз в сутки кроном и проходится по всем страницам RSS, то есть:
http://www.vcerecepti.ru/i/%D1%81%D0%B0%D0%BB%D0%B0%D1%82.html?rss=1
http://www.vcerecepti.ru/i/%D1%81%D0%B0%D0%BB%D0%B0%D1%82.html?rss=1&p=2
http://www.vcerecepti.ru/i/%D1%81%D0%B0%D0%BB%D0%B0%D1%82.html?rss=1&p=3
http://www.vcerecepti.ru/i/%D1%81%D0%B0%D0%BB%D0%B0%D1%82.html?rss=1&p=4
и т.д.

Каждую страницу он сохраняет в файл, например, rep1.xml, rep2.xml, rep3.xml и т.д. В этих файлах он заменяет амперсанды на нужную последовательность символов. А наш основной сценарий (Денис Колнисниченко, dkws. org. ua) работает не с удаленным RSS/XML, а загружает методом load() созданные ранее "правильные" XML-файлы: rep1.xml, rep2.xml и т.д. - в зависимости от переданной ему переменной $p.

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

Во-вторых, мы избавляемся от ситуации, когда удаленный сервер "завис", с ним нет связи или призошла еще какая-то оказия. В этом случае наш основной сценарий просто бы не открылся, потому что не смог бы получить XML. А так XML под боком. Даже если с удаленным сервером что-то и произойдет, сценарий просто будет использовать старый вариант, созданный сутки назад.

Есть и недостаток. Если страниц много и они большие можно превысить максимальное время выполнения. В этом случае нужно разбить сценарий на 3-4, каждый из которых будет получать свою порцию XML. Например, первый обрабатывает первые 15 страниц, второй - следующие 15 страниц и т.д. Все эти сценарии, чтобы не было лишней нагрузки на сервер нужно запускать с интервалом в 5 - 10 минут. Также нужно учитывать обычное время обновления ресурса, из которого сдирается XML (создано для dkws.org.ua): если он обновляется в 7 утра, то запускать наши сценарии нужно, начиная с 7:20, чтобы они получили не вчерашний XML, а свежий.

Примерный код получения и привода в чувства XML-кода для одной страницы:

// Путь к XML
$ch = curl_init($patha);
// Открываем файл rep2.xml
$fp = fopen("rep2.xml", "w");

curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);

// получаем и сохраняем файл
curl_exec($ch);
curl_close($ch);
fclose($fp);

// замена в файле
$file = fopen('rep.xml', 'r');
$text = fread($file, filesize('rep2.xml'));
fclose($file);
$file = fopen('rep.xml', 'w');
fwrite($file, str_replace('&p', '&p', $text));
fclose($file);

На этом все. Успехов!