I am finishing up development of my first Yii website, and I would like to ask if someone can check the following bit of code. The action below should either display an image in the browser, or force a download of the image. Images that have been uploaded (to a non-web-accessible directory) will not be modified, other than possibly being deleted. I would like a browser to use a cached version of the image as much as possible.
Like I said, this is my first Yii project, but it is also my first larger complete project. So I have been learning a lot about Yii, PHP, JavaScript and so on. Caching is important so that my site reduces bandwith as much as needed, but Googling for headers and cache-control seems to bring up a lot of different code fragments. This is the best I could figure out so far.
The below is dumbed down a bit, but the important parts are shown. The $model variable contains an Image model that holds information about the image path, mime type and so on.
public function actionImage($model, $forceDownload)
{
$lastModified = filemtime($model->path);
$ClientHeaders = apache_request_headers();
if (isset($ClientHeaders["If-Modified-Since"]) && (strtotime($ClientHeaders["If-Modified-Since"]) >= $lastModified))
header("Last-Modified: " . gmdate("D, d M Y H:i:s", $lastModified) . " GMT", true, 304);
else
{
header('Content-Type: ' . $model->mime);
header('Content-Disposition: filename="' . $model->filename . '"');
header('Cache-Control: private, must-revalidate, max-age=31536000');
header("Last-Modified: " . gmdate("D, d M Y H:i:s", $lastModified) . " GMT", true, 200);
if ($forceDownload)
{
header('Content-Description: File Transfer');
header('Content-Length: ' . filesize($model->path));
header('Content-Disposition: attachment; filename="' . $model->filename . '"');
}
readfile($model->path);
}
exit;
}
Any input on what is right, wrong, and how to improve it would be very much appreciated. Thanks!