Search code examples
phpapache.htaccess

How to configure htaccess to display images from a directory other than the root directory


I am working with PHP and apache, and I have configured a router that shows me the images that are on the public site and root without problem, but when trying to show the images of the private site does not load them.

test

I need to save images on the private site and show them only to the owners, I don't think saving the images on the public site is ideal.

The router is configured so that all routes publicly begin with "/" and not "../".

How could I solve this locally and have it work correctly on a real server?.

//project structure:

app/
-------/public     <======Root
---------------/css
---------------/img
---------------/js
---------------/index.php
---------------/.htaccess
-------/private
---------------/imgs    
---------------/pages
---------------/dashboard.php
-------/lib
-----------/route.php`

//.htaccess config

AddType Content-Type: application / x-www-form-urlencoded

Options -MultiViews
RewriteEngine On 

RewriteCond %{REQUEST_FILENAME} !-f 


RewriteRule ^(.*)$ index.php? [QSA,L]

//html

    <span> <img src="img/test2.jpg" width="30px"> </span>
   <span> <img src="../private/imgs/test1.jpg" width="30px"> </span>

//php try

<?php
    $directorio = "../private/imgs/";

    function printImagesDir($dir){
        $files = glob($dir.'*.{jpg,JPG,jpeg,JPEG,png,PNG}', GLOB_BRACE);
        foreach($files as $filename){
            $imgsrc = basename($filename);
            echo "<img src='{$dir}/{$imgsrc}' />";
        }        
    }

    printImagesDir($directorio);
?>

Solution

  • Route all your images into one script file that will fetch images (or even validate if current logged in user is valid to access that).

    # .htaccess
    
    # Adjust regex to your needs
    RewriteRule images/(\w+\.(?:\w{3,4}))$ images.php?image=$1 [L]
    
    // public/images.php
    
    $image = $_GET['image'] ?? null;
    
    if (empty($image)) {
        throw new Exception('Image not found');
    }
    
    $name = dirname(__DIR__) . '/private/imgs/' . $image;
    $fp = fopen($name, 'rb');
    
    // Change header depending on file extension!
    header('Content-Type: image/png');
    header('Content-Length: ' . filesize($name));
    
    fpassthru($fp);
    
    // Terminate further output or image can get corrupt
    exit(0);
    

    and finally in HTML just request that URL:

    <img src="images/test1.jpg"/>
    <img src="images.php?image=test1.jpg"/>