0

I have an img tag with a src value defined. However, I don't want to show this src value, since it compromises my server. I've been recommended to use virtual URL: The IMG tag refers to a URL, however in this scheme the URL is a virtual one: /uploads/myuser/mypict.jpg will not directly map to the image, but a rewrite rule will pass this URL as parameter to a /uploads.php?url=myuser/mypict.jpg script, and this script will have the ability to access and send the content of files outside of the web root directory (web server root directory does not apply to scripts' file handling functions). Source

But I don't understand how an img tag could access to a PHP script, and how this script could show the image in the img tag.

Any idea on how could I achieve it?

Update:

I would give an answered mark to all of you, ... but I can't. I've finally found a way of calling the script without any parameter, as the name and path of image are stored in the database. I'm working with Symfony2, so I will give my particular solution:

I simply do in a Twig template:

<img src="{{ path('acme_home_seeImage') }}" width="{{ image.width }}" height="{{ image.height }}">

and add the route:

acme_home_seeImage:
  pattern: /seeImage
  defaults: { _controller: AcmeHomeBundle:Home:seeImage}

Then, when the page is loaded, the img tag trigger the seeImageAction() method which handles the below code:

public function seeImageAction() 
{
    if(!isset($_SESSION)) session_start();
    header('Content-type: image/png');
    if(isset($_SESSION['id'])) {
        //call to image in database
        $em = $this->getDoctrine()->getEntityManager();
        $image = $em->getRepository('AcmeHomeBundle:Image')->find($_SESSION['id']);
        readfile($image->getPath());
    } else {
        readfile('public/img/default.png');
    }   
}

as the image is associated to the session id of the client. And that's all! Now, I can put the upload directory outside the Document Root with success, and my upload path keeps hidden.

Community
  • 1
  • 1
Manolo
  • 16,729
  • 16
  • 67
  • 115

3 Answers3

3

The IMG SRC attribute links to a resource of type "image". An image is a bag of octets. So what your server have to do is send back a bag of octets :)

Usually, the SRC attribute is a filename which is interpreted by the server as a path on the disk. What is important is that the server send back an image, regardless of its origine. So it may be a file on the disk or a script generated image, it doesn't care.

If the link points to a script, the only thing the script must do is generate an image and ensure that the proper headers are sent. With PHP, you have several way to generate an image (read it on file system and output it, generate it from scratch, generate it from cloning/modifying existing on,...) then for the headers, you have the header function.

This post may inspire you : how to send png image from server to display in browser via ajax (the response from Alexei is your response).

Community
  • 1
  • 1
Armage
  • 588
  • 6
  • 16
2

If php script's header is set to

header('Content-Type: image/jpg');

then the php script appears as jpg image(to img src), just like /uploads/myuser/mypict.jpg.

There's an example:

<?php
  header('Content-Type: image/jpg');
  readfile('/uploads/myuser/mypict.jpg');
?>

Then you can access it like this:

<img src="imghandler.php" alt="mypict.jpg"/ >
aksu
  • 5,035
  • 5
  • 21
  • 38
2

Let me clarify this with a small ASCII art.

Browser                      Server
   |
   | requests HTML
   |--------------------------->|
                                | sends HTML back
   |<---------------------------|
   |
   | reads HTML,
   | finds <img>, re-
   | solves URL to
   | image from src attribute
   |
   | requests image /foo.jpg
   |--------------------------->|
                                | searches foo.jpg,
                                | but doesn't find
                                | it. Configured to
                                | call PHP script in this case:
                                |
                                |-----------------------> PHP script called
                                                          with URL foo.jpg.
                                                          Checks, if user has
                                                          right to view, and
                                                          if so, reads bar.jpg
                                |<----------------------- and outputs that
                                |
                                | Takes output from PHP
                                | and sends it to browser
   |<---------------------------|
   |
   | receives image bar.jpg,
   | but doesn't know. For the
   | browser it's called /foo.jpg

The trick is, that /foo.jpg doesn't exist, but the server calls the PHP script instead. This does the rights management and returns the correct data. Note, that bar.jpg is not accessible via server, that is, a request to /bar.jpg gives a 401 Forbidden (or better, bar.jpg is stored somewhere completely differently).

Boldewyn
  • 75,918
  • 43
  • 139
  • 205