Skip to content

Instantly share code, notes, and snippets.

@richthegeek
Last active December 17, 2018 10:52
Show Gist options
  • Save richthegeek/5865960 to your computer and use it in GitHub Desktop.
Save richthegeek/5865960 to your computer and use it in GitHub Desktop.
A simple caching wrapper for PHPSass - does not take into account changes in files referrred to from @include. Assumes that the PHPSass library is located in a directory at ./phpsass Assumes it can write to a directory called ./phpsass_cache, or create it.
<?php
function compileSass($filename, $cached = true) {
$cache_dir = './phpsass_cache';
# if cached, ensure we can write to the cache directory
if ($cached) {
if (!file_exists($cache_dir) && !mkdir($cache_dir)) {
throw 'SASS cache directory does not exist and cannot be created';
}
if (!is_writable($cache_dir)) {
throw 'SASS cache directory is not writable';
}
}
# have to check + throw here for the hashing
if (!file_exists($filename)) {
throw 'Filename requested for compilation did not exist';
}
# create a unique filename based on the contents of the included file
$contents = file_get_contents($filename);
$hash = md5($contents);
$cache_filename = $cache_dir . '/' . $hash . '_' . basename($filename);
# if we have a cache hit, return it now.
if ($cached && file_exists($cache_filename)) {
return file_get_contents($cache_filename);
}
# no cache hit, so compile as usual
require_once './phpsass/SassParser.php';
$syntax = substr($file, -4, 4);
$options = array(
'style' => 'expanded',
'cache' => false, # yes, this is ironic
'syntax' => $syntax,
'debug' => false
);
$parser = new SassParser($options);
$contents = $parser->toCss($filename);
# save to cache
if ($cached) {
file_put_contents($cache_filename, $contents);
}
return $contents;
}
<?php
function compileSass($filename, $cached = true) {
$cache_dir = './phpsass_cache';
# if cached, ensure we can write to the cache directory
if ($cached) {
if (!file_exists($cache_dir) && !mkdir($cache_dir)) {
throw 'SASS cache directory does not exist and cannot be created';
}
if (!is_writable($cache_dir)) {
throw 'SASS cache directory is not writable';
}
}
# have to check + throw here for the hashing
if (!file_exists($filename)) {
throw 'Filename requested for compilation did not exist';
}
# create a unique filename based on the contents of the included file
$contents = file_get_contents($filename);
$cache_filename = $cache_dir . '/' . basename($filename);
# if we have a cache hit, return it now.
if ($cached && file_exists($cache_filename)) {
$source = filemtime($filename);
$target = filemtime($cache_filename);
if ($target >= $source) {
return file_get_contents($cache_filename);
}
}
# no cache hit, so compile as usual
require_once './phpsass/SassParser.php';
$syntax = substr($file, -4, 4);
$options = array(
'style' => 'expanded',
'cache' => false, # yes, this is ironic
'syntax' => $syntax,
'debug' => false
);
$parser = new SassParser($options);
$contents = $parser->toCss($filename);
# save to cache
if ($cached) {
file_put_contents($cache_filename, $contents);
}
return $contents;
}
@richthegeek
Copy link
Author

The line 24 is because i've been writing nothing but javascript for the last year, thanks for fixing it.

With regards to the duplicate files: in order to know when a cached file changes we can either use the hash or the file mod time. Really, either work fine. Using the mtime would allow the cached filename to be the same in all cases, and so there would not be any duplicate files. One possible issue is that you have two files with the same name which are compiled. With the mtime method, the cached file gets overwritten due to a name collision.

So the two choices for solving the first issue are:

  1. use the mtime method, but accept that name collisions will be problematic.
  2. use the hash method, but either accept the duplicate files or add a "delete all files ending in _$filename" loop before the file_put_contents.

@richthegeek
Copy link
Author

I've added a second file which uses mtime instead of hashing for recompiling on save and cache naming.

Copy link

ghost commented Jul 3, 2013

Hi Rich,

sorry for waiting, i have a lot of trouble last week.
This week doesn't look better, but i taked some minutes to test your code.
Now the cache-method works, and i do a small change in https://gist.github.com/aspross/5870297.
I renamed the cache files in ".css" instead of ".sass".

I hope to find time this week to look for a solution on the include problem.
I want to generate a css file for every imported sass-file.

If you have an idea to solve it, i will be very happy.

Copy link

ghost commented Jul 5, 2013

Hi Rick,

i added a few changes on the code.
See on https://gist.github.com/aspross/5937524.

Now, i'm able to compile imports.
But my problem now, is when i do changes on an import like layout.sass,
example : @import url("/tmp/sass/layout.sass"). ( content from style.sass)

I didn't update my layout.css.

Only if my main css file called style.sass have any changes, i compiled my imports.

I make a comment on the place i think we have to check the import changes :
// Check the imports in $filename
// if changes on importfiles, replace the import files

Maybe you have any ideas to solve it.

Copy link

ghost commented Jul 6, 2013

Hi Rich,

good news, i found a solution.
You can found it on https://gist.github.com/aspross/5941082.

Now it will recompile the sass files, if i make any changes on an import sass file.

I know i can probably improve the code, but for now i think it's ok.
Me and my cousin have to test this script to find eventually errors.

Maybe you can test it too and give some feedback ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment