2012-09-22 21 views
-2

我在编写一个显示HTML文本框的单个PHP脚本时遇到问题,该文本框将搜索Linux计算机的/ tmp目录中的文件。一旦用户将该字符串键入文本框并按下提交按钮,匹配的超链接将显示在文本框下方,并具有网络目录之外的文件名(位于/ tmp)。如何在不使用HTML内容的情况下使用PHP下载Web目录之外的文件?

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

有没有什么办法可以下载文件,而无需将我的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>"; 
?> 
+0

'return'退出当前范围,在本例中为脚本。最后的回声将不会再执行。 http://php.net/return - 你的系统也可以被篡改和攻击,因为这是开放的注入和遍历攻击。 – hakre

+0

您可以在'readfile'行之后添加'exit;'。 – andrewsi

+0

如果我添加一个退出,则下载的文件在文件内容之前仍具有HTML内容。我正在以正确的方式来解决这个问题吗? – Vahe

回答

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/数据不应该提供下载,因为它可以用来攻击的应用程序,其用户甚至系统。

+0

有没有办法阻止函数调用之前的任何html不被输出到文件中。这是我卡住的地方。因为我正在使用标题,所以出现此问题。这可以做到没有标题? – Vahe

+0

@ user1691103:请参阅上面的脚本,这是整个脚本。函数调用之前没有输出。 – hakre

+0

当我在/ tmp里面创建一个包含数字1234的文件abcd,然后搜索abcd并从值1234之前的脚本中下载包含html标签的文件。 – Vahe

相关问题