We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Using PHP to serve Images

I have situation where I need to serve image files from PHP for security. Actual image file are stored outside public directory. I have image size, image mime type , name etc. in database .

In simple PHP, could be done using :


if($imageData) {
// array with image details from DB :
// $imageData

/ basic headers
header("Content-type:" . $imageData['mimeType']);
header("Expires: Mon, 1 Jan 2099 05:00:00 GMT");
header("Last-Modified: " . date(DATE_RFC2822 , $imageData['created'] . " GMT");
header("Content-Length: $imageData['size'] bytes");

// output the file contents
readfile($$imageData['full_path']);
} else {
header('HTTP/1.0 404 Not Found');
die();
}

How can achieve this in pure Phalcon way. I know I can disable view rendering but still a proper idea or guide will be helpful. Also, currently I have no plan to use micro application .



8.8k
edited Jul '18

Nevermind, I figured it myself. What I did was disable the vew rendering completely by :

 $this->view->disable();

And then using https://docs.phalcon.io/uk/3.3/response I created various headers

        $this->response->setContentType($mimeType);
        $this->response->setExpires(new dateTime('+50 years'));
        $this->response->setLastModified($lastModified);
        $this->response->setContentLength($imgSize);

Lastly, you need to load the file using readfile();

And then in and summ it up by :

    return $this->response->send();


8.8k

However, I am not particularly sure how to handle 404 not found error. I did
if (!$files) { $this->response->setStatusCode(404, 'Not Found'); die(); }

That way , it all just ends when there is no file to serve. But hopefully Phalcon has some native way to just send 404 response and nothing else ?



8.3k

The best idea is using exceptions:

throw new Exception('File not found');

then You don't need to do anything if only You have error handling. I don't reccomend Phalcon error handler, because we can't change anything. You have to write Your own or use other library (I recommend Whoops for instance). Error handler catches exceptions and shows error page, debug stack trace or something different. This is fragment od my code:

   public function handle()
    {
        if ($this->config->error->logErrors) {
            error_log($this->getException());
        }

        $simpleView = $this->prepareSimpleView();

        $content = $simpleView->render($this->config->error->viewsDir . DIRECTORY_SEPARATOR . 'general', [
            'exception' => $this->getException(),
        ]);

        $response = new \Phalcon\Http\Response();
        $response->setStatusCode(404, "Not found");
        $response->setContent($content);

        $response->send();
    }

Of course You can service many situations like "bad request" or "forbidden".