Display all images from outside web root folder us

2019-07-06 21:55发布

问题:

I want to display all images that are stored outside my web root folder. Please help me. I am only able to display one image repeatedly. For example, if I have 5 images in my folder, only one image is displayed on my browser 5 times. Please help me on this. I've been working on this problem for over a month now. I'm a newbie. Help. Thank you. Here is the code I'm using.

images.php

<?php   
  // Get our database connector
require("includes/copta.php");

// Grab the data from our people table
$sql = "select * from people";

$result = mysql_query($sql) or die ("Could not access DB: " . mysql_error());

$imgLocation = " /uploadfile/";

while ($row = mysql_fetch_array($result))
{
    $imgName = $row["filename"]; 
    $imgPath = $imgLocation . $imgName;

    echo "<img src=\"call_images.php?imgPath=" . $imgName . "\"  alt=\"\"><br/>";
    echo $row['id'] . " " . $imgName. "<br />";

}

?>

call_images.php

<?php
  // Get our database connector
require("includes/copta.php");

$imgLocation = '/ uploadz/';

$sql = "select * from people";

$result = mysql_query($sql) or 
    die ("Could not access DB: " . mysql_error());   

while ($row = mysql_fetch_array($result)) {

    $imgName = $row["filename"]; 
    $imgPath = $imgLocation . $imgName;


    // Make sure the file exists
    if(!file_exists($imgPath) || !is_file($imgPath)) {
        header('HTTP/1.0 404 Not Found');
        die('The file does not exist');
    }

    // Make sure the file is an image
    $imgData = getimagesize($imgPath);
    if(!$imgData) {
        header('HTTP/1.0 403 Forbidden');
        die('The file you requested is not an image.');
    }


    // Set the appropriate content-type
    // and provide the content-length.

    header("Pragma: public");
    header("Expires: 0");
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");

    header("Content-Type: image/jpg");
    header("Content-length: " . filesize($imgPath));

    // Print the image data
    readfile($imgPath);
    exit();

}
?>

回答1:

The problem is you're not parsing the QueryString variable you pass to call_images.php, but instead running the same database query, which will just return the first image that the database comes back with every time. Here is a (hopefully) corrected version.

<?php
// Get our database connector
require("includes/copta.php");

$imgLocation = '/ uploadz/';

$fn = mysql_real_escape_string($_GET['imgPath']);

$sql = "select filename from people WHERE filename = '{$fn}'";

$result = mysql_query($sql) or 
    die ("Could not access DB: " . mysql_error());   

if (mysql_num_rows($result) == 0) {
    header('HTTP/1.0 404 Not Found');
    die('The file does not exist');
}
$imgName = mysql_result($result, 0, 0); 
$imgPath = $imgLocation . $imgName;

// Make sure the file exists
if(!file_exists($imgPath) || !is_file($imgPath)) {
    header('HTTP/1.0 404 Not Found');
    die('The file does not exist');
}

// Make sure the file is an image
$imgData = getimagesize($imgPath);
if(!$imgData) {
    header('HTTP/1.0 403 Forbidden');
    die('The file you requested is not an image.');
}


// Set the appropriate content-type
// and provide the content-length.

header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");

header("Content-Type: image/jpg");
header("Content-length: " . filesize($imgPath));

// Print the image data
readfile($imgPath);
exit();
?>

What to know about these changes:

  • $fn = mysql_real_escape_string($_GET['imgPath']); gets the variable you passed via querystring, and then escapes it so we can run it through the database again. This way we can be sure that the user hasn't used relative paths to try to expose an image that they shouldn't have access to (unless you have a database record for it; security is what you make it).
  • I removed the loop entirely, it was not necessary
  • I used mysql_result() since we only needed one field's worth of data.
  • I would recommend switching readfile() for fpassthru(), which requires a call to fopen, but does not buffer the contents of the file in memory.