2012-01-19 18 views
4

名前とバージョンを指定してファイルをダウンロードするPHPスクリプトを作成しています。ファイルは次のようにサーバー上に保存されます。名前が変更されたファイルをPHPでダウンロードする

/dl/Project1/1.0.txt 
/dl/Project1/1.1.txt 
/dl/Project2/2.3.jar 
/dl/Project2/2.3.1.jar 

そして、このようなファイルを取得するためのパスは次のようになります。実際にファイルをダウンロードするときに

download.php?name=Project1&type=txt&version=1.0 
download.php?name=Project1&type=txt&version=1.1 
download.php?name=Project2&type=jar&version=2.3 
download.php?name=Project2&type=jar&version=2.3.1 

問題が発生します。この例では、最初の2つのファイルをProject1.txtとしてダウンロードし、最後の2つをProject2.jarとしてダウンロードします。これを有効にするには、これらの名前を一時的に変更するにはどうすればよいですか?

答えて

6

ファイルの名前を定義するヘッダーを送信します。

$filename = $name . "." . $type; 
header('Content-Description: File Transfer'); 
header('Content-Type: application/octet-stream'); 
header('Content-Disposition: attachment; filename=' . $filename); 
header('Content-Transfer-Encoding: binary'); 
header('Expires: 0'); 
header('Cache-Control: must-revalidate'); 
header('Pragma: public'); 
header('Content-Length: ' . filesize($file)); 

これらを送信する必要があるので、追加のヘッダーも追加しました。これはあなたができることの変更された例ですsee in the PHP documentation on readfile

0

あなたはおそらく、単にコンテンツ-dispositionヘッダーを使用したい:

header('Content-disposition: attachment; filename=Project1.txt'); 
readfile('Project1/1.0.txt'); 
2

あなたはそれを名前を変更する必要はありません、あなただけのヘッダー内の名前を変更する必要があり、スクリプトがあります:

<?php 
// Check is set all params 
if (isset($_GET['name'], $_GET['type'], $_GET['version'])) { 
    // Get the params into variables. 

    // Secure replace to avoid the user downloading anyfile like @Kristian Antonsen said. 
    // Replace all '..' to a single '.'; 
    $name = preg_replace('/[\.]{2,}/', '.', trim($_GET['name'])); 
    // Replace any strange characters. 
    $type = preg_replace('/[^A-Za-z0-9]/', '', trim($_GET['type'])); 
    // Replace any letter and strange character. 
    $version = preg_replace('/[^0-9\.]/', '', trim($_GET['version'])); 

    /** 
    * Check is all the params filled with text 
    * and check if the version is in the right format. 
    */ 
    if (!empty($name) && 
     !empty($type) && 
     !empty($version) && 
     preg_match('/^[0-9](\.[0-9])+$', $version)) { 
    /** 
    * Get the file path, here we use 'dirname' to get the absolute path 
    * if the download.php is on root 
    */ 
    $filePath = dirname(__FILE__) . '/dl/' . $name . '/' . $version . '.' . $type; 

    // Check if the file exist. 
    if (file_exists($filePath)) { 
     // Add headers 
     header('Cache-Control: public'); 
     header('Content-Description: File Transfer'); 
     header('Content-Disposition: attachment; filename=' . $name . '.' . $type); 
     header('Content-Length: ' . filesize($filePath)); 
     // Read file 
     readfile($filePath); 
    } else { 
     die('File does not exist'); 
    } 
    } else { 
    die('Missing params'); 
    } 
} 
+0

あなたは正しいです、ユーザーがanyfileをダウンロードできるようにするバグがあります...私は今すぐ編集するつもりです。 –

+0

が編集されました。私はいくつかの 'preg_replace'を追加して、場所で意味を持たない文字を置き換え、ファイルを取得する前に' preg_match'チェックを追加しました。 –

+0

はい、あなたは今それを解決しました。一般的な解決策は、明らかに悪意を持っているので、何かにアクセスしようとしている人を拒否することです。 – kba

関連する問題