2012-06-24 15 views
6

Sto utilizzando query di database in PHP per recuperare un file binario. Ma quando sto provando a forzare il download, l'intestazione ('Content-type: application/octet-stream') riga causa file 0 byte. Senza quella linea posso scaricare il file con il contenuto completo. È un file binario che è sicuro, quindi non riesco a capire perché quella linea causa il problema. Il codice:intestazione ('Content-type: application/octet-stream') causa file 0 byte

$result = mysql_query("SELECT data FROM stored_file WHERE file_name = '$q'"); 

while($row = mysql_fetch_array($result)) 
{ 
    $file = $row['data']; 
} 


    header('Content-disposition: attachment; filename='.$q); 
    header('Content-type: application/octet-stream'); 
    header('Content-Length: '.filesize($file)); 
    header("Pragma: no-cache"); 
    header("Expires: 0"); 
    echo $file; 

Qualche idea? Grazie.

+2

Commenta tutte le intestazioni; abilita la segnalazione degli errori ed esegui il tuo script. Pubblica eventuali messaggi di errore. –

+0

Non ho ricevuto messaggi di errore. – Akos

+0

Anche se sembra che filesize ($ file) non restituisca nulla. – Akos

risposta

5

filesize() non restituirà un valore significativo.

si dispone di dati binari in $file, non un vero nome come richiesto come primo parametro. Quindi si otterrebbe un errore. (Attiva error_reporting! Non vedi gli errori, e non averli sono due cose diverse.)

Quindi quello che vuoi usare è strlen($file), non filesize().

Btw, application/octet-stream o altri fill-in non servono per forzare i download. È l'intestazione Content-Disposition: che è la più cruciale in tal senso. Hai ancora il permesso di inviare il tipo MIME corretto.

+0

Grazie mille! È fondamentale utilizzare l'intestazione Content-Length? Informazioni sulla segnalazione degli errori. Ho abilitato il php.ini e anche nel codice: ini_set ('display_errors', 1); error_reporting (E_ALL); quindi non capisco perché non ho ricevuto i messaggi di errore. – Akos

+0

Come ultima risorsa, prova 'set_error_handler (" var_dump ");' in cima allo script. L'intestazione Content-Length: è ampiamente considerata secondaria, di solito funziona senza. I metadati del payload sono richiesti solo se si implementa anche Range: headers ecc. Come farebbe un server web. – mario

1

Dall'esame della query, suppongo che in $row['data'] siano memorizzati i dati binari. Per impostare l'intestazione Content-Length corretta devi usare mb_strlen($row['data']);. Se nessun supporto multibyte (le funzioni mb_) è attivato sulla macchina, utilizzare strlen(). Ma attenzione, questo potrebbe causare risultati akward perché i dati binari potrebbero effettivamente contenere la sequenza di byte EOF e restituire una lunghezza troppo breve. Con la funzione mb_strlen sei sul lato di salvataggio.

Problemi correlati