as "cachear" css concatenated via GET

Asked

Viewed 86 times

0

I’m making a concatenation of css files where the names of the files are passed by parameters in the url to the css.php file, my question is if it is somehow possible to "cached" the requested files as in the example below:

HOME

if(is_home()) {
<link rel="stylesheet" href="css.php?files=common,home">
}

SERVICES

if(is_page('servicos')) {
<link rel="stylesheet" href="css.php?files=common,servicos">
}

css.php code

<?php

if (empty($_GET['files']))
    die();

$files = explode(",", $_GET['files']);
$directoryOfCss = 'C:\xampp\htdocs\frederico\css\\';
$cssContent = "";

foreach($files as $oneFile) {
  if (file_exists($directoryOfCss . $oneFile . ".css")) {
      $cssContent .= file_get_contents($directoryOfCss . $oneFile . ".css");
  }
}
header("Content-Type: text/css;X-Content-Type-Options: nosniff;");
echo $cssContent;

2 answers

0


You can store the result of the concatenation in a new CSS file and access it during a certain period until the cache expires.

<?php

if (empty($_GET['files']))
    die();

// Configurações
$cacheExpirationInSeconds = 60;
$directoryOfCss = 'C:\xampp\htdocs\frederico\css\\';
$cacheFile = $directoryOfCss.'cache-'.str_replace(',', '-', $_GET['files']).'.css';

// Verifica se o arquivo cache existe e se ainda é válido
if (file_exists($cacheFile) && (filemtime($cacheFile) > time() - $cacheExpirationInSeconds)) {

    // Lê o arquivo cacheado
    $cssContent = file_get_contents($cacheFile);
} else {

    // Concatena os arquivos
    $cssContent = '';
    $files = explode(',', $_GET['files']);
    foreach ($files as $oneFile) {
        if (file_exists($directoryOfCss.$oneFile.'.css')) {
            $cssContent .= file_get_contents($directoryOfCss.$oneFile.'.css');
        }
    }

    // Cria o cache
    $cssContent .= '/*Gerado em '.date('d/m/Y H:i:s').'*/';
    file_put_contents($cacheFile, $cssContent);
}

header('Content-Type: text/css;X-Content-Type-Options: nosniff;');
echo $cssContent;

One advantage of this approach is that you can delete the cached file via programming or manually and avoid problems with outdated caching in your clients' browser.

Another solution for your case is to cache in memory the result of concatenation through some PHP module. On the site "PHP: The Right Way" there is a more detailed explanation. Below is an example of how you would look using Memcache.

<?php

if (empty($_GET['files']))
    die();

$directoryOfCss = 'C:\xampp\htdocs\frederico\css\\';

// Conecta ao Memcache
$memcache = new Memcache;
$memcache->connect('127.0.0.1', 11211);

// Monta um identificador para o cache
$key = str_replace(',', '-', $_GET['files']);

// Busca o cache
$cssContent = $memcache->get($key);

// Se não existir o cache, é retornardo o dado original e esse dado é armazenado em cache para as próximas solicitações
if (!$cssContent) {

    // Concatena os arquivos
    $cssContent = '';
    $files = explode(',', $_GET['files']);
    foreach ($files as $oneFile) {
        if (file_exists($directoryOfCss.$oneFile.'.css')) {
            $cssContent .= file_get_contents($directoryOfCss.$oneFile.'.css');
        }
    }

    // Armazena em cache
    $expireInSeconds = 300;
    $memcache->set($key, $cssContent, false, $expireInSeconds);
}

// Exibe o resultado
echo $cssContent;

// E caso você queira excluir dinamicamente o cache basta executar
$memcache->delete($key);

In Xampp, at least the version I use, does not contain Memcache by default, you would have to install it for this code to work.

  • 1
  • For his case the best answer is to point out the two main caching alternatives for him to verify which one is possible to follow. It is no use to post a code using Memcache and its server does not have it enabled.

  • can give a practical example of how to cache in memory?

  • I updated my reply with an example of code using Memcache.

0

If you are talking about HTTP, use is simple:

$expira = 3600; //Expira em uma hora por exemplo

header("Content-Type: text/css;X-Content-Type-Options: nosniff;");
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $expira) . ' GMT');
header('Cache-Control: public, max-age=' . $expira);
header('Pragma: max-age=' . $expira);

echo $cssContent;

Now if you’re talking about server-side usage consumption I would say that the interesting thing would be to save the data of this in a separate document for example:

<?php

if (empty($_GET['files']))
    die();

$expirar = 3600; //uma hora, pode ajustar
$cacheName = $_GET['files'];
$cachePath = 'C:/xampp/htdocs/frederico/' . $cacheName . '.tmp';

$files = explode(",", $cacheName);
$directoryOfCss = 'C:/xampp/htdocs/frederico/css/';

function http_cache($expires)
{
    header("Content-Type: text/css;X-Content-Type-Options: nosniff;");

    header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $expires) . ' GMT');
    header('Cache-Control: public, max-age=' . $expires);
    header('Pragma: max-age=' . $expires);
}

if (is_file($cachePath)) {
     $lastMod = filemtime($cachePath);

     /*
       Se o tempo da ultima modificação m ais o tempo
       de expirar for maior que o tempo atual então usa
       o arquivo "temporário", caso contrário continua com o script
     */
     if ($lastMod + $expirar > time()) {
         http_cache($expirar);
         die();
     }
}

$cssContent = "";

foreach($files as $oneFile) {
  if (is_file($directoryOfCss . $oneFile . ".css")) {
      $cssContent .= file_get_contents($directoryOfCss . $oneFile . ".css");
  } else {
      header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found', true, 404);
      die('Arquivo invalido');
  }
}

http_cache($expirar);

echo $cssContent;

file_put_contents($cachePath, $cssContent); //Salva no "temporario"

Browser other questions tagged

You are not signed in. Login or sign up in order to post.