Отображать все изображения из внешней корневой веб-папки, используя PHP - PullRequest
3 голосов
/ 04 мая 2010

Я хочу отобразить все изображения, которые хранятся вне моей корневой веб-папки. Пожалуйста, помогите мне. Я могу отображать только одно изображение повторно. Например, если в моей папке 5 изображений, в моем браузере отображается только одно изображение 5 раз. Пожалуйста помоги мне с этим. Я работаю над этой проблемой уже более месяца. Я новичок. Помогите. Спасибо. Вот код, который я использую.

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 Ответ

3 голосов
/ 04 мая 2010

Проблема в том, что вы не анализируете переменную QueryString, переданную в call_images.php, а вместо этого запускаете тот же запрос к базе данных, который просто возвращает первое изображение, с которым база данных возвращается каждый раз. Вот (надеюсь) исправленная версия.

<?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();
?>

Что нужно знать об этих изменениях:

  • $fn = mysql_real_escape_string($_GET['imgPath']); получает переменную, которую вы передали через строку запроса, и затем экранирует ее, чтобы мы могли снова запустить ее через базу данных. Таким образом, мы можем быть уверены, что пользователь не использовал относительные пути, чтобы попытаться показать изображение, к которому у него не должно быть доступа (если у вас нет записи в базе данных; безопасность - это то, что вы делаете).
  • Я полностью удалил цикл, это было не нужно
  • Я использовал mysql_result(), поскольку нам требовались данные только одного поля.
  • Я бы рекомендовал переключить readfile() на fpassthru(), который требует вызова fopen, но не буферизует содержимое файла в памяти.
...