Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Кэширование
 
 автор: iskanderro   (08.11.2015 в 16:30)   письмо автору
 
 

Доброго времени суток форумчане!
Вот уже несколько дней бьюсь как рыба об лед, не могу сделать нормальное кэширование. Облазил кучу сайтов, испробовал несколько скриптов, но пока не получается добиться нужного результата.
Итак, суть проблемы.

Есть скрипт библиотека контента – “simple_html_dom” ее помощью парсится сайт, результат записывается в переменную $out и отдается браузеру. На этом этапе вроде заморочек нет. Но так как хочется быстроты и парсинга нескольких тем, то решено было использовать кэширование, вместо прямого, постоянного обращения от каждой загрузки страницы. Тем более что обращение идет к гуглу и парсится тем (кейвордов) несколько за один заход.
Для кэширования перепробовал несколько скриптов, с примерно одним функционалом и нормально работать стал только один из них.


<?php
   error_reporting
(E_ALL|E_STRICT);
    
// мониторим скорость выполнения
    
$start microtime(true);
    
// задаем время жизни кэша в секундах
    
$cacheTime 600;
    
// Название скрипта
    
$fileName strrchr($_SERVER["SCRIPT_NAME"], "/");
    
// удаляем все слеши
    
$fileName trim($fileName'/\\');
    
// путь для хранения кеша
    
$cacheFile "cashe/$fileName.cache";
    
// если кэш существует
    
if (file_exists($cacheFile)) {
        
// проверяем актуальность кеша
        
if ((time() - $cacheTime) < filemtime($cacheFile)) {
            
// показываем данные из кеша
            
echo file_get_contents($cacheFile);
            
// мониторим скорость работы
            
echo 'Время выполнения скрипта: '.(microtime(true) - $start).' сек.';
            exit; 
// Завершаем скрипт
        
}
    }
    
// открываем буфер
    
ob_start();
?>
<!DOCTYPE html>
<html>
<head>
    <title>Test cache</title>
    <meta http-equiv="content-type"content="text/html; charset=utf-8" />
</head>
<body>
<?php
// Выводимое в браузер
echo "Однажды в студеную зимнюю пору он из лесу вышел и тут началось! Кого только не было здесь на опушке – гориллы, безьяны, удавы и лось";
?>
</body>
</html>
<?php
    
// Открываем файл для записи
    
$file fopen($cacheFile'w');
    
// сохраняем все что есть в буфере вфайл кеша
    
fwrite($fileob_get_contents());
    
// закрываем файл
    
fclose($file);
    
// выводим страницу
    
ob_end_flush();
    
// мониторим скорость работы
    
echo 'Время выполнения скрипта: '.(microtime(true) - $start).' сек.';
?>


В приведенном виде все работает отлично кэш сохраняется в виде файла и радоваться бы жизни но…
Как только я вставляю вместо –

// Выводимое в браузер
echo "Однажды в студеную зимнюю пору он из лесу вышел и тут началось! Кого только не было здесь на опушке – гориллы, безьяны, удавы и лось";

Код парсера все останавливается и нет сохраненных файлов, да и вообще скрипт быстро останавливает работу и перед глазами девственно белый лист!
Отсюда вопрос, может ли динамически формирующаяся страница из-за вызова нескольких классов прерывать процесс кэширования?
Пробовал вот этот код, отдельно он работает:

$url = "Какой-то сайт";
include 'simple_html_dom.php';
function request($url,$post = 0){
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url ); // отправляем на 
    curl_setopt($ch, CURLOPT_HEADER, 0); // пустые заголовки
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // возвратить то что вернул сервер
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // следовать за редиректами
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);// таймаут4
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_COOKIEJAR, dirname(__FILE__).'/cookie.txt'); // сохранять куки в файл 
    curl_setopt($ch, CURLOPT_COOKIEFILE,  dirname(__FILE__).'/cookie.txt');
    curl_setopt($ch, CURLOPT_POST, $post!==0 ); // использовать данные в post
    if($post)
        curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
    $data = curl_exec($ch);
    curl_close($ch);
    return $data;
}

class parser{
    var $cacheurl = array();
    var $result = array();
    var $_allcount = 10;
    function __construct(){
        if(isset($_POST['url'])){
            $this->parse($_POST['url']);
        }
    }
    function parse($url){
        $url = $this->readUrl($url);
        
        if( !$url or $this->cacheurl[$url] or $this->cacheurl[preg_replace('#/$#','',$url)] )
            return false;
            
        $this->_allcount--;
        
        if( $this->_allcount<=0 )
            return false;
            
        $this->cacheurl[$url] = true;
        $item = array();    
        
        $data = str_get_html(request($url));
        $item['url'] = $url;
        $item['title'] = count($data->find('title'))?$data->find('title',0)->plaintext:'';
        $item['text'] = $data->plaintext;
        $this->result[] = $item;
        
        if(count($data->find('a'))){
            foreach($data->find('a') as $a){
                $this->parse($a->href);
            }
        }
        $data->clear();
        unset($data);
        
    }
     function printresult(){
#     print_r($item);
        foreach($this->result as $item){
            echo '<h2>'.$item['title'].' - <small>'.$item['url'].'</small></h2>';
            echo '<p style="margin:20px 0px;background:#eee; padding:20px;">'.$item['text'].'</p>';
        };
        exit();
    }
    var $protocol = '';
    var $host = '';
    var $path = '';
    function readUrl($url){
        $urldata = parse_url($url);
        if( isset($urldata['host']) ){
            if($this->host and $this->host!=$urldata['host'])
                return false;
                
            $this->protocol = $urldata['scheme'];
            $this->host = $urldata['host'];
            $this->path = $urldata['path'];
            return $url;
        }
            
        if( preg_match('#^/#',$url) ){
            $this->path = $urldata['path'];
            return $this->protocol.'://'.$this->host.$url;
        }else{
            if(preg_match('#/$#',$this->path))
                return $this->protocol.'://'.$this->host.$this->path.$url;
            else{
                if( strrpos($this->path,'/')!==false ){
                    return $this->protocol.'://'.$this->host.substr($this->path,0,strrpos($this->path,'/')+1).$url;
                }else 
                    return $this->protocol.'://'.$this->host.'/'.$url;
            }
        }
    }
}
$pr = new Parser();
$pr->printresult();


Может подскажете в каком направлении копать, или может у кого то есть более простые решения для парсинга и последующего кэширования.

  Ответить  
 
 автор: cheops   (08.11.2015 в 22:05)   письмо автору
 
   для: iskanderro   (08.11.2015 в 16:30)
 

Зря кэшируете в файлы. Даже если сбой происходит пока локально, в реальности на сервере начнется кошмар. Несколько обращений к странице будут открывать файл и бить его. Так как вы его не блокируете (с блокировкой впрочем тоже ошибиться не долго).
Кэшируйте в базу данных, у неё очередь, она не позволит вам повредить данные. А лучше, если оперативная память позволяет сразу в какое-нибудь NoSQL-решение вроде memcache или redis.

  Ответить  
 
 автор: cheops   (08.11.2015 в 22:10)   письмо автору
 
   для: iskanderro   (08.11.2015 в 16:30)
 

Локально ваш скрипт работает нормально, если сбоит уже на сервере - 95% - это одновременное обращение к скрипту, в результате чего файл и бьется. Не работайте с файлами. Даже если будете блокировать их при помощи flock(), подумайте о базе данных - сильно себе сэкономите сил и времени.

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования