簡體   English   中英

Web服務器根目錄外部的PHP顯示/下載目錄文件

[英]PHP display/download directory files outside the webserver root

我已經下載了此非常簡單的一個文件php Web文件資源管理系統(稱為Indexer )並將其添加到我的XAMPP服務器。

我的XAMMP服務器在C:驅動器上,但是我希望Indexer在我的G:驅動器上顯示目錄。 但是,當我更改(我認為是)正確的配置變量時,它將無法正常工作。

這是我認為與問題有關的代碼:

// configuration  
$Root = realpath("G:/test");  
$AllowDownload = TRUE;  
$WebServerPath = dirname("G:/test");

然后在代碼中...

elseif ($AllowDownload) {  

        echo "<a href=\"http://".getenv("SERVER_NAME").$WebServerPath."/$rel_path".$item["filename"]."\">".$item["name"]."</a>";
    }

correctly display the contents of the "test" directory on the G: drive, but when I click the filename, to download/view the file, the link is broken because the php constructs the link wrong (I suppose). 這是發生了什么:腳本在G:驅動器上正確顯示了“ test”目錄的內容,但是當我單擊文件名以下載/查看文件時,鏈接被破壞了,因為php構造錯誤的鏈接(我想)。 鏈接看起來像這樣:http:// localhostg // [文件名]。

你知道如何解決這個問題嗎?

如果我更改配置變量,此腳本將完美工作,從而顯示相對子目錄的內容。 它還說$ Root變量可以位於Web服務器根目錄之外。

另外,即使單擊鏈接不起作用,右鍵單擊並選擇“目標另存為”也可以保存/下載文件。

(隨時詢問您是否需要更多信息):)

您的Web服務器看不到DocRoot外部的文件,因此無法通過具有直接鏈接的瀏覽器提供文件。 您需要使用正確設置標頭的readfile()將它們的內容打印到瀏覽器中。

為此,您需要在indexer.php中更改配置:

// this way it works with accentuated letters in Windows
$Root = utf8_decode("G:\test"); // define the directory the index should be created for (can also be located outside the webserver root)

$AllowDownload = TRUE; // enclose file items with the anchor-tag (only makes sense when the files are in the webserver root)
// you need to place download.php in the same directory as indexer.php
$WebServerPath = dirname($_SERVER['SCRIPT_NAME']) . "/download.php?path="; // path where the indexed files can be accessed via a http URL (only required when $AllowDownload is TRUE)

並且您必須將一個名為download.php的新文件與indexer.php同一目錄中,其內容如下:

<?php

// it must be the same as in indexer.php
$Root = utf8_decode("G:\test");

function checkFileIsInsideRootDirectory($path, $root_directory) {
    $realpath = realpath($path);

    if (!file_exists($realpath))
        die("File is not readable: " . $path);

    // detects insecure path with for example /../ in it
    if (strpos($realpath, $root_directory) === false || strpos($realpath, $root_directory) > 0)
        die("Download from outside of the specified root directory is not allowed!");
}

function forceDownload($path) {
    $realpath = realpath($path);

    if (!is_readable($realpath))
        die("File is not readable: " . $path);

    $savename = (basename($path));

    header("Pragmaes: 0");
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    header("Cache-Control: private", false);
    header("Content-type: application/force-download");
    header("Content-Transfer-Encoding: Binary");
    header("Content-length: " . filesize($path));
    header("Content-disposition: attachment; filename=\"$savename\"");

    readfile("$path");
    exit;
}

if (!isset($_GET['path']))
    die("Path not specified!");

$fullPath = $Root . $_GET['path'];

checkFileIsInsideRootDirectory($fullPath, $Root);

forceDownload($fullPath);

您必須更改您的Apache配置。 問題不在於php腳本,而是Web服務器(除非您將其配置為Web服務器,否則它無法在Web根目錄之外提供文件)。

在您的apache配置中嘗試以下操作:

Alias /testalias "G:/test"
<Directory "G:/test">
  Options Indexes FollowSymLinks MultiViews ExecCGI
  AllowOverride All
  Order allow,deny
  Allow from all
</Directory>

這告訴Apache在訪問http:// localhost / testalias時從G:/ test提供文件

然后像這樣更改腳本配置:

$WebServerPath = dirname("testalias");

它應該工作!

讓我們看一下該腳本:

$Root = realpath("."); // define the directory the index should be created for (can also be located outside the webserver root)
$AllowDownload = TRUE; // enclose file items with the anchor-tag (only makes sense when the files are in the webserver root)
$WebServerPath = dirname(getenv("SCRIPT_NAME")); // path where the indexed files can be accessed via a http URL (only required when $AllowDownload is TRUE)

注意“僅當文件位於Web服務器根目錄中時才有意義”和“可通過http URL訪問索引文件的路徑”。 這表明此腳本的設計目的不在於能夠下載Web服務器根目錄之外的文件。

但是,您可以修改此腳本,使其能夠按照styu在其回答中指出的方式進行操作。 然后,您可以將所做的更改發送給腳本的作者。

順便說一句,我在自己的服務器上對此進行了測試。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM