Перейти к содержимому

Сервис обмена электронных валют

Партнерская программа Kredov

  • Закрытая тема Тема закрыта

И снова кеширование

#1 Kismedia

Kismedia
  • Пользователь
  • 315 сообщений
  • Репутация: 0
0

Отправлено 17 Февраль 2011 - 11:46

Все здрасте! :mellow:

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

Есть скрипт:

if($xml_content = @file_get_contents("http://www.pr-cy.ru/updates.xml")){
$xml = new SimpleXMLElement($xml_content);


$cy = $xml->cy;
$pr = $xml->pr;
$yav = $xml->yav;


На выходе имеем три переменные: $cy, $pr, $yav

Необходимо их записывать в файл cache.txt и держать там, скажем 12 часов.
Если время записи уже не актуально, то выполняем выше приведенный скрипт и записываем эти три значения.

Естественно, впереди идет условие, если данные в cache.txt актуальны по времени, то берем значения переменных от туда.

Надеюсь, сформулировал все понятно.

Спасибо за помощь! :)

 

 

  • 0

#2 admin

admin
  • Пользователь PRO
  • 5 272 сообщений
  • Репутация: 54

Отправлено 17 Февраль 2011 - 12:07

Это, наверное, по крону нужно делать :mellow:
А для чего записи в файл? Вы думаете, что это будет быстрее, чем парсить с xml другого сайта или нагрузка меньше будет?
  • 0

#3 Kismedia

Kismedia
    Topic Starter
  • Пользователь
  • 315 сообщений
  • Репутация: 0

Отправлено 17 Февраль 2011 - 12:23

Нет там без крона, время жизни кеш просто выставить на файл (я такое уже видел, но сам не разберусь) , то есть мне не нужно это действие производить автоматически каждые 12 часов.


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


  • 0

#4 ZiTosS

ZiTosS
  • Пользователь
  • 5 148 сообщений
  • Репутация: 8

Отправлено 17 Февраль 2011 - 16:46

Kismedia, не понимаю про какой кеш идет речь, всё равно данные придётся хранить в файле или в базе. Если сделать по крону, то мы будем каждые 12 часов записывать актуальные данные, если достучимся до сервера. Если без крона, то в голову приходит вариант чисто сравнивать время изменения файла и текущее время сервера, если привысило 12 часов, запускаем парсер... Но чем это лучше? Или может я чего-то не так понял?
  • 0

#5 Kismedia

Kismedia
    Topic Starter
  • Пользователь
  • 315 сообщений
  • Репутация: 0

Отправлено 17 Февраль 2011 - 19:53

Что бы не объяснять дальше на пальцах чего же я там хочу и что означает опять загадачная формулировка слова "Кеш". :)

Привожу в качестве примера ниже приведенный код:

<?
// считываем файл из кэша
$d=@file("/tmp/news.cache");
$fs=trim($d[1]);
// Если файл не обновлялся 3600 секунд (1 час) или файл пуст,
// то обновляем его
if (intval($d[0])<time()-600 || empty($fs)) {
$d=@file("http://news.novgorod.ru/ultramode.txt");
$fs=trim($d[1]);
// Сохраняем новую версю в кэше
if (!empty($fs)) {
$fw=fopen("/tmp/news.cache","wt");
flock($fw, LOCK_EX);
// В первую строку запишем текущее время
fputs($fw,time()."n");
// Сохраним остальные строки
for ($i=1;$i<count($d);$i++) fputs($fw,trim($d[$i])."n");
fclose($fw);
}
// Если, почему-то, файл не был скачан,
// то воспользуемся кэшированной версией
else $d=@file("/tmp/news.cache");
}

// Вывод данных
for ($i=0;$i<11;$i++) {
$msg=$d[2+$i*8];
$url=$d[3+$i*8];
$date=$d[4+$i*8];
print "<a href='http://news.novgorod.ru".trim($url)."'>";
print trim($msg)."</a> (".$date.")";
}


Алгоритм его работы следующий:

1. Считываем кэшированную версию
2. Если кэшированная версия устарела, то на ее место считываем файл http://news.novgorod.ru/ultramode.txt, заменяем первую строку на текущее время и сохраняем в кэш.
3. Оформляем и выводим данные пользователю.

Вот мне тоже самое только для файла http://www.pr-cy.ru/updates.xml :)

А если быть точным, то для приведенного мной скрипта парсера.

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

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

Я просто парюсь с массивами, как записать эти три переменные, скажем по строчно а потом так же считывать?


  • 0

#6 matroskin8

matroskin8
  • Пользователь PRO
  • 767 сообщений
  • Репутация: 143

Отправлено 17 Февраль 2011 - 22:14

Код откомментировал - так что алгоритм, думаю, понятен.
1) получаем время изменения файла;
2) получаем текущее время;
3) если разница больше 12 часов - вызываем ф-цию парсинга и перезаписываем файл
3.1) иначе - просто читаем файл.
<?php
$file = 'cache.txt'; // куда записываем
$stat = stat($file); // массив с информацией о файле

$stat = date("Y-m-d-G-i", $stat[9]); // дата изменения файла в формате: год-месяц-день-часы-минуты
$now = date("Y-m-d-G-i"); // текущая дата

$old = explode('-', $stat);
$new = explode('-', $now);

$time_old = mktime($old[3], $old[4], 0, $old[1], $old[2], $old[0]); // получаем метку времени даты изменения файла
$time_new = mktime($new[3], $new[4], 0, $new[1], $new[2], $new[0]); // получаем метку времени текущей даты

$dif = ($time_new - $time_old)/3600; // разница в часах

/*---------------
функция парсинга начало
----------------*/
function parser(){
if($xml_content = @file_get_contents("http://www.pr-cy.ru/updates.xml")){
$xml = new SimpleXMLElement($xml_content);

$cy = $xml->cy;
$pr = $xml->pr;
$yav = $xml->yav;
return $cy. '||' .$pr. '||' .$yav; // возвращаем данные в формате: 30.12.2010||21.01.2011||16.02.2011
}
}
/*---------------
функция парсинга конец
----------------*/

if($dif > 12){
// если разница между последним изменением файла и текущей датой больше 12 часов - парсим и записываем в файл результат
$res = parser();

$handle = fopen($file, 'w');
if (fwrite($handle, $res) === FALSE) {
echo "Не могу произвести запись!";
exit;
}
echo "Записано!";
fclose($handle);
}else{
// иначе - делаем то, что нужно, например, считываем строку из файла, разбиваем на ее на подстроки при помощи explode() и выводим элементы массива в нужном месте
echo 'Еще не прошло 12 часов. Прошло - ' .$dif. ' часов';
}
?>

  • 0


#7 Kismedia

Kismedia
    Topic Starter
  • Пользователь
  • 315 сообщений
  • Репутация: 0

Отправлено 17 Февраль 2011 - 22:36

Так, ошибок нет, а как читать из файла, нам же вначале нужно вывести эти переменные из нашего cache.txt
И если дата не актуальна то вводить парсер и записывать

Я так понимаю это вот здесь должно быть:

}else{
// иначе - делаем то, что нужно, например, считываем строку из файла, разбиваем на ее на подстроки при помощи explode() и выводим элементы массива в нужном месте
echo 'Еще не прошло 12 часов. Прошло - ' .$dif. ' часов';
}

  • 0

#8 Kismedia

Kismedia
    Topic Starter
  • Пользователь
  • 315 сообщений
  • Репутация: 0

Отправлено 17 Февраль 2011 - 22:42

Дэмо данные бы вставить не актуальные в cache.txt, что бы проверить запись в файл.
  • 0

#9 matroskin8

matroskin8
  • Пользователь PRO
  • 767 сообщений
  • Репутация: 143

Отправлено 17 Февраль 2011 - 23:00

Я так понимаю это вот здесь должно быть:

}else{
// иначе - делаем то, что нужно, например, считываем строку из файла, разбиваем на ее на подстроки при помощи explode() и выводим элементы массива в нужном месте
echo 'Еще не прошло 12 часов. Прошло - ' .$dif. ' часов';
}

Правильно понимаешь :mellow: Только, наверное, лучше убрать else - нам ведь в любом случае нужно выводить данные из файла, а вот записывать в него будем только по условию (если не обновлялся больше 12 часов). Код обновил ниже - без else.

Дэмо данные бы вставить не актуальные в cache.txt, что бы проверить запись в файл.

Эмм... если ты имеешь в виду вообще левые данные, то теряется смысл обновления файла каждые 12 часов... т.е., данные в файле будут актуальными за последние 12 часов. Можно в условии уменьшить время, чтобы посмотреть, что обновление файла происходит, например поставить if($dif > 0.1) (6 минут будет) или меньше.

а как читать из файла

Чтение из файла добавил.

, нам же вначале нужно вывести эти переменные из нашего cache.txt
И если дата не актуальна то вводить парсер и записывать

Наоборот... Сначала надо проверить как давно обновлялся файл, если больше 12 часов - то запустим парсер и обновим файл и только потом в любом случае выведем его содержимое.
<?php
$file = 'cache.txt'; // куда записываем
$stat = stat($file); // массив с информацией о файле

$stat = date("Y-m-d-G-i", $stat[9]); // дата изменения файла в формате: год-месяц-день-часы-минуты
$now = date("Y-m-d-G-i"); // текущая дата

$old = explode('-', $stat);
$new = explode('-', $now);

$time_old = mktime($old[3], $old[4], 0, $old[1], $old[2], $old[0]); // получаем метку времени даты изменения файла
$time_new = mktime($new[3], $new[4], 0, $new[1], $new[2], $new[0]); // получаем метку времени текущей даты

$dif = ($time_new - $time_old)/3600; // разница в часах

/*---------------
функция парсинга начало
----------------*/
function parser(){
if($xml_content = @file_get_contents("http://www.pr-cy.ru/updates.xml")){
$xml = new SimpleXMLElement($xml_content);

$cy = $xml->cy;
$pr = $xml->pr;
$yav = $xml->yav;
return $cy. '||' .$pr. '||' .$yav; // возвращаем данные в формате: 30.12.2010||21.01.2011||16.02.2011
}
}
/*---------------
функция парсинга конец
----------------*/

if($dif > 12){
// если разница между последним изменением файла и текущей датой больше 12 часов - парсим и записываем в файл результат
$res = parser();

$handle = fopen($file, 'w');
if (fwrite($handle, $res) === FALSE) {
echo "Не могу произвести запись!";
exit;
}
echo "Записано!";
fclose($handle);
}
// читаем файл и выводим его содержимое
$handle = fopen($file, 'r');
$content = fgets($handle);
$result = explode('||',$content);
echo 'Это первое значение: ' .$result[0]. '<br />Это второе значение: ' .$result[1]. '<br />Это третье значение: ' .$result[2];
?>

  • 0


#10 Kismedia

Kismedia
    Topic Starter
  • Пользователь
  • 315 сообщений
  • Репутация: 0

Отправлено 17 Февраль 2011 - 23:15

Ну все работает!!! :mellow:
Еще раз большое спасибо!
Я бы сам не разобрался. :)

Только у меня такой порядок получился:

.$result[1].
.$result[0].
.$result[2].

  • 0

robot

robot
  • Пользователь PRO
  • 2 652 сообщений
  • Репутация: 85


Оформление форума – IPBSkins.ru