2009-05-26 23 views
77

Sto cercando un modo semplice per importare/copiare immagini da server remoto a una cartella locale utilizzando PHP. Non ho accesso FTP al server, ma è possibile accedere a tutte le immagini remote tramite HTTP (ad esempio http://www.mydomain.com/myimage.jpg).Copia immagine da server remoto su HTTP

Esempio di utilizzo: un utente desidera aggiungere un'immagine al proprio profilo. L'immagine esiste già sul web e l'utente fornisce un URL diretto. Non desidero collegare l'immagine hotlink ma per importare e servire dal mio dominio.

+0

Non server hanno moduli proxy per questo? – jiggunjer

risposta

142

Se si dispone di PHP5 e il flusso HTTP involucro abilitato sul server, è incredibilmente semplice per copiare in un file locale:

copy('http://somedomain.com/file.jpeg', '/tmp/file.jpeg'); 

Questo si prenderà cura di qualsiasi pipelining ecc che serve. Se è necessario fornire alcuni parametri HTTP, è possibile fornire un terzo parametro "stream context".

+29

Ricordati allow_url_fopen deve essere = on in php.ini –

+3

Il commento allow_url_fopen appena risolto più di un'ora di testa-graffio Grazie, @ mauro.dec –

+2

che vengono doning con gli URL come questo 'http:..! // Desmond .imageshack.us/Himg100/scaled.php? server = 100 & filename = desertoh.jpg & res = crop' ??? – zhilevan

0

Utilizzare una richiesta GET per scaricare l'immagine e salvarla in una directory accessibile dal Web sul server.

Poiché si utilizza PHP, è possibile utilizzare curl per scaricare file dall'altro server.

2

È estremamente semplice utilizzando file_get_contents. Basta fornire l'url come primo parametro.

+1

Questo è bloccato su file system locali su molti host condivisi per motivi di sicurezza.cURL è migliore, più veloce, più forte, ecc ... E di solito è disponibile su quegli host che bloccano fopen su filesystem remoti. – Oli

+0

se cURL è disponibile, sarebbe ancora meglio. vedi cUrl at php.net PatrikAkerstrand

7

Hai avuto su queste quattro possibilità:

  • Remote files. Questo richiede che allow_url_fopen sia abilitato in php.ini, ma è il metodo più semplice.

  • In alternativa è possibile utilizzare cURL se l'installazione di PHP lo supporta. C'è anche un example.

  • E se si vuole davvero farlo manualmente, utilizzare HTTP module.

  • Non provare nemmeno a use sockets directly.

+0

Perché "Non provare nemmeno ad usare le prese direttamente"? (Che è quello che sto usando, https://gist.github.com/0893a7ec908ff508aac6) – Gajus

+0

@Gajus: non stai usando i socket direttamente in quello snippet. Stai utilizzando la capacità di php per aprire file remoti. –

4

Ecco il modo più semplice:

$url = "http://other-site/image.png"; 
$dir = "/my/local/dir/"; 

$rfile = fopen($url, "r"); 
$lfile = fopen($dir . basename($url), "w"); 

while(!feof($url)) fwrite($lfile, fread($rfile, 1), 1); 

fclose($rfile); 
fclose($lfile); 

Ma se si sta facendo un sacco di questo (o i blocchi file host l'accesso ai sistemi remoti), è possibile utilizzare CURL, che è più efficiente, leggermente più veloce e disponibile su host più condivisi.

È inoltre possibile contraffare l'agente utente in modo che assomigli a un desktop anziché a un bot!

$url = "http://other-site/image.png"; 
$dir = "/my/local/dir/"; 
$lfile = fopen($dir . basename($url), "w"); 

$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL, $url); 
curl_setopt($ch, CURLOPT_HEADER, 0); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)'); 
curl_setopt($ch, CURLOPT_FILE, $lfile); 

fclose($lfile); 
curl_close($ch); 

Con entrambe le istanze, si potrebbe voler passare attraverso GD per assicurarsi che sia davvero un'immagine.

+1

Per controllare l'immagine con GD, considera l'esecuzione corretta dopo aver salvato il file: http://www.psoug.org/snippet/Check_if_an_image_exists_GD_364.htm - se torna falso, elimina immediatamente il file. – Oli

+2

Ti sei perso 'curl_exec ($ ch)' prima di 'curl_close ($ ch)', e 'fclose ($ ch)' dovrebbe essere posto alla fine piuttosto che prima di 'curl_close ($ ch)', che significa chiudere il file prima non è stato scritto nulla nel file, quindi otterrai solo un file vuoto. –

0

Dato che hai taggato la tua domanda "php", assumerò il tuo php in esecuzione sul tuo server. La cosa migliore è se controlli il tuo server web, quindi compila cURL in php. Ciò consentirà al tuo server web di effettuare richieste ad altri server web. Questo può essere piuttosto pericoloso dal punto di vista della sicurezza, quindi la maggior parte dei provider di hosting di base non avrà questa opzione abilitata.

Ecco lo php man page on using cURL. Nei commenti puoi trovare un esempio che scarica e file immagine.

Se non si desidera utilizzare libcurl, è possibile codificare qualcosa utilizzando fsockopen. Questo è integrato in PHP (ma può essere disabilitato sul tuo host) e può direttamente leggere e scrivere sui socket. Vedi Examples on the fsockopen man page.

10

PHP ha una funzione built-in file_get_contents(), che legge il contenuto di un file in una stringa.

 
<?php 
//Get the file 
$content = file_get_contents(" http://example.com/image.jpg ");

//Store in the filesystem. $fp = fopen("/location/to/save/image.jpg", "w"); fwrite($fp, $content); fclose($fp); ?>

Se si desidera archiviare il file in un database, utilizzare semplicemente la variabile $ content e non salvare il file su disco.

+2

usando curl è un buon metodo perche 'alcuni server non supportano i file_get_contents per ragioni di sicurezza –

+1

Consigli utili per file piccoli, ma per i file più grandi la memoria php esploderà :( arricciatura non è anche una buona scelta, perché non fa parte di standard di PHP – Radon8472

2

cartella marca e il nome è esempio nemico scarica pad nota aperta e inserire questo codice

cambiano solo http://www.google.com/aa.zip al file e salvarlo in m.php per esempio

chamod il file php per 666 e il download cartella da 777

<?php 
define('BUFSIZ', 4095); 
$url = 'http://www.google.com/aa.zip'; 
$rfile = fopen($url, 'r'); 
$lfile = fopen(basename($url), 'w'); 
while(!feof($rfile)) 
fwrite($lfile, fread($rfile, BUFSIZ), BUFSIZ); 
fclose($rfile); 
fclose($lfile); 
?> 

finalmente dal browser entrare a questi URL http://www.example.com/download/m.php

si vedrà nella cartella di download del file di download dal altro server

grazie

26

uso

$imageString = file_get_contents("http://example.com/image.jpg"); 
$save = file_put_contents('Image/saveto/image.jpg',$imageString); 
+0

grazie amico !! la seconda soluzione sta funzionando .. per me la soluzione migliore non è la mia: p – Rajnish

+4

Un bel consiglio per i file piccoli, ma per i file più grandi la memoria php esploderà :( – Radon8472

0

Ho provato a copiare/scaricare i file remoti utilizzando la funzione di copia behint un proxy, ma copiare si connette direttamente senza proxy.

Ho provato a impostare le mie impostazioni come contesto predefinito e le ho dato come 3. parametro funzione da copiare.

ma sembra che il contesto non viene mai utilizzato, ma readfile o get_headers utilizzare lo stesso successo contesto.

Here's il mio codice:

$url = "http://myserver.com/testfile"; 
$context_opts = array(
    "http" => array(
     "proxy" => "tcp://myProxy:8080", 
     "request_fulluri" => True, 
     "ignore_errors" => true 
    ) 
); 

stream_context_get_default($context_opts); 
print_r(get_headers($url,1)); 

copy($url,$filename, stream_context_create($context_opts)); 

mio server è in esecuzione con:

  • Windows XP SP3
  • Apache 2.2.12 (in esecuzione come servizio)
  • PHP 5.3. 0 (API20090626, TS, VC6) (configurato come modulo apache)

urlfopen è abilitato http e flussi https sono registrati per php

-2

This answer mi ha aiutato a scaricare l'immagine dal server al client.

<a download="original_file.jpg" href="file/path.jpg"> 
    <img src="file/path.jpg" class="img-responsive" width="600" /> 
</a> 
+1

per favore leggi la domanda prima di postare la risposta. – Steeve

0

Per coloro che hanno bisogno di conservare il nome del file e l'estensione originale

$origin = 'http://example.com/image.jpg'; 

$filename = pathinfo($origin, PATHINFO_FILENAME); 
$ext = pathinfo($origin, PATHINFO_EXTENSION); 

$dest = 'myfolder/' . $filename . '.' . $ext; 

copy($origin, $dest); 
Problemi correlati