0

I dynamically generate svgz images with php, for example:

<?php
    header("Content-Encoding: gzip");
    header("Content-Type: image/svg+xml");
    $wth=1280;$hth=180;
    $hd="<svg width='".$wth."' height='".$hth."' viewBox='0 0 ".$wth." ".$hth."' xmlns='http://www.w3.org/2000/svg' version='1.1'>";
    $hd.="<rect x='0' y='0' width='".$wth."' height='".$hth."' fill='green'/>";
    $rad=25;$ncr=20;$rcv=['yellow','gray','red'];
    for($c=0;$c<$ncr;$c++){$hd.="<circle cx='".mt_rand($rad,$wth-$rad)."' cy='".mt_rand($rad,$hth-$rad)."' r='".$rad."' fill='".$rcv[mt_rand(0,count($rcv)-1)]."'/>";}
    $hd.="</svg>";
    echo gzencode($hd,9);
?>

In my htaccess file I add:

ExpiresActive on
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/svg+xml "access plus 60 seconds"
ExpiresDefault "access plus 0 seconds"

but it does NOT work as expected, and the php-svg image file shows always a 200 OK status I tried also simply:

ExpiresActive on
ExpiresByType image/png "access plus 1 month"
ExpiresDefault "access plus 60 seconds"

(this doesn't suit my needs as I wish 0 seconds for all other html/xml files) but also this way the php-svg image is not cached and comes out with 200 OK

Note that also the other php files, served as html are not cached (???)

In both cases the png files are cached as expected and deliver a 304 status

I tried also to add a

ini.set('session.cache_limiter','public')
ini.set('session.cache_expire',60)

directly in the php-svg file with no result

Note that in my php.ini file the settings are

session.cache_limiter = nocache
session.cache_expire = 180

What's going wrong ? Is there a issue related to some php.ini configuration ? Does htaccess overrides php.ini or not ? Is there a solution not requiring any modification to php ini ?

Any help very welcome !

Giovanni (my website: http://isbooth.com )

2 Answers2

0

I do not believe Apache will "guess" the content type of whatever PHP script will produce. So you've got several options:

  1. add expiry setting to your PHP code, just like you've already added other headers. Skip setting of the same headers in apache unless you craft some special logic - otherwise your headers from PHP will be overwritten.
  2. put reverse proxy in front of apache that would do that for you. (or do some whacky thing where you have the same apache instance reverse-proxying to itself)
  3. set expiry per-directory (with only svg-generating scripts located there):
<Directory /var/www/html/svg>
ExpiresDefault "access plus 60 seconds"
</Directory>

Similar questions have been asked before around here: Setup HTTP expires headers using PHP and Apache

Community
  • 1
  • 1
Droopy4096
  • 311
  • 1
  • 10
  • I far prefer your option 1, but I could not make it happen...can you explain why ? It seems that htaccess mod exp overrides the headers set in the php file – Giovanni Drago Apr 09 '15 at 15:36
  • @GiovanniDrago yes- you can't mix expiry headers from php and from apache. Apache's mechanism you're using is a "blunt" weapon - it doesn't care what comes - it just can set|append|merge|add|unset|echo|edit the header: [link](http://httpd.apache.org/docs/2.2/mod/mod_headers.html#header), same goes for Expires\* directives - they don't care for pre-existing headers and will override. – Droopy4096 Apr 09 '15 at 17:31
0

Inpired by the post php eTag generation using php, I finally found a solution to cache svgz images in my specific case, but had to set a Etag and send a 304 header MANUALLY:

$duration=300;
$etag=md5(__FILE__.round(time()/$duration));
$ifNoneMatch=(isset($_SERVER['HTTP_IF_NONE_MATCH']) ? trim($_SERVER['HTTP_IF_NONE_MATCH']) : false);
header("Etag: ".$etag);
if ($ifNoneMatch == $etag){header("HTTP/1.1 304 Not Modified");}

Adding the above snippet inside my svg-php file allowed to set a duration to cache my file, which use a random variable to give some surprise to users. However, the above prevent too frequent updates (5min) and limits http requests.

All more elegant solution welcome: I would like to avoid adding the code above to all my php-svg files

Note that all trials to simply add cache control headers in the php failed in both Safari and Firefox, ex:

header("Cache-Control: max-age=900");
header("Expires: ".gmdate("D, d M Y H:i:s",time()+900)." GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s",time()-36000)." GMT");

Many thanks, Giovanni (website: http://isbooth.com)

Community
  • 1
  • 1