php link to image file outside default web directory

Solution 1:

It is not possible to directly access files outside of the webroot; this is a builtin security restriction that is there for good reason.

It is however possible to use a PHP-script to serve these images for you. This way you can call an image like:

/image.php?file=myfile.jpg

and use file_get_contents() to get the file contents and print them to your browser. You should also send the headers to the client, in this case using PHP's header() function. A short example:

<?php

    $file = basename(urldecode($_GET['file']));
    $fileDir = '/path/to/files/';

    if (file_exists($fileDir . $file))
    {
        // Note: You should probably do some more checks 
        // on the filetype, size, etc.
        $contents = file_get_contents($fileDir . $file);

        // Note: You should probably implement some kind 
        // of check on filetype
        header('Content-type: image/jpeg');

        echo $contents;
    }

?>

Using a script to this has some more advantages:

  • You can track your downloads and implement a counter, for example
  • You can restrict files to authenticated users
  • ... etc

Solution 2:

If you are using Apache as the server, you can set it to alias a directory in httpd.conf...

<IfModule mod_alias.c>

    Alias /images/ "/User/Public_html/Image/"

    <Directory "/User/Public_html/Image">
        Options Indexes MultiViews
        AllowOverride None
        Order allow,deny
        Allow from all
    </Directory>

</IfModule>

IIRC, the aliased folder does not need to be within the webroot.

Solution 3:

You can't serve a page that's outside of the web directory because the path doesn't work, i.e. http://mydomain.com/../page.html simply refers to an inaccessible location.

If you really want to serve (static) files that are outside the webroot, you could write a small PHP script to read them and output them. Thus you would redirect requests to the PHP script, and the PHP would read the appropriate file from disk and return it back.

Solution 4:

Create symlink inside web root that points to directory you want.

cd public_html
ln -s ../images

Apache needs Options +FollowSymlinks configuration directive for this to work (you may place it in .htaccess in your web root).

Writing PHP script that serves files from outside web root defeats the purpose of web root. You'd have to verify paths very carefully to avoid exposing entire disk to the web.