Autor Zpráva
Kcko
Profil
Snažím se zmergovat více CSS souborů do 1 (krom toho také zmenšit datovou velikost).
Skript funguje asi takto -> projde css soubory, spojí do 1, oseká o nepotřebné věci, porovná jejich poslední modifikaci, vygeneruje případně přegeneruje už vzniklý soubor (MD5 hash) a vrátí název výsledného MD5 hashe. Ten se umístí do HTML šablony.

Má to pro mě jeden problém, vcelku zásádní ;-).

Při prvním obnovení stránky vrátí browser (FF i Chrome) 200 OK. Při druhém by měl již vracet 304, ale opět vrátí 200 OK. Teprve při třetím vrátí 304. Nemůžu se dopátrat toho proč mi 2x vrátí 200.

Co mne napadá, že pokud přegeneruji soubor, tak se to tam někde interně v keši drží a pošle 200 znovu, protože je to jiné když do css souboru sáhnu já a změním ho než když to udělá za mě PHPko, ale nejsem si jist.

Neveděl by někdo?

HTML kód
<? 
      
    
    include 'cache-css-2.php';
    $cssCache = new csscache;
    $cssFile = $cssCache->run();
    
?>

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Test keše</title>
<link rel="stylesheet" type="text/css" href="<?= $cssFile ?>">
</head>
<body>
  <a href="?<?= uniqid() ?>">click me</a>

</body>
</html>


<?php

class csscache
{


    function minify( $css ) {
        $css = preg_replace( '#\s+#', ' ', $css );
        $css = preg_replace( '#/\*.*?\*/#s', '', $css );
        $css = str_replace( '; ', ';', $css );
        $css = str_replace( ': ', ':', $css );
        $css = str_replace( ' {', '{', $css );
        $css = str_replace( '{ ', '{', $css );
        $css = str_replace( ', ', ',', $css );
        $css = str_replace( '} ', '}', $css );
        $css = str_replace( ';}', '}', $css );

        return trim( $css );
    }
     

    function compress_css($buffer)
    {
       $buffer = $this->minify($buffer);
       
     return $buffer;
    }


    function buildCache(array $cssFiles)
    {
        $cssString = "";
        foreach($cssFiles as $cssFile)
        {
            $cssString .= file_get_contents($cssFile);
        }
        $cssString = $this->compress_css($cssString);
        return $cssString;
    }


    function writeCache($cacheFilename, $cssCompressed)
    {
        $f = fopen($cacheFilename, "w");
       
        flock($f, LOCK_EX);
        fwrite($f,$cssCompressed);
        fclose($f);

    }


    function checkCacheIsOk($cacheFilename, array $cssFiles)
    {
        if(file_exists($cacheFilename))
        {
            $lastCssModificatedAt = 0;
            foreach($cssFiles as $cssFile)
            {
                $cssModificatedAt = filemtime($cssFile);
              
                if($cssModificatedAt > $lastCssModificatedAt)
                {
                    $lastCssModificatedAt = $cssModificatedAt;
                }
            }

            if(filemtime($cacheFilename) >= $lastCssModificatedAt)
            {
                return true;
            }
        }
        return false;
    }


    
    function run()
    {    
        
        $cssFiles = array_filter(scandir('css/'), function ($file)
        {
            return strlen($file) > 3;
        });

        foreach ($cssFiles as &$file)
        {
            $file = 'css/'.$file;
        }

        $cacheFilename = 'css-cache/' . md5(implode("",$cssFiles)).".css";
        
        $cssCompressed = "";

        
        if(!$this->checkCacheIsOk($cacheFilename, $cssFiles))
        {
            $cssCompressed = $this->buildCache($cssFiles);
            $this->writeCache($cacheFilename, $cssCompressed);
        }

        return $cacheFilename;
    }
}
Davex
Profil
Všiml jsem si, že u příliš čerstvých souborů posílá Apache weak ETag a u druhého načtení proto neprojde kontrola HTTP hlavičky If-None-Match a soubor se odešle celý se stavem 200.

Když jsem čerstvě vytvořený stylopis udělal o sekundu starší, tak už Apache odeslal běžný ETag a stav 304 byl už při druhé obnově.
Kcko
Profil
Davex:
Poprosím o ukázku modifikace kódu.
Davex
Profil
function writeCache($cacheFilename, $cssCompressed)
    {
        $f = fopen($cacheFilename, "w");

        flock($f, LOCK_EX);
        fwrite($f,$cssCompressed);
        fclose($f);

    touch($cacheFilename, time()-1); /* možná bude lepší, když bude starší o víc sekund */
    }
Kcko
Profil
Davex:
To mě nenapadlo, zkoušel jsem clearstatscache apod. Vyzkouším a otestuji. Díky moc!

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: