Skopiuj obraz ze zdalnego serwera przez HTTP


82

Szukam prostego sposobu na importowanie / kopiowanie obrazów ze zdalnego serwera do lokalnego folderu za pomocą PHP. Nie mam dostępu FTP do serwera, ale wszystkie zdalne obrazy są dostępne przez HTTP (tj. Http://www.mydomain.com/myimage.jpg ).

Przykładowe zastosowanie: użytkownik chce dodać zdjęcie do swojego profilu. Obraz już istnieje w sieci, a użytkownik podaje bezpośredni adres URL. Nie chcę hotlinkować obrazu, ale importować i udostępniać z mojej domeny.


Czy serwery nie mają do tego modułów proxy?
jiggunjer

Odpowiedzi:


154

Jeśli masz PHP5 i włączone opakowanie strumienia HTTP na swoim serwerze, bardzo łatwo jest skopiować je do pliku lokalnego:

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

To zajmie się wszelkimi potrzebnymi rurociągami itp. Jeśli chcesz podać niektóre parametry HTTP, możesz podać trzeci parametr „kontekst strumienia”.


33
Pamiętaj, że allow_url_fopen musi być włączone w php.ini.
mauro.dec

3
Komentarz allow_url_fopen właśnie rozwiązał ponad godzinę drapania się po głowie. Dzięki, @ mauro.dec!
Michael Stalker

2
co przekazujesz z takimi adresami URL http://desmond.imageshack.us/Himg100/scaled.php?server=100&filename=desertoh.jpg&res=crop ?
Yuseferi,

Dzięki za tę odpowiedź - chyba już prawie na miejscu! Kiedy mówisz „/tmp/file.jpg” - do czego to się odnosi? ROOT serwera WWW ... (np .: / var / www / vhosts itp.) Lub katalog główny witryny: / httpdocs / ... ?? Nie widzę pojawiających się plików, a opcja url-fopen jest ustawiona na ON. !!
itsricky

1
Nie używaj protokołu https, po prostu http
edCoder

31

posługiwać się

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

dzięki!! drugie rozwiązanie działa .. top ze wszystkich rozwiązanie nie działa dla mnie: p
Rajnish

4
Dobra

10

PHP ma wbudowaną funkcję file_get_contents (), która wczytuje zawartość pliku do łańcucha.

<?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); ?>

Jeśli chcesz przechowywać plik w bazie danych, po prostu użyj zmiennej $ content i nie zapisuj pliku na dysku.


2
używanie curl jest dobrą metodą, ponieważ niektórzy faceci od serwerów nie obsługują file_get_contents ze względów bezpieczeństwa
Rinto George,

1
Dobra wskazówka dla małych plików, ale dla większych plików pamięć php eksploduje :( curl również nie jest dobrym wyborem, ponieważ nie jest częścią standardowego php
Radon8472

8

Masz około czterech możliwości:


Dlaczego pojawia się komunikat „Nawet nie próbuj używać gniazd bezpośrednio”? (Którego właśnie używam, gist.github.com/0893a7ec908ff508aac6 )
Gajus

@Gajus: Nie używasz gniazd bezpośrednio w tym fragmencie. Używasz możliwości php do otwierania plików zdalnych.
Georg Schölly

4

Oto najbardziej podstawowy sposób:

$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);

Ale jeśli robisz to dużo, dużo (lub twój host blokuje dostęp do plików do systemów zdalnych), rozważ użycie CURL, który jest bardziej wydajny, nieco szybszy i dostępny na bardziej współdzielonych hostach.

Możesz również sfałszować klienta użytkownika, aby wyglądał jak komputer stacjonarny, a nie 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);

W obu przypadkach możesz chcieć przekazać to przez GD, aby upewnić się, że to naprawdę jest obraz.


1
Aby sprawdzić obraz za pomocą GD, rozważ uruchomienie tego zaraz po zapisaniu pliku: psoug.org/snippet/Check_if_an_image_exists_GD_364.htm - jeśli okaże się fałszywy, natychmiast usuń plik.
Oli

4
Tęskniłeś curl_exec($ch)wcześniej curl_close($ch)i fclose($ch)powinien być umieszczony raczej na końcu niż wcześniej curl_close($ch), co oznacza zamknięcie pliku, zanim nic nie zostanie zapisane w pliku, dlatego otrzymasz tylko pusty plik.
Hendra Uzia

2

Jest to niezwykle proste przy użyciu file_get_contents . Po prostu podaj adres URL jako pierwszy parametr.


1
Jest to ograniczone do lokalnych systemów plików na wielu współdzielonych hostach ze względów bezpieczeństwa. cURL jest lepszy, szybszy, silniejszy itd. I zwykle dostępny na tych hostach, które blokują fopen na zdalnych systemach plików.
Oli

jeśli cURL jest dostępny, byłoby jeszcze lepiej. zobacz <a href=" se2.php.net/curl"> cUrl na php.net </a>
PatrikAkerstrand

2

stwórz folder i nazwij go wrogiem przykład pobierz otwarty notes i wstaw ten kod

zmień tylko adres http://www.google.com/aa.zip na swój plik i zapisz go na przykład w m.php

chamod plik php na 666, a folder pobierz na 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);
?>

na koniec z przeglądarki wprowadź adres URL http://www.example.com/download/m.php

w folderze pobierania zobaczysz plik pobrany z innego serwera

dzięki


0

Użyj żądania GET, aby pobrać obraz i zapisać go w katalogu dostępnym w sieci na serwerze.

Ponieważ używasz PHP, możesz użyć curldo pobierania plików z innego serwera.


0

Ponieważ oznaczyłeś pytanie jako „php”, zakładam, że masz uruchomione php na serwerze. Najlepiej jest, jeśli kontrolujesz swój własny serwer WWW, a następnie skompiluj cURL do php. Umożliwi to serwerowi WWW wysyłanie żądań do innych serwerów WWW. Może to być dość niebezpieczne z punktu widzenia bezpieczeństwa, więc większość podstawowych dostawców usług hostingowych nie ma włączonej tej opcji.

Oto strona podręcznika php o używaniu cURL . W komentarzach można znaleźć przykład pobierania i plik obrazu.

Jeśli nie chcesz używać libcurl, możesz coś zakodować za pomocą fsockopen. Jest to wbudowane w php (ale może być wyłączone na twoim hoście) i może bezpośrednio czytać i zapisywać w gniazdach. Zobacz Przykłady na stronie podręcznika fsockopen .


0

Dla tych, którzy chcą zachować oryginalną nazwę pliku i rozszerzenie

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

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

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

copy($origin, $dest);

-5

Ta odpowiedź pomogła mi pobrać obraz z serwera na klienta.

<a download="original_file.jpg" href="file/path.jpg">
  <img src="file/path.jpg" class="img-responsive" width="600" />
</a>
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.