PHP Readfile()不适合我,我不知道为什么

时间:2011-11-06 23:42:48

标签: php download readfile

我试图让这段代码工作但是出于某种原因,所有的echo都能够输出正确的内容,但是标题似乎并不想强制下载我的文档。以下是我试图为文件下载构建的文件。它设置为输入如下代码:downloader.php?f=13&t=doc从两个文件夹之一下载名为201-xxx.doc201-xxx.pdf的文件,具体取决于用户权限。

所有逻辑都适用于底部的标题信息。如果我注释掉标题内容类型和标题内容处置,那么它会将文件读入浏览器。如果包含其中任何一行,则会显示错误"Error 6 (net::ERR_FILE_NOT_FOUND): The file or directory could not be found."

<?php
//ob_start();
if ( !defined('__DIR__') ) define('__DIR__', dirname(__FILE__));
define( "TLOJ_FSROOT", __DIR__ . "/" );
define('WP_USE_THEMES', false);
require('./wp-blog-header.php');

$lessonnumber = $_REQUEST['f'];
$type = $_REQUEST['t'];

    if ( $lessonnumber < '10' ) { $threedigitlesson = '00' . $lessonnumber; }
    elseif ( $lessonnumber < '100' ) { $threedigitlesson = '0' . $lessonnumber; }
    else { $threedigitlesson = $lessonnumber; }
    $filenamestart = "201-" . $threedigitlesson;

    $contenttype = 'application/octet-stream';

    switch ($type) {
        case 'pdf':
            $extension = '.' . $type;
            $contenttype = 'application/pdf';
            break;
        case 'doc':
            $extension = '.' . $type;
            $contenttype = 'application/msword';
            break;
        default:
            $contenttype = '';
            exit("It appears that you are trying to download a file that is not a lesson document. Please contact us if you believe this to be an error.");
    }

$filename = $filenamestart . '.' . $type;
$current_user = wp_get_current_user();

//$siteurl = site_url();
$pathroot = TLOJ_FSROOT;

$download_path = $pathroot . "1hoefl4priaspoafr/";
    if ( current_user_can("access_s2member_ccap_extendedlessons")) { 
        $download_path = $download_path . "ex/";
    } else {
        $download_path = $download_path . "st/";
    }

$file_path = $download_path . $filename;

$tlojmemberlength = tlojunlocklessons();

if ( !is_user_logged_in() ) { exit("Please log in to access the file"); }

if ( !current_user_can("access_s2member_ccap_downloadlessons") ) { exit("You don't have access to download the lessons!"); }

if ( $lessonnumber > $tlojmemberlength ) { exit("It appears you are trying to jump ahead! While I am excited at your enthusiam, let's not rush our study time."); }

if ( ($lessonnumber > '195') && (!current_user_can("access_s2member_ccap_lastweek")) ) { exit("Upgrade now to access the downloads for the five bonus lessons!"); }

// build Final File Name
$extendedmessage = "";
if ( current_user_can("access_s2member_ccap_extendedlessons")) { $extendedmessage = " - Extended"; }
$myfinishedlessonname = "Lesson " . $lessonnumber . $extendedmessage . " -- The Life of Jesus Study" . "." . $type;

//  echo 'Download Path: ' . $download_path . '<br />';
//  echo 'Source/Lesson Number: ' . $lessonnumber . '<br />';
//  echo 'File Name: ' . $filename . '<br />';
//  echo 'File Type: ' . $type . '<br />';
//  echo 'Allowed Lessons: ' . $tlojmemberlength . '<br />';
//  echo 'Final File Name: ' . $myfinishedlessonname . '<br />';
//  echo 'File Path: ' . $file_path . '<br />';
//  echo 'Content Type: ' . $contenttype . '<br />';
//  echo 'File Size: ' . filesize($file_path) . '<br />';

if (headers_sent()) { exit("Sorry but the headers have already been sent."); }

    ob_end_clean();

if (file_exists($file_path)) {
    header('Content-Description: File Transfer');
    header('Content-type: ' . $contenttype);
    header('Content-disposition: attachment; filename="' . $myfinishedlessonname . '"');
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: ');
    header('Pragma: ');
    header('Content-Length: ' . filesize($file_path));
    flush();
    ob_clean();
    readfile($file_path);
    exit;
} else { exit("No file present."); }


?>

请帮助我,因为我一整天都在这里,我很困惑,为什么这不起作用。 Filesize()拉出正确的长度,所以我知道我正在查看的路径中有一个文件。 (我也是PHP的新手,所以如果有遗漏的东西,请分享。)

提前致谢!

5 个答案:

答案 0 :(得分:8)

如果它是一个大文件,则无法与readfile一起发送。试着用这个:

  $handle = fopen($file_path, 'rb'); 
  $buffer = ''; 
  while (!feof($handle)) { 
    $buffer = fread($handle, 4096); 
    echo $buffer; 
    ob_flush(); 
    flush(); 
  } 
  fclose($handle); 

答案 1 :(得分:3)

我不确定为什么会这样,但我能够通过将我的php文件分成两部分来解决这个问题。第1部分加载WordPress并执行逻辑验证。然后文件1将信息传递给文件2以执行下载逻辑并写入标题信息。

就像我说的那样,我不确定为什么会这样,但是一个比我更了解PHP的朋友说,有时如果脚本处理时间太长,那么标题就不会采用。对于这些标题,WordPress可能会将脚本挂起太长时间。

希望这个解释可以帮助那些遇到这种困难的人。

答案 2 :(得分:2)

如果您尝试使用

强制浏览器下载文件
Content-Type: application/octet-stream
Content-Disposition: attachment; filename="your-file.jpg"

但Chrome会为您提供 ERR_FILE_NOT_FOUND ,而Firefox也会因“未找到”而失败(奇怪的是Opera似乎有效)尝试添加:

header('HTTP/1.0 200 OK', true, 200);

答案 3 :(得分:0)

Chrome告诉我:“错误6(net :: ERR_FILE_NOT_FOUND):找不到文件或目录。” 而且Firefox说该文件不存在。

虽然同一个php文件正在处理不同类型的下载我遇到了PNG和ICO的问题,我尝试了一些只显示图片但没有提示下载框的方法。

最后我发现感谢Crazycoolcam,Wordpress就是问题所在。 我把一个php包含在一个名为“tools.php”的文件中, 在tools.php里面它有一个包含到wordpress的主头文件, 为了解决这个问题,我将我的工具文件拆分为wordpress版本和非wordpress版本,并在将文件写出来之后将wordpress包括在内。

答案 4 :(得分:0)

这里只是另一种可能性,为什么它不起作用。这是我的原因。有趣的是,file_exists返回true,但没有任何形式向公众提供下载文件而没有正确设置以下内容。

PHP有一个名为 open_basedir

的设置

确保将此设置与您的托管环境正确相关。 open_basedir可以通过php.ini

编辑