Newsgroup: it.comp.www.php
Titolo: download di file

<?php
echo 'parte iniziale';
 
if ($_GET['p'] = 'prova'){
	header('Content-Type: application/binary');
	echo file_get_contents('test.txt', FILE_USE_INCLUDE_PATH);
}
?>
 
come vedete, dopo la visualizzazione della scritta "parte iniziale", se 
nell'url è stato specificato il parametro (?p=prova), viene scaricato il 
file "test.txt".
Il problema è che tale file, una volta scaricato, oltre al contenuto 
originare, include anche la scritta "parte iniziale".
 
Si può evitare questo inconveniente?

 Si può evitare questo inconveniente?
 
Certo, togliendo l'echo all'inizio dello script :-)
 
Ciao.
 
-- 
Pubblicita' regresso: 
http://www.ferrero.org
 
** Per scrivermi in mail, sostituire nutella con ferrero...
** To contact me by email, change nutella to ferrero...
 

 	header('Content-Type: application/binary');
 
Questo non dovrebbe funzionare, non puoi mandare header dopo aver 
cominciato l'output, a meno che non ci sia il buffering (e non ne sono 
nemmeno sicuro).
Se vuoi scaricare un file non è il Content-Type che ti interessa, ma il 
Content-Disposition.

 Si può evitare questo inconveniente?
 
O fai visualizzare qualcosa sul browser o fai scaricare un file, che 
sappia io non e' possibile fare entrambe nella stessa esecuzione del 
file php.
 
Ciao
-- 
MMM

 Content-Disposition.
 
in effetti le risposte che avete dato, me le aspettavo.
Cmq leggo "Content-Disposition", cosa sarebbe?
Vabè, inizio a documentarmi!!!

 Vabè, inizio a documentarmi!!!
 
ad ogni modo mi sembra di capire che per il download bisogna per forza 
creare un file php separato, giusto?
Pero come faccio a passare a tale file php, il nome del file da scaricare?
Potrei passarlo come parametro (?fn=etc/virtualroot/test/prova.txt), 
però per motivi di sicurezza, non voglio che nell'URL il nome compaia in 
chiaro.
Ho pensato di usare il metodo $_POST, ma bisognerebbe creare una form 
con apposito pulsante....
Insomma penso che una soluzione ci sia, però... suggerimenti?

 con apposito pulsante....
 
Non glielo passi.
GET o POST sono comunque dati che arrivano dal client, quindi 
inaffidabili.
 
Passa un codice (un id di database, un'indice di array in sessione, ecc.) 
che associ lato server al file da scaricare.
 
Bye.
 

 che associ lato server al file da scaricare.
 
infatti, intuivo che era l'unico sistema.
grazie di tutto

 creare un file php separato, giusto?
 
Separato da cosa?
Puoi usare un unico file php per stampare output e fornire un file da 
scaricare, l'importante è che non faccia tutte e due le operazioni nella 
stessa esecuzione.

 stessa esecuzione.
 
e se il php in questione viene incluso da un altro php, e quest'ultimo 
ha già prodotto un output prima dell'inclusione?

 ha già prodotto un output prima dell'inclusione?
 
Rimane il punto: non puoi produrre output per la pagina e poi cambiare 
gli header.
 
Se succede quanto sopra sposta la logica prima nell'esecuzione: o scrivi 
a video o dai il file da scaricare.

 a video o dai il file da scaricare.
 
dunque ricapitolando, abbiamo due file:
 
- index.php (che dopo un eventuale ed indesiderato output iniziale, 
include il file 'download.php')
- download.php (che contiene solo le istruzioni specifiche per il 
download del file specificato tramite il parametro "?fn=...")
 
A questo punto penso che basterebbe annullare l'"eventuale" output 
iniziale cambiando pagina, cioè facendo il redirect forzato verso 
'downlaod.php', al cui indirizzo verrà aggiunto anche il parametro "?fn=".
 
Il problema è però ricavare l'indirizzo http (non quello assoluto) di 
tale file.
 
Per il momento vorrei fare così:
 
//ottengo l'url del file 'download.php'
$urlFn = substr(__FILE__, strlen($_SERVER['DOCUMENT_ROOT']));
 
$a = isset($_GET['fn']); //è stato specificato il file da scaricare
$b = $urlFn != $_SERVER['PHP_SELF']; //il browser non sta visualizzando 
il file specifico per il download (download.php)
 
//quindi se è stato specificato il file da scaricare,
//ma il browser non sta visualizzando il file specifico per il download...
if ($a && $b) {
	//...viene fatto il redirect verso il file specifico
	$url = $urlFn . '?fn=' . $_GET['fn'];
	header('location:' . $url);
}
 
Naturalmente avrei potuto usare semplicemente $_SERVER['PHP_SELF']:
 
$urlFn = $_SERVER['PHP_SELF'];
 
ma verrebbe restituito il nome del file principale (quello che potrebbe 
generare accidentalmente un output preventivo), non di quello specifico.
Possibile che non esista una funzione ad hoc, per conoscere l'url del 
file incluso?
 
Comunque ancora devo testare il tutto, anche se temo che dopo aver 
avviato il download, bisogna trovare il sistema per tornare alla pagina 
principale (index.php)...

 download del file specificato tramite il parametro "?fn=...")
 
No. index.php NON include download.php
 
Devi usare HTML o Javascript per richiamare download.php, per esempio
 
index.php:
 
<html>
 
<head>
 
 <meta http-equiv="REFRESH" content="0;url=
http://tuosito/
 
download.php?...">
 
</head>
 
<body>
 
 Scrivi quello che devi scrivere
 
</body>
 
</html>
 
 
Avrai DUE richieste al webserver: una per index.php e una per 
download.php, completamente indipendenti.
 
Bye.
 

 download.php, completamente indipendenti.
 
ma davvero? ;)
Scherzi a parte, non ci ho capito granchè...

 Scherzi a parte, non ci ho capito granchè...
 
Fondamentalmente: per ogni richiesta HTTP puoi trasmettere un solo 
MIMEtype. O trasmetti text/html, o trasmetti image/jpeg. Non puoi 
trasmetterli tutti e due.
 
Bye.