2012-07-15 23 views
6

Se faccio l'url per un file zip il href di un collegamento e clicco sul link, il mio file zip viene scaricato e aprendolo ottiene il contenuto come mi aspetto.L'apertura del file zip scaricato crea un file cpgz?

Ecco che HTML:

<a href="http://mysite.com/uploads/my-archive.zip">download zip</a> 

Il problema è che vorrei il collegamento a punto per la mia applicazione in modo tale che ho potuto determinare se l'utente è autorizzato ad accedere a questo file zip.

così Vorrei che il mio HTML essere questo:

<a href="/canDownload">download zip</a> 

e il mio PHP per la pagina /canDownload:

//business logic to determine if user can download 

if($yesCanDownload){ 

$archive='https://mysite.com/uploads/my-archive.zip'; 
header("Content-Type: application/zip"); 
header("Content-Disposition: attachment; filename=".basename($archive)); 
header("Content-Length: ".filesize($archive)); 
ob_clean(); 
flush(); 
echo readfile("$archive"); 
} 

Quindi, penso che il problema ha a che fare con il codice header() ma ho provato un sacco di cose relative a questo sulla base di vari suggerimenti su Google e altri SO e nessuno funziona.

Se si risponde alla mia domanda, è probabile si può rispondere a questa domanda anche: Zipped file with PHP results in cpgz file after extraction

+0

Che cos'è un file * cpgz *? – hakre

+0

Per semplicità ho fatto riferimento ad esso come un file cpgz, ma in realtà è un file 'xxx.zip.cpgz'. Da Google, penso che sia una chiusura lampo del file zip. Sembra che sto scaricando un file il cui contenuto non può essere letto forse perché le istruzioni header() sono già state determinate da/canDownload? –

+0

Prova a cambiare l'estensione in .txt e controlla se c'è del testo semplice. – jprofitt

risposta

1

Ok, ho risposto alla mia domanda.

Il problema principale, che in origine non ho chiarito, era che il file non si trovava sul mio server applicazioni. Era in un secchio di Amazon AWS s3. Questo è il motivo per cui ho usato un url completo nella mia domanda, http://mysite... e non solo un percorso file sul server. Come si scopre, fopen() può aprire gli URL (tutti gli "oggetti" bucket s3, i file a.k.a., hanno gli URL), quindi è quello che ho fatto.

Ecco il mio codice finale:

$zip= "http://mysite.com/uploads/my-archive.zip"; // my Amazon AWS s3 url 
header("Content-Type: archive/zip"); // works with "application/zip" too 
header("Content-Disposition: attachment; filename='my-archive.zip"); // what you want to call the downloaded zip file, can be different from what is in the s3 bucket 
$zip = fopen($zip,"r"); // open the zip file 
echo fpassthru($zip); // deliver the zip file 
exit(); //non-essential 
3

La documentazione di PHP per readfile dice che sarà in uscita il contenuto di un file e tornare un int.

Così il vostro codice, echo readfile("$archive");, risuonerà $archive (a proposito, le virgolette sono prive di significato qui; è necessario rimuoverli), quindi l'uscita int che viene restituito. Ovvero, la riga deve essere: readfile($archive);

Inoltre, si dovrebbe utilizzare un percorso locale (non un collegamento http: //) all'archivio.

Complessivamente:

if($yesCanDownload){ 
    $archive='/path/to/my-archive.zip'; 
    header("Content-Type: application/zip"); 
    header("Content-Disposition: attachment; filename=".basename($archive)); 
    header("Content-Length: ".filesize($archive)); 
    ob_clean(); 
    flush(); 
    readfile($archive); 
} 

Infine, se questo non funziona, assicurarsi che filesize($archive) sta tornando la lunghezza precisa del file.

+0

grazie a @cegfault per il tuo aiuto, ho bisogno di usare un 'http: //' perché il file zip è effettivamente su un server remoto. Quindi, sì, ora che sto realizzando, readfile() non ha senso in questo contesto. Hai altri suggerimenti? –

+0

come stai caricando il file remoto? questo è probabilmente il problema. Ho visto che potresti usare un secchio S3.Ho avuto un problema su Rackspace CloudFiles in cui il file stava anche leggendo le intestazioni e c'erano alcuni CRLF extra ("\ r \ n") nel file. assicurati di chiamare correttamente il file: prova prima con un file .txt o qualcosa del genere. Se hai ancora problemi, inserisci il tuo codice S3 reale (rimuovi il nome utente/apikey/etc), perché potrebbe essere dove si trova il problema. – cegfault

+0

hi @cegfault, al momento non ho alcun codice S3 nel mio file php '/ canDownload'. Quello che ho è esattamente ciò che vedi. Sto solo imparando l'S3 SDK. Vedo che c'è una chiamata [getObject] (http://docs.amazonwebservices.com/AWSSDKforPHP/latest/#m=AmazonS3/get_object) ma non sono sicuro di come adattarla alla mia situazione. Non sono un noob totale in quanto posso caricare sul mio S3, ma ancora un po 'confuso, potresti essere in grado di consigliarlo? –

1

si sta passando l'URL readfile() come:

$archive = 'https://mysite.com/uploads/my-archive.zip'; 

Mentre si dovrebbe passare il percorso sul server, ad esempio:

$archive = '/uploads/my-archive.zip'; 

Supponendo che il file si trova nella cartella di caricamento .

inoltre provare le seguenti intestazioni:

header("Content-type: application/octet-stream"); 
header("Content-disposition: attachment; filename=file.zip"); 
+0

Lo zip è in realtà in un bucket S3 e non nella mia app. La mia domanda sembrava abbastanza complicata, ecco perché avevo bisogno di includere l'URL completo. –

5

La risposta nel mio caso era che ci fosse una linea di uscita essendo vuota prima readfile().

così ho aggiunto:

ob_end_clean();

readfile ($ nome file);

Ma probabilmente dovresti cercare il punto in cui questa linea viene emessa nel tuo codice.

+0

Brillante, grazie. – BarryMode

+0

Perfetto, grazie – SOSTheBlack

2

Un'altra possibile risposta, ho trovato Dopo molte ricerche, ho scoperto che i due possibili ragioni di un *.zip "decompressione" ad un *.zip.cpgz sono:

  1. il file *.zip è danneggiato
  2. il "decomprimere" strumento utilizzato non può maniglia> file 2GB

essendo un utente Mac, la seconda ragione è stata la causa per il mio problema decomprimere il file: lo strumento standard di Mac OS è Archive Utility e apparentemente non è in grado di gestire file da 2 GB. (Il file in questione per me era un'immagine disco zippata da 4 GB raspbian.)

Quello che ho finito è stato utilizzare una macchina virtuale Debian, già esistente in Virtual Box sul mio Mac. unzip 6.0 su Debian 8.2 non ha avuto problemi a decomprimere l'archivio.

Problemi correlati