Skrypt download.php nie działa. Proszę o pomoc.

0

Witam.
Mam skrypt
download_file.php, który powoduję pobranie pliku z serwera po jego ID

Nie wiem dlaczego mi nie działa.
Jak nie ma pliku w $dir = "files/$id_user/"; to wyświetla komunkat, że nie ma.
Jak jest to jest puste okno przeglądarki i nic.
Co może być nie tak? Może potrzeba jakiś ustawień .htaccess ?? albo ustawienia na serwerze. Sam nie wiem.
Proszę o pomoc.

<?php session_start();
include ('config.php');                 // plik z konfiguracją strony 
include('core.php');                    // plik z funkcjami

$id = check_input($_GET['idf']);

$sql = mysql_query("SELECT * FROM `gu_files` WHERE `id_file` = '$id'");
while ($rek = mysql_fetch_array($sql)) {
    $id_file = $rek['id_file'];
    $id_user = $rek['id_user'];
    $nazwa_pliku = $rek['nazwa_pliku'];
    $rozszerzenie = $rek['rozszerzenie'];
    $hash = $rek['hash'];
    $size = round($rek['size'] / 1024,1) . ' KB';
}

if ($_SESSION['id'] == $id_user) {
    
    $filename = $hash . '.' . $rozszerzenie;
    $dir = "files/$id_user/";
     
    if(ini_get('zlib.output_compression')){ ini_set('zlib.output_compression', 'Off'); }
     
    $file_extension = strtolower(substr(strrchr($filename,"."),1));
     
    if( $filename == ""){
        echo "<html><title>Document Downloads</title><body>Error: No such file to download.</body></html>";
        exit;
    } elseif (!file_exists($dir.$filename)){
        echo "<html><title>Document Downloads</title><body>Error: File ".$dir.$filename." Not Found</body></html>";
        exit;
    }
     
    switch( $file_extension ){
        case "pdf": $ctype="application/pdf"; break;
        case "exe": $ctype="application/octet-stream"; break;
        case "zip": $ctype="application/zip"; break;
        case "doc": $ctype="application/msword"; break;
        case "docx": $ctype="application/msword"; break;
        case "xls": $ctype="application/vnd.ms-excel"; break;
        case "xlsx": $ctype="application/vnd.ms-excel"; break;
        case "ppt": $ctype="application/vnd.ms-powerpoint"; break;
        case "gif": $ctype="image/gif"; break;
        case "png": $ctype="image/png"; break;
        case "jpeg":
        case "jpg": $ctype="image/jpg"; break;
        default: $ctype="application/force-download";
    }
    header("Pragma: public");
    header("Expires: 0");
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    header("Cache-Control: private",false);
    header("Content-Type: ".$ctype);
    header("Content-Disposition: attachment; filename=\"".basename($nazwa_pliku.".".$rozszerzenie)."\";" );
    header("Content-Transfer-Encoding: binary");
    header("Content-Length: ".filesize($dir.$filename));
    //readfile($dir.$filename);
    header("X-Sendfile: $dir$filename");
    
    exit();
}
else {
    echo "<html><title>Document Downloads</title><body>Error: File ".$dir.$filename." is Not Your!</body></html>";
}
?>
0

Masz na serwerze obsługę nagłówka X-Sendfile? W przypadku Apache będzie to mod_xsendfile.

0
Rev napisał(a):

Masz na serwerze obsługę nagłówka X-Sendfile? W przypadku Apache będzie to mod_xsendfile.

Mam konto na hostingu. Tam mogę chyba dodawać.
Jak powinno to wyglądać aby dodać X-sendfile i gdzie.

Mam Hosting na WebiQ

0

Odkomenduj readfile(), a zakomentuj linijkę pod nim, bo nie skorzystasz na tym hostingu z mechanizmu sendfile raczej.

0
Demonical Monk napisał(a):

Odkomenduj readfile(), a zakomentuj linijkę pod nim, bo nie skorzystasz na tym hostingu z mechanizmu sendfile raczej.

Ok zrobiłem i teraz pobiera, ale zamiast np plik .zip mam na oknie przeglądarki "krzaki" albo jpg to samo, a powinno zip pokazać gdzie zapisać a jpg otworzyć.
Co może być jeszcze?

0
header("Content-Disposition: attachment; filename=\"".basename($nazwa_pliku.".".$rozszerzenie)."\";" );

zamień na:

header('Content-Disposition: attachment; filename="' . basename($nazwa_pliku . '.' . $rozszerzenie) . '"');

Jedyne co tam może przeszkadzać to średnik na samym końcu nagłówka raczej.

0
Demonical Monk napisał(a):
header("Content-Disposition: attachment; filename=\"".basename($nazwa_pliku.".".$rozszerzenie)."\";" );

zamień na:

header('Content-Disposition: attachment; filename="' . basename($nazwa_pliku . '.' . $rozszerzenie) . '"');

Jedyne co tam może przeszkadzać to średnik na samym końcu nagłówka raczej.

zamieniłem i to samo.

Na pewno dobrze pozamieniałeś znaki " na ' ?

Nawet jak całkowicie usunąłem tą linijkę to jest to samo hm. W takim razie ona jest niewykorzystywana.

Funkcja readfile chyba traktuję plik jako dane i czyta jak nazwa mówi a nie wysyła hm

0

spróbuj

$aFile='nazwapliku.txt';
header('Content-Disposition: attachment; filename='.$aFile); 

Content-Disposition daje Ci nazwę pliku, więc dla testów wstaw sobie jakąś nazwę i zobacz, czy pod tą nazwą będzie Ci te pliki ściągać
jeśli masz plik 'doc' to daj rozszerzenie 'doc'
zobaczysz, czy nie ma gdzieś błędu w przetwarzaniu nazwy

0
tomasz256 napisał(a):

spróbuj

$aFile='nazwapliku.txt';
header('Content-Disposition: attachment; filename='.$aFile); 

Content-Disposition daje Ci nazwę pliku, więc dla testów wstaw sobie jakąś nazwę i zobacz, czy pod tą nazwą będzie Ci te pliki ściągać
jeśli masz plik 'doc' to daj rozszerzenie 'doc'
zobaczysz, czy nie ma gdzieś błędu w przetwarzaniu nazwy

wstawiłem, ale nic nie dało. Zachowuje się identycznie jak przedtem.

0
grax napisał(a):

wstawiłem, ale nic nie dało. Zachowuje się identycznie jak przedtem.

to może problem jest w pobieraniu nazwy pliku
poniżej Twojego postu dzek69 dał przykład
ewentualnie sprawdź ten tylko przerób pod swoje zapytanie

if(isset($_POST['file_name'])){
$aFile = $_POST['file_name'];
$filepath = 'admin/files/';
$path = $filepath.$aFile;

 header("Content-Type: application/force-download");
                header("Content-Description: File Transfer");
                header('Content-Disposition: attachment; filename='.$aFile);
                header("Content-Transfer-Encoding: binary");
                header('Content-Length: '.filesize($path));
                readfile($path);

}
?> 
0
tomasz256 napisał(a):
grax napisał(a):

wstawiłem, ale nic nie dało. Zachowuje się identycznie jak przedtem.

to może problem jest w pobieraniu nazwy pliku
poniżej Twojego postu dzek69 dał przykład
ewentualnie sprawdź ten tylko przerób pod swoje zapytanie

if(isset($_POST['file_name'])){
$aFile = $_POST['file_name'];
$filepath = 'admin/files/';
$path = $filepath.$aFile;

 header("Content-Type: application/force-download");
                header("Content-Description: File Transfer");
                header('Content-Disposition: attachment; filename='.$aFile);
                header("Content-Transfer-Encoding: binary");
                header('Content-Length: '.filesize($path));
                readfile($path);

}
?> 

Nie wiem, coś nie idzie. Jak funkcja X-Sendfile nie działa, to co mogę zmienić w skrypcie aby działał identycznie i pobierał plik a nie otwierał go w oknie przeglądarki jako dane ("krzaki") ?

0
header("Content-Type: application/force-download");

To jest najważniejsze. Wrzuć to i będzie pobierać plik.

Wywal za to to:

header("Content-Type: ".$ctype);

i całego tego switcha wyżej

0
dzek69 napisał(a):
header("Content-Type: application/force-download");

To jest najważniejsze. Wrzuć to i będzie pobierać plik.

Wywal za to to:

header("Content-Type: ".$ctype);

i całego tego switcha wyżej

dalej krzaki....ehh nie wiem co to już.

0

pokaz caly kod jaki teraz masz, bo cholera wie co po drodze zmieniales

0
dzek69 napisał(a):

pokaz caly kod jaki teraz masz, bo cholera wie co po drodze zmieniales

Teraz mam na czysto jak na pierwszej stronie, weź wklej cały kod jak powinien być zmieniony i sprawdzę.

0

Aha, czyli zastosowanie się do mojego posta + wklejenie kodu Cię przerasta i czekasz na gotowca? :/

Masz, wypoprawiane na tyle co mi się chciało, jest to sensowniejsze z punktu widzenia protokołu HTTP, pokazałem Ci gdzie masz dziurę, powinno działać.

<?php session_start();
include ('config.php');                 // plik z konfiguracją strony 
include('core.php');                    // plik z funkcjami
 
$id = check_input($_GET['idf']);
 
$sql = mysql_query("SELECT * FROM `gu_files` WHERE `id_file` = '$id'"); // DZIURA SQL INJECTION
while ($rek = mysql_fetch_array($sql)) {
    $id_file = $rek['id_file'];
    $id_user = $rek['id_user'];
    $nazwa_pliku = $rek['nazwa_pliku'];
    $rozszerzenie = $rek['rozszerzenie'];
    $hash = $rek['hash'];
    $size = round($rek['size'] / 1024,1) . ' KB';
}
 
if ($_SESSION['id'] == $id_user) {
 
    $filename = $hash . '.' . $rozszerzenie;
    $dir = "files/$id_user/";
 
    if(ini_get('zlib.output_compression')){ ini_set('zlib.output_compression', 'Off'); }
 
    $file_extension = strtolower(substr(strrchr($filename,"."),1));
 
    if( $filename == ""){
        header($_SERVER['SERVER_PROTOCOL']." 404 Not Found", true, 404);
        echo "<html><title>Document Downloads</title><body>Error: No such file to download.</body></html>";
        exit;
    }
    elseif (!file_exists($dir.$filename)){
        header($_SERVER['SERVER_PROTOCOL']." 404 Not Found", true, 404);
        echo "<html><title>Document Downloads</title><body>Error: File ".$dir.$filename." Not Found</body></html>";
        exit;
    }
    header("Content-Description: File Transfer", true);
    header("Content-Type: application/force-download", true);
    header('Content-Disposition: attachment; filename="'.$nazwa_pliku.'"', true);
    header("Content-Transfer-Encoding: binary", true);
    header("Content-Length: ".filesize($dir.$filename), true);
    readfile($dir.$filename);
    //header("X-Sendfile: $dir$filename");
    exit();
}
else {
    header($_SERVER['SERVER_PROTOCOL']." 403 Forbidden", true, 403);
    echo "<html><title>Document Downloads</title><body>Error: File ".$dir.$filename." is Not Your!</body></html>";
}
?>
0

The script sets the correct MIME type for ZIP files, all other files are sent as octet stream. You may customize that part depending on the type of docs you host.
http://www.richnetapps.com/php-download-script-with-resume-option/

0
dzek69 napisał(a):

Aha, czyli zastosowanie się do mojego posta + wklejenie kodu Cię przerasta i czekasz na gotowca? :/

Masz, wypoprawiane na tyle co mi się chciało, jest to sensowniejsze z punktu widzenia protokołu HTTP, pokazałem Ci gdzie masz dziurę, powinno działać.

<?php session_start();
include ('config.php');                 // plik z konfiguracją strony 
include('core.php');                    // plik z funkcjami
 
$id = check_input($_GET['idf']);
 
$sql = mysql_query("SELECT * FROM `gu_files` WHERE `id_file` = '$id'"); // DZIURA SQL INJECTION
while ($rek = mysql_fetch_array($sql)) {
    $id_file = $rek['id_file'];
    $id_user = $rek['id_user'];
    $nazwa_pliku = $rek['nazwa_pliku'];
    $rozszerzenie = $rek['rozszerzenie'];
    $hash = $rek['hash'];
    $size = round($rek['size'] / 1024,1) . ' KB';
}
 
if ($_SESSION['id'] == $id_user) {
 
    $filename = $hash . '.' . $rozszerzenie;
    $dir = "files/$id_user/";
 
    if(ini_get('zlib.output_compression')){ ini_set('zlib.output_compression', 'Off'); }
 
    $file_extension = strtolower(substr(strrchr($filename,"."),1));
 
    if( $filename == ""){
        header($_SERVER['SERVER_PROTOCOL']." 404 Not Found", true, 404);
        echo "<html><title>Document Downloads</title><body>Error: No such file to download.</body></html>";
        exit;
    }
    elseif (!file_exists($dir.$filename)){
        header($_SERVER['SERVER_PROTOCOL']." 404 Not Found", true, 404);
        echo "<html><title>Document Downloads</title><body>Error: File ".$dir.$filename." Not Found</body></html>";
        exit;
    }
    header("Content-Description: File Transfer", true);
    header("Content-Type: application/force-download", true);
    header('Content-Disposition: attachment; filename="'.$nazwa_pliku.'"', true);
    header("Content-Transfer-Encoding: binary", true);
    header("Content-Length: ".filesize($dir.$filename), true);
    readfile($dir.$filename);
    //header("X-Sendfile: $dir$filename");
    exit();
}
else {
    header($_SERVER['SERVER_PROTOCOL']." 403 Forbidden", true, 403);
    echo "<html><title>Document Downloads</title><body>Error: File ".$dir.$filename." is Not Your!</body></html>";
}
?>

Stosując ten skrypt pobiera poprawnie. Pliki nie są uszkodzone, ale nie ustawia rozszerzeń dla plików. Jak to naprawić?

0

Kolejny programista programujący metodą Kopiego Pasty.

header('Content-Disposition: attachment; filename="'.$nazwa_pliku.".".$rozszerzenie.'"', true);

albo to, jeżeli Twoja kolumna z rozszerzeniem zawiera kropkę

header('Content-Disposition: attachment; filename="'.$nazwa_pliku.$rozszerzenie.'"', true);

EDIT:
"Podoba" mi się to jak składasz kod do kupy z nieskładnych kawałków i kopiujesz nawet linijkę z komentarzem // DZIURA SQL INJECTION (choć ty masz jakiś check_input, możliwe, że to Cię jakoś zabezpiecza)

0
dzek69 napisał(a):

Kolejny programista programujący metodą Kopiego Pasty.

header('Content-Disposition: attachment; filename="'.$nazwa_pliku.".".$rozszerzenie.'"', true);

albo to, jeżeli Twoja kolumna z rozszerzeniem zawiera kropkę

header('Content-Disposition: attachment; filename="'.$nazwa_pliku.$rozszerzenie.'"', true);

EDIT:
"Podoba" mi się to jak składasz kod do kupy z nieskładnych kawałków i kopiujesz nawet linijkę z komentarzem // DZIURA SQL INJECTION (choć ty masz jakiś check_input, możliwe, że to Cię jakoś zabezpiecza)

ale mam to dodać gdzieś czy zastąpić coś.

0

Zrobione! Dzięki! :)

0

ale w drukim pliku, który tworzy kolejke i plik do pobrania mam:

	          //pobieram plik
	          switch($rozszerzenie){
	            case "pdf": $ctype="application/pdf"; break;
	            case "zip": $ctype="application/zip"; break;
	            case "rar": $ctype="application/rar"; break;
	            case "exe": $ctype="application/octet-stream"; break;
	            case "zip": $ctype="application/zip"; break;
	            case "doc": $ctype="application/msword"; break;
	            case "docx": $ctype="application/msword"; break;
	            case "xls": $ctype="application/vnd.ms-excel"; break;
	            case "xlsx": $ctype="application/vnd.ms-excel"; break;
	            case "ppt": $ctype="application/vnd.ms-powerpoint"; break;
	            case "gif": $ctype="image/gif"; break;
	            case "png": $ctype="image/png"; break;
	            case "jpeg": $ctype="image/jpeg"; break;
	            case "jpg": $ctype="image/jpg"; break;
	            default: $ctype="application/force-download";
	          }

	          header("Content-type: $ctype");
	          header("Content-Disposition: attachment; filename=$nazwa_pliku.$rozszerzenie");
		      header("X-Sendfile: $nazwa");
			  
		}

I jest identycznie jak opisywałem w pierwszym, ale zamiana header("Content-Disposition: attachment; filename=$nazwa_pliku.$rozszerzenie"); nie pomaga.

0

Udało mi się:

zmieniłem

header("X-Sendfile: $nazwa");

na

readfile($nazwa);
1

Ujmę to tak: z takiego kodzenia to dzieci nie będzie...

0
Demonical Monk napisał(a):

Ujmę to tak: z takiego kodzenia to dzieci nie będzie...

ja nie jestem programistą tylko jestem administratorem sieci, więc w PHP tylko poprawki itp. Nie zajmuję się typowo programowaniem.

Dzięki za pomoc.

0

Zauważyłem, że pliki ZIP, TXT są ok, ale np jpg i rar dalej po pobraniu się nie otwiera.
Można ustawić jakoś, aby każdy rodzaj pliku bez problemu się pobierał i działał?

0

Podpowie mi kto co zmienić w tym skrypcie , aby działał bez problemu z każdego rodzaju plikiem. Teraz w txt działa i po pobraniu odczytuje, ale ZIP itd po pobraniu wyrzuca, że plik jest uszkodzony. Będę wdzięczny.

0

Otwórz w hexedytorze taki plik zip. możliwe, że znajdziesz tam komunikat z błędem php, który psuje plik

0
dzek69 napisał(a):

Otwórz w hexedytorze taki plik zip. możliwe, że znajdziesz tam komunikat z błędem php, który psuje plik

nic nie moge znaleźć :/ prosze o pomoc. Będę wdzięczny.

Jak powinien ten skrypt wyglądać, aby działał poprawnie z każdym rozszerzeniem i nie psuł plików innych niż txt

0

@dzek69: a może skoro psuje tylko pliki nietekstowe to chodzi o BOM? Wyjaśnij mu ktoś bo nie mam siły dzisiaj...

1 użytkowników online, w tym zalogowanych: 0, gości: 1