Salve a tutti,
sto buttando giù questa mini pillola perché leggendo nell'ot di php...ho visto che hanno dato a bubu un link sui mime types...e mi son chiesto...ma a che serve?
ci sono quelli di apache!!!
ok...passo a scrivere ^___^
Allora...
Vi siete mai chiesto come fa apache a dire al browser che quello che state scaricando è un file zip? oppure è un file java? o ancora un rm o un mp3? (come apache qualsiasi altro server web)
Bene...ve lo dico io!
Se aprite la cartellina di apache (nn c'è ne una di default...dipende da dove lo avete installato) ed entrate dentro conf ci saranno svariati file.
Sicuramente riconoscerete httpd.conf che è il file di configurazione di apache!
Li dentro ci sono 2 file, mime.types e magic (senza estensione), che apache usa per poter dire, appunto, al browser che tipo di file si sta scaricando.
Il primo file, mime.types, contiene una lista di Content-Type (Tipi di contenuti) che sono inviati al browser basandosi sull'estenesione del file. Se ad esempio apache deve inviare un file con estensione mp3, apre questo file e legge tutte le righe fin quando non trova l'elemento interessato.
Ad esempio Apache per un mp3 invierà l'header
audio/mpeg
e non
text/html
che è quello di default per le pagine statiche o dinamiche.
(Ad es. in php si può settare un'altro formato, ma di solito si usa quello perché senno nn si vedrebbe nulla nel browser, si cambia solo quando, ad es., php deve inviare una immagine allora in quel caso si invia l'apposito header)
Prendiamo una riga a caso dal file...
codice:
application/xml xml xsl
La prima parte è quello che Apache invia al browser, mentre la seconda indica le estensioni per le quali Apache deve inviare quella stringa. Se notate c'è uno spazio tra le estensioni, serve, appunto, per poter inserire più estensioni, cosi Apache legge prima XML e poi XSL (in questo caso)!
Ricapitolando...Apache quando deve inviare un file al browser legge dal file, che ha precedentemente caricato in memoria, che header deve inviare per questo file.
Se non trova nulla, ad es un'estesione .ciccio Apache non sa cosa sia, allora manda application/octet-stream
Ci sono parecchie linee senza nessuna estensione, purtroppo non so dirvi a che servono, ne ho solo una vaga idea...se lo sapete...postate ))
L'altro file di cui parlavo è particolare...ci sono certi file che hanno un'estenzione che non si trova nel file precedente, allora in questo file si trovano delle regole, ad esempio se i primi 4 byte sono XYZT, e cose simili, del file che deve essere inviato, allora lui prende e fa questi check.
Il file a noi è effettivamente inutile...è meglio nn toccarlo...però è meglio sapere cos'è e a cosa serve!
Praticamente...qua c'è la seguenza
- Richiesta da parte del client al server
- Apache controlla se il file esiste
- Legge l'estensione se esiste
- Cerca l'estensione dentro mime.types
- Se non la trova, applica le regole di ricerca che stanno dentro magic sul contenuto del file per riconoscere qualke formato
- Se non trova neanche nulla allora invia l'header application/octet-stream
Per completare il discorso, come si possono settare i Content-Type in php?
Allora, essendo che Apache (lo fa anche qualsiasi altro server web) specifica questo nell'header noi possiamo semplicemente usare il comando header per inviare quello che ci interessa.
Ad esempio
header("Content-Type: text/plain");
questo farà si che sarà letto il contenuto inviato da apache dal browser come un file di testo
O ad esempio
header("Content-Type: image/jpg");
Questo dirà al browser che state inviando una immagine!
o ad es
header("Content-Type: audio/mpeg");
questo farà si che il browser crea che stiamo inviando un file audio con compressione mpeg!!!
bene...detto questo...ho finito la micro pillola ))
spero di nn aver detto #@$#@$
------Seconda parte--------
Ok...mettiamo caso (e dico ... caso) che dovete ad es non dare il link diretto ai vostri utenti...ma volete che sia uno script php che invii il file al vostro utente.
Allora...vi faccio qui un "ragionamento logico" mi stuffa scrivere tanto codice...
Innanzi tutto dovete sapere che file inviare...questo lo ottenete tramite 1 parametro passato in GET che chiameremo id
Su mysql abbiamo questa tabella che chiamiamo files
fid - INT(10) - UNSIGNED - PRIMARY KEY
filesize - INT(10)
filename - VARCHAR(255)
filetype - VARCHAR(255)
filepath - VARCHAR(255)
(se ad es volete creare la lista dei file scaricabili potete usare il campo filename varchar(255) ma nn lo trattiamo...idem x quanto riguarda il numero di downloads...basta aggiungere downloads int(10))
allora...mettiamo che venga richiamato
http://sito.ext/download.php?id=1
e nella prima riga della tabella (con l'id a 1 [ovvero il campo fid]) ci sta il link ad un file (che può stare sul web o sull'hd del server)
ok...ipotizziamo questo codice
codice:
<?php
// -> CONNESSIONE A MYSQL E SELEZIONE DEL DATABASE <-
// Converto l'id in numero in modo da evitare possibili SQL Injection
$_GET['id'] = (int) $_GET['id'];
// Controllo se l'id passato esiste ed è diverso da zero (false)
if (!$_GET['id']) {
// Se non è stato passato, allora muore ritornando errore
echo "Non è stato specificato il file!
";
// Esce con errore
exit(1);
}
// Esegue la query per estrarre i risultati interessati
$query = mysql_query("
SELECT
filesize, filepath, filetype
FROM
files
WHERE
fid = {$_GET['id']};");
// Estrae i dati dalla query
$result = mysql_fetch_assoc($query);
// Controlla se il file esiste nel database
if (!$result['filepath']) {
// Se no, stampa la scritta
echo "File Inesistente!
";
// Ed esce con errore
exit(1);
}
// Legge il file
$file_content = implode('', file($result['filepath']))
// Invia l'header del formato di file
header("Content-Type: {$result['filetype']}");
// Specifica al browser che il file è un allegato, ovvero
//è da scaricare non da visualizzare
header("Content-Disposition: attachment; filename={$result['filename']}");
// Specifica la lunghezza del file
header("Content-Length: {$result['filesize']}");
// Specifica il tipo di codifica nel trasferimento
header("Content-Transfer-Encoding: binary");
// Invia il file al browser
echo $file_content;
// Esce con successo
exit(0);
I dati della tabella li inserite quando viene fatto l'upload. Altrimenti se non li uploadate dovete modificare
codice:
header('Content-Type: {$result['filetype']}');
in
codice:
header('Content-Type: application/octet-stream');
poi
codice:
$query = mysql_query("
SELECT
filesize, filepath, filetype
FROM
files
WHERE
fid = {$_GET['id']};");
in
codice:
$query = mysql_query("
SELECT
filesize, filepath
FROM
files
WHERE
fid = {$_GET['id']};");
e potete rimuovere il campo filetype dalla tabella
Non sto a spiegare il codice, xche i commenti lo spiegano da solo!