2016-02-13 201 views
0

我試圖使用由互聯網提供的SmartFile下載提供的代碼。在代碼中,我使用登錄ID檢查文件名,以避免用戶直接在URL中提供不同的文件名。 (因爲他很容易猜到,因爲文件名的第一部分是來自登錄ID) 。我在代碼中檢查它是否相等,然後允許PDF下載,否則顯示訪問衝突。 到目前爲止每件事情都很好。但下載後,我收到文件已損壞或文件已損壞的消息(它是作爲電子郵件附件發送的,未正確解碼)。 我找不出問題所在。任何幫助讚賞。謝謝php pdf下載文件損壞

<?php 
session_start(); 
include_once('header.php'); 
if(!$_SESSION['username']) 
{ 

    header("Location: index.php");//redirect to login page to secure the welcome page without login access. 
} 
else 
{ 
$user = $_SESSION['username']; 

// Allow direct file download (hotlinking)? 
// Empty - allow hotlinking 
// If set to nonempty value (Example: example.com) will only allow downloads when referrer contains this text 
define('ALLOWED_REFERRER', ''); 

// Download folder, i.e. folder where you keep all files for download. 
// MUST end with slash (i.e. "/") 
define('BASE_DIR','../../downloads/'); 

// log downloads? true/false 
define('LOG_DOWNLOADS',true); 

// log file name 
define('LOG_FILE','downloads.log'); 

// Allowed extensions list in format 'extension' => 'mime type' 
// If myme type is set to empty string then script will try to detect mime type 
// itself, which would only work if you have Mimetype or Fileinfo extensions 
// installed on server. 
$allowed_ext = array (


    // documents 
    'pdf' => 'application/pdf' 
); 



#################################################################### 
### DO NOT CHANGE BELOW 
#################################################################### 

// If hotlinking not allowed then make hackers think there are some server problems 
if (ALLOWED_REFERRER !== '' 
&& (!isset($_SERVER['HTTP_REFERER']) || strpos(strtoupper($_SERVER['HTTP_REFERER']),strtoupper(ALLOWED_REFERRER)) === false) 
) { 
die("Internal server error. Please contact system administrator."); 
} 

// Make sure program execution doesn't time out 
// Set maximum script execution time in seconds (0 means no limit) 
//set_time_limit(0); 

if (!isset($_GET['f']) || empty($_GET['f'])) { 
    die("Please specify file name for download."); 
} 

// Nullbyte hack fix 
if (strpos($_GET['f'], "\0") !== FALSE) die(''); 

// Get real file name. 
// Remove any path info to avoid hacking by adding relative path, etc. 
$fname = basename($_GET['f']); 
if ($fname == $user."IN".".pdf") 
{ 
// Check if the file exists 
// Check in subfolders too 
function find_file ($dirname, $fname, &$file_path) { 

    $dir = opendir($dirname); 

    while ($file = readdir($dir)) { 
    if (empty($file_path) && $file != '.' && $file != '..') { 
     if (is_dir($dirname.'/'.$file)) { 
     find_file($dirname.'/'.$file, $fname, $file_path); 
     } 
     else { 
     if (file_exists($dirname.'/'.$fname)) { 
      $file_path = $dirname.'/'.$fname; 
      return; 
     } 
     } 
    } 
    } 

} // find_file 

// get full file path (including subfolders) 
$file_path = ''; 
find_file(BASE_DIR, $fname, $file_path); 

if (!is_file($file_path)) { 
    die("File does not exist. Make sure you specified correct file name."); 
} 

// file size in bytes 
$fsize = filesize($file_path); 

// file extension 
$fext = strtolower(substr(strrchr($fname,"."),1)); 

// check if allowed extension 
if (!array_key_exists($fext, $allowed_ext)) { 
    die("Not allowed file type."); 
} 

// get mime type 
if ($allowed_ext[$fext] == '') { 
    $mtype = ''; 
    // mime type is not set, get from server settings 
    if (function_exists('mime_content_type')) { 
    $mtype = mime_content_type($file_path); 
    } 
    else if (function_exists('finfo_file')) { 
    $finfo = finfo_open(FILEINFO_MIME); // return mime type 
    $mtype = finfo_file($finfo, $file_path); 
    finfo_close($finfo); 
    } 
    if ($mtype == '') { 
    $mtype = "application/force-download"; 
    } 
} 
else { 
    // get mime type defined by admin 
    $mtype = $allowed_ext[$fext]; 
} 

// Browser will try to save file with this filename, regardless original filename. 
// You can override it if needed. 

if (!isset($_GET['fc']) || empty($_GET['fc'])) { 
    $asfname = $fname; 
} 
else { 
    // remove some bad chars 
    $asfname = str_replace(array('"',"'",'\\','/'), '', $_GET['fc']); 
    if ($asfname === '') $asfname = 'NoName'; 
} 

// set headers 
header("Pragma: public"); 
header("Expires: 0"); 
header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); 
header("Cache-Control: public"); 
header("Content-Description: File Transfer"); 
header("Content-Type: $mtype"); 
header("Content-Disposition: attachment; filename=\"$asfname\""); 
header("Content-Transfer-Encoding: binary"); 
header("Content-Length: " . $fsize); 

// download 
// @readfile($file_path); 
$file = @fopen($file_path,"rb"); 
if ($file) { 
    while(!feof($file)) { 
    print(@fread($file, 1024*8)); 
    flush(); 
    if (connection_status()!=0) { 
     @fclose($file); 
     die(); 
    } 
    } 
    @fclose($file); 
} 

// log downloads 
if (!LOG_DOWNLOADS) die(); 

$f = @fopen(LOG_FILE, 'a+'); 
if ($f) { 
    @fputs($f, date("m.d.Y g:ia")." ".$_SERVER['REMOTE_ADDR']." ".$fname."\n"); 
    @fclose($f); 
} 
} 
else 
{ 
        echo '<script type="text/javascript">alert("Access Violation !")header("Location: index.php");</script>'; 
} 
} 
?> 
+2

可能有些輸出打印在標題之前。要檢查它,嘗試在第一個'header'調用之前放置'die()',然後檢查結果是否完全**爲空(請參閱瀏覽器的源代碼頁)。如果什麼都沒有發生,請檢查標題中的變量是否已更正($ mtype,$ asfname等);還檢查下載文件的文件大小。 – fusion3k

+1

如果您已經有位了,請去掉「標題」調用並直接訪問該頁面。如果這沒有幫助,請從'fopen,fputs,fclose'中刪除抑制'@'的錯誤,看看你看到了什麼 – Terminus

+0

謝謝老人。但沒有人工作。請幫助 – suresh

回答

0

輸出緩衝區在發送任何頭文件之前應該被清除,否則文件將被損壞。 ob_end_clean()應該照顧它。