-2

我在编写一个显示 HTML 文本框的 PHP 脚本时遇到问题,该文本框将在 Linux 机器的 /tmp 目录中搜索文件。一旦用户在文本框中键入字符串并按下提交按钮,匹配的超链接将显示在文本框下方,其中包含 Web 目录(在 /tmp 中)之外的文件的名称。

当我单击超链接时,我想从 /tmp 目录下载文件。不幸的是,因为我需要使用单个 php 脚本,所以 HTML 内容被附加到文件中,因为我使用的是 php header 命令。

有什么方法可以下载文件,而无需将我的 php 页面中的 html 附加到文件中,也无需使用多个 php 脚本?

<?php


function displayfiles()
{
    echo '<ul>';

    if ($handle = opendir('/tmp')) 
    {
        while ($file = readdir($handle))
        {
            if ($file != "." && $file != ".." && (strstr($file, $_POST['searchbox'])))
            {
                echo '<li><a href="search.php?file='.$file.'">'.$file.'</a></li>';
            }
            else if ($file != "." && $file != ".." && (eregi($file, $_POST['searchbox'])))
            {
                echo '<li><a href="search.php?file='.$file.'">'.$file.'</a></li>';  
            }
        }
        closedir($handle);
    }
    echo '</ul>';
}

function downloadfile($filename)
{            
    header("Content-disposition: attachment; file='/tmp/$filename' filename=$filename");
        header("Content-Length: " . filesize("/tmp/$filename"));
        header("Pragma: no-cache");
        header("Expires: 0");
        readfile("/tmp/$filename");
    exit(); 
}


echo 
"<html>
<head>
<title>File Search</title>
</head>
<body>
        <form method='POST'>
        <input id='searchbox' name='searchbox' id='searchbox' type='textbox' />
        <input type='submit' name='submit' />
        </form>";

                if (isset($_POST['submit']))
                {
                    displayfiles();        
                }
                else if (isset($_GET['file']) && file_exists("/tmp/".$_GET['file']))
                {
            downloadfile($_GET['file']);
        }

 echo "</body></html>";
?>
4

1 回答 1

0

您需要在输出其他任何内容之前处理文件下载的输出,快速而肮脏的示例(即使只有一个功能而不是评论中建议的两个功能,我想您明白了):

<?php

function action_download() {
    if (!isset($_GET['file'])) return FALSE;
    $file = sprintf('/tmp/%s', $_GET['file']);
    $file = realpath($file);
    if (substr($file, 0, 5) !== '/tmp/') return FALSE;
    if (!is_file($file) || !is_readable($file)) return FALSE;

    header("Content-disposition: attachment; filename='".basename($file)."'");
    header("Content-Length: " . filesize($file));
    header("Pragma: no-cache");
    header("Expires: 0");
    readfile($file);
    return TRUE;
}

if (action_download()) return;

?>
<head>
<title>File Search</title>
</head>
<body>
        <form method='POST'>
        <input id='searchbox' name='searchbox' id='searchbox' type='textbox' />
        <input type='submit' name='submit' />
        </form>
<?php
                if (isset($_POST['submit']))
                {
                        echo '<ul>';

                         if ($handle = opendir('/tmp')) {
                                while ($file = readdir($handle))
                                {
                                  if ($file != "." && $file != ".." && (strstr($file, $_POST['searchbox'])))
                                  {
                                        echo '<li><a href="search.php?file='.$file.'">'.$file.'</a></li>';
                                  }
                  else if ($file != "." && $file != ".." && (eregi($file, $_POST['searchbox'])))
                  {
                        echo '<li><a href="search.php?file='.$file.'">'.$file.'</a></li>';  
                  }
                                }
                          closedir($handle);
                          }
                        echo '</ul>';
                }
?>
</body></html>

还要注意其中可能存在/tmp/不应提供下载的数据,因为它可用于攻击应用程序、其用户甚至系统。

于 2012-09-22T17:59:34.007 回答