Поможите сделать кеширование результата работы пхп-скрипта!

Тема в разделе "Как сделать...", создана пользователем Красавчег, 21 окт 2011.

  1. Красавчег

    Красавчег Завсегдатай

    Регистр.:
    15 мар 2010
    Сообщения:
    901
    Симпатии:
    297
    Нашел давеча неплохой скрипт информера курсов валюты.

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

    Чтобы потом этот файл kurs.html можно было выводить/подключать к другим страницам сайта.

    PHP:
    <?
    /************
    * getCourseDynamic()
    * Получение курса валют
    * $currency - массив с кодами валют
    * возвращает массив со значениями курсов заданных валют,
    * динамикой и разницой изменения курса по сравнению со вчерашним днем
    *    [course] => курс валюты
    *    [nominal] => номинал
    *    [spread] => разница курсов
    * коды валют можно найти здесь: http://www.cbr.ru/scripts/XML_val.asp?d=0
    * Например:
    * Доллар США - R01235
    * Евро - R01239
    * Фунт стерлингов - R01035
    *************/
    function getCourse($currency = array('R01235','R01239'),$shift 0){
        
    $value = array();
        
    $td mktime(0,0,0,date('m'),intval(date('d'))+$shift,date('Y'));
        
    $ystd mktime(0,0,0,date('m'),intval(date('d'))+$shift-1,date('Y'));
        foreach(
    $currency as $cur){
            
    $url 'http://www.cbr.ru/scripts/XML_dynamic.asp?date_req1='.date('d/m/Y',$ystd).'&date_req2='.date('d/m/Y',$td).'&VAL_NM_RQ='.$cur;
            
    $xml DOMDocument::loadXML(file_get_contents($url));
            if(!
    $xml) return null;
            
    $y =
            
    $t 0;
            
    $nominal 1;
            
    $xpc = new DOMXPath($xml);
            if(
    $xpc->evaluate('count(//Record)')<&& abs($shift)<10){
                return 
    getCourse($currency,$shift-1);
            }
            
    $res $xpc->query('/ValCurs/Record[@Date="'.date('d.m.Y',$ystd).'"]/Value/text()');
            if(
    $res->length$y floatval(str_replace(',','.',$res->item(0)->data));
            
    $res $xpc->query('/ValCurs/Record[@Date="'.date('d.m.Y',$td).'"]/Value/text()');
            if(
    $res->length$t floatval(str_replace(',','.',$res->item(0)->data));
            
    $res $xpc->query('/ValCurs/Record[@Date="'.date('d.m.Y',$td).'"]/Nominal/text()');
            if(
    $res->length$nominal floatval(str_replace(',','.',$res->item(0)->data));
            
    $value[$cur]['date'] = $td;
            
    $value[$cur]['course'] = $t;
            
    $value[$cur]['nominal'] = $nominal;
            
    $value[$cur]['spread'] = $t-$y;
        }
        return 
    $value;
    }
    ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Информер курса валют - pgood.ru</title>
    <style type="text/css">
    table{
    font:12px Arial, Helvetica, sans-serif;
    color:#333;
    }
    table td,th{
    padding:5px;
    text-align:left;
    }
    </style>
    </head>
    <body>
    <?
    $val = array(
        'R01235' => 'Доллар США',
        'R01239' => 'Евро'
    );
    $cur = getCourse(array_flip($val));
    ?>
    <table border="0" cellspacing="0" cellpadding="5">
        <tr>
            <td>&nbsp;</td>
            <th colspan="3">Курс валют на <?=date('d.m.Y',$cur['R01235']['date'])?></th>
        </tr>
    <?
    foreach($val as $i => $cur_name){
        $color = $cur[$i]['spread']>=0 ? '00CC00' : 'FF0000';        //красный, если понизился, зеленый, если повысился
        $spread = number_format($cur[$i]['spread']*100,0,',','');    //разницу в курсах переводим в копейки
        $course = number_format($cur[$i]['course'],4,',',' ');        //текущий курс
    ?>
        <tr>
            <td style="background:#<?=$color?>;">&nbsp;</td>
            <th><?=$cur_name?></th>
            <td style="color:#999;"><?=$cur[$i]['spread']>='+' ''?><?=$spread?> коп.</td>
            <td><strong><?=$course?></strong> руб.</td>
        </tr>
    <?
    }
    ?>
    </table>
    </body>
    </html>
     
  2. zzallexx

    zzallexx

    Регистр.:
    11 июн 2008
    Сообщения:
    1.035
    Симпатии:
    703
    создаешь папку cache в корне сайта с правами 777
    PHP:
    <?php 
    function getCourse($currency = array('R01235','R01239'),$shift 0){ 
        
    $value = array(); 
        
    $td mktime(0,0,0,date('m'),intval(date('d'))+$shift,date('Y')); 
        
    $ystd mktime(0,0,0,date('m'),intval(date('d'))+$shift-1,date('Y')); 
        foreach(
    $currency as $cur){ 
            
    $url 'http://www.cbr.ru/scripts/XML_dynamic.asp?date_req1='.date('d/m/Y',$ystd).'&date_req2='.date('d/m/Y',$td).'&VAL_NM_RQ='.$cur
            
    $xml DOMDocument::loadXML(file_get_contents($url)); 
            if(!
    $xml) return null
            
    $y 
            
    $t 0
            
    $nominal 1
            
    $xpc = new DOMXPath($xml); 
            if(
    $xpc->evaluate('count(//Record)')<&& abs($shift)<10){ 
                return 
    getCourse($currency,$shift-1); 
            } 
            
    $res $xpc->query('/ValCurs/Record[@Date="'.date('d.m.Y',$ystd).'"]/Value/text()'); 
            if(
    $res->length$y floatval(str_replace(',','.',$res->item(0)->data)); 
            
    $res $xpc->query('/ValCurs/Record[@Date="'.date('d.m.Y',$td).'"]/Value/text()'); 
            if(
    $res->length$t floatval(str_replace(',','.',$res->item(0)->data)); 
            
    $res $xpc->query('/ValCurs/Record[@Date="'.date('d.m.Y',$td).'"]/Nominal/text()'); 
            if(
    $res->length$nominal floatval(str_replace(',','.',$res->item(0)->data)); 
            
    $value[$cur]['date'] = $td
            
    $value[$cur]['course'] = $t
            
    $value[$cur]['nominal'] = $nominal
            
    $value[$cur]['spread'] = $t-$y
        } 
        return 
    $value


    $cache_file=$_SERVER['DOCUMENT_ROOT']."/cache/kurs.txt"//права на папку cache 777

    if (file_exists$cache_file ) && 
        
    date('Y-m-d',filemtime($cache_file))==
        
    date("Y-m-d"mktime(000date("m") , date("d"), date("Y")))){
        
    $f=fopen($cache_file,"rb");  
       
    $kurs=fread($f,filesize($cache_file)); 
       
    fclose($f);
    }else{
    $style ='<style type="text/css"> 
    table{ 
    font:12px Arial, Helvetica, sans-serif; 
    color:#333; 

    table td,th{ 
    padding:5px; 
    text-align:left; 

    </style>'


    $val = array( 
        
    'R01235' => 'Доллар США'
        
    'R01239' => 'Евро' 
    ); 
    $cur getCourse(array_flip($val)); 

    $tab1='<table border="0" cellspacing="0" cellpadding="5"> 
        <tr> 
            <td>&nbsp;</td> 
            <th colspan="3">Курс валют на '
    .date('d.m.Y',$cur['R01235']['date']).'</th> 
        </tr>'
    ;
     
    foreach(
    $val as $i => $cur_name){ 
        
    $color $cur[$i]['spread']>='00CC00' 'FF0000';        //красный, если понизился, зеленый, если повысился 
        
    $spread number_format($cur[$i]['spread']*100,0,',','');    //разницу в курсах переводим в копейки 
        
    $course number_format($cur[$i]['course'],4,',',' ');        //текущий курс 
        
    if($cur[$i]['spread']>=)$plus "+"; else $plus "";
        
    $tab2 $tab2.'<tr> 
            <td style="background:#'
    .$color.'">&nbsp;</td> 
            <th>'
    .$cur_name.'</th> 
            <td style="color:#999;">'
    .$plus.$spread.' коп.</td> 
            <td><strong>'
    .$course.'</strong> руб.</td> 
        </tr>'




    $tab3 '</table>';
    $kurs $style.$tab1.$tab2.$tab3;

       @
    file_put_contents($cache_file,$kurs);

    }
    echo 
    $kurs;
     
    Красавчег нравится это.
  3. Красавчег

    Красавчег Завсегдатай

    Регистр.:
    15 мар 2010
    Сообщения:
    901
    Симпатии:
    297
    zzallexx, спасибо за помощь, вот только каждый раз при запуске скрипта он не обновляет/перезаписывает данные в кеш-файле, а тупо выводит старые данные взятые из кеша /cache/kurs.txt
     
  4. zzallexx

    zzallexx

    Регистр.:
    11 июн 2008
    Сообщения:
    1.035
    Симпатии:
    703
    обновления кеша в данном случае раз в сутки а зачем тогда нужен кеш если он будет обнавляться при каждом запросе?
     
  5. Красавчег

    Красавчег Завсегдатай

    Регистр.:
    15 мар 2010
    Сообщения:
    901
    Симпатии:
    297
    Да нет, я понимаю, что он не должен каждый раз обновляться. Просто я сейчас вывод kurs.txt на страницах настраиваю/оформляю, а данные старые (вчерашние) выводятся. Я запустил файл со скриптом, а он на новые данные не обновился. И как он вообще теперь обновляется, сам что ли будет запускаться? Я предполагал что его нужно будет кроном дергать..
     
  6. zzallexx

    zzallexx

    Регистр.:
    11 июн 2008
    Сообщения:
    1.035
    Симпатии:
    703
    вот кусок кода
    PHP:
    if (file_exists$cache_file ) &&  //проверяем есть ли кеш файл
        
    date('Y-m-d',filemtime($cache_file))== //дата изменения файла в формате 2011-10-21
        
    date("Y-m-d"mktime(000date("m") , date("d"), date("Y")))){  // настоящая дата в формате 2011-10-21
        
    $f=fopen($cache_file,"rb");   
       
    $kurs=fread($f,filesize($cache_file)); //получаем данные их кеш файла  
       
    fclose($f); 
    }else{
    //здесь работет парсер
    $kurs $style.$tab1.$tab2.$tab3//данные из парсера
    @file_put_contents($cache_file,$kurs); //запихиваем все в кеш файл
    }
    echo 
    $kurs;//выводим данные
    который проверяет разницу между датой создания файла и настоящей датой если они одинаковые то данные берутся из файла если разные работает парсер и обновляет файл кеша
     
  7. Красавчег

    Красавчег Завсегдатай

    Регистр.:
    15 мар 2010
    Сообщения:
    901
    Симпатии:
    297
    zzallexx, ну, может у меня и лыжи не едут, хз. Но сколько бы я скрипт не запускал, ничего не обновляется. Скрипт упорно показывает мне курсы за 22 число.

    Можно сделать, чтобы при запуске скрипта он просто перезаписывал в файле /cache/kurs.txt все данные на новые?
     
  8. zzallexx

    zzallexx

    Регистр.:
    11 июн 2008
    Сообщения:
    1.035
    Симпатии:
    703
    ну какбы выходные у Центробанка тоже бывают иногда, обновится сегодня ночью :) http://www.cbr.ru/scripts/XML_dynamic.asp?date_req1=22/10/2011&date_req2=24/10/2011&VAL_NM_RQ=R01235 результат
    тоесть тоже самое что на настоящий момент выводит скрипт если не обновится перепишу по запуску :) дело в том что скрипт берет текущую дату а банк дает новый курс по окончании торгов в России и уже по новой дате поэтому тут два пути либо после определенного времени(окончания торгов) запускать скрипт по крону и дату ставить на день вперед либо ждать полночи, кстати не знаешь в какое время по Москве устанавливется новый курс
     
  9. Красавчег

    Красавчег Завсегдатай

    Регистр.:
    15 мар 2010
    Сообщения:
    901
    Симпатии:
    297
    Фиг его знает, посмотрел на cbr.ru - ничего про это не нашел.

    Да, лучше бы конечо так.

    Запускается крон например в час ночи -> скрипт читывает курсы на данный момент -> записывает новые данные в файл -> и всё, через сутки делаем тоже самое.
     
  10. zzallexx

    zzallexx

    Регистр.:
    11 июн 2008
    Сообщения:
    1.035
    Симпатии:
    703
    для этого крон не нужен если ночью обновлять незнаю в чем там причина парсер тот кривой или что-то поменялось cbr.ru вообщем держи такой вариант
    PHP:
    <?php 
    $cache_file
    =$_SERVER['DOCUMENT_ROOT']."/cache/kurs.txt"//права на папку cache 777
    if (file_exists$cache_file ) && 
        
    date('Y-m-d',filemtime($cache_file))==
        
    date("Y-m-d"mktime(000date("m") , date("d"), date("Y")))){
        
    $f=fopen($cache_file,"rb");  
       
    $kurs=fread($f,filesize($cache_file)); 
       
    fclose($f);}
    else{
        
    $url 'http://www.cbr.ru';
        
    $content file_get_contents($url);
        
    $content iconv('utf-8','windows-1251',$content);
        
    preg_match('/icon_dollar\.gif\".*?nowrap>(.*?)&nbsp;<img alt=\'(.*?)\'.*?nowrap>(.*?)&nbsp;<img alt=\'(.*?)\'/si',$content,$match);
        
    $dollar =  $match[1];
        
    $spread explode(' ',$match[2]);
        
    $d_spread number_format($spread[1]*100,0,',',''); 
        
    $euro =  $match[3];
        
    $spread explode(' ',$match[4]);
        
    $e_spread number_format($spread[1]*100,0,',','');
     
         
    $style ='<style type="text/css"> 
                table{ font:12px Arial, Helvetica, sans-serif; color:#333; } 
                table td,th{ padding:5px; text-align:left; } 
                </style>'


        
    $tab1='<table border="0" cellspacing="0" cellpadding="5"> 
                    <tr> 
                    <td>&nbsp;</td> 
                        <th colspan="3">Курс валют на '
    .date('d.m.Y').'</th> 
                    </tr>'
    ;
        
    $color $d_spread >='00CC00' 'FF0000';        //красный, если понизился, зеленый, если повысился 
        
    if($d_spread >=)$plus "+"; else $plus "";
        
    $tab2 '<tr> 
            <td style="background:#'
    .$color.'">&nbsp;</td> 
            <th>Доллар США</th> 
            <td style="color:#999;">'
    .$plus.$d_spread.' коп.</td> 
            <td><strong>'
    .$dollar.'</strong> руб.</td> 
        </tr>'

         
    $color $e_spread >='00CC00' 'FF0000';        //красный, если понизился, зеленый, если повысился 
        
    if($d_spread >=)$plus "+"; else $plus "";
        
    $tab3 '<tr> 
            <td style="background:#'
    .$color.'">&nbsp;</td> 
            <th>Евро</th> 
            <td style="color:#999;">'
    .$plus.$e_spread.' коп.</td> 
            <td><strong>'
    .$euro.'</strong> руб.</td> 
        </tr></table>'

        
    $kurs $style.$tab1.$tab2.$tab3;
        @
    file_put_contents($cache_file,$kurs);
    }
    echo 
    $kurs;