Uzak Sunucudan Görüntüyü HTTP Üzerinden Kopyala


83

Resimleri uzak sunucudan PHP kullanarak yerel bir klasöre aktarmak / kopyalamak için basit bir yol arıyorum. Sunucuya FTP erişimim yok, ancak tüm uzak görüntülere HTTP (yani http://www.mydomain.com/myimage.jpg ) aracılığıyla erişilebilir .

Örnek kullanım: Bir kullanıcı profiline bir resim eklemek istiyor. Görüntü web'de zaten var ve kullanıcı doğrudan bir URL sağlıyor. Görüntüyü hotlink yapmak değil, etki alanımdan içe aktarmak ve sunmak istiyorum.


Sunucuların bunun için proxy modülleri yok mu?
jiggunjer

Yanıtlar:


155

Sunucunuzda PHP5 ve HTTP akış sarmalayıcı etkinse, yerel bir dosyaya kopyalamak inanılmaz derecede kolaydır:

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

Bu, gerekli olan herhangi bir boru hattı vb. İle ilgilenecektir. Bazı HTTP parametreleri sağlamanız gerekiyorsa, sağlayabileceğiniz üçüncü bir 'akış bağlamı' parametresi vardır.


33
Php.ini içinde allow_url_fopen = açık olması gerektiğini unutmayın.
mauro.dec

3
Allow_url_fopen yorumu, bir saatten fazla süren kafa karıştırıcılıkla çözüldü. Teşekkürler @ mauro.dec!
Michael Stalker

2
bunun gibi URL'lerle neler bağışlanıyor http://desmond.imageshack.us/Himg100/scaled.php?server=100&filename=desertoh.jpg&res=crop ???
Yuseferi

Bu cevap için teşekkürler - Sanırım neredeyse geldim! '/Tmp/file.jpg' dediğinizde - neye göre bu? Web sunucusunun KÖKÜ ... (örneğin: / var / www / vhosts vb.) Veya web sitesinin kökü: / httpdocs / ... ?? Dosyaların göründüğünü göremiyorum ve url-fopen ayarım AÇIK. !!
itsricky

1
Https kullanmayın, sadece http
edCoder

31

kullanım

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

teşekkürler dostum!! ikinci çözüm çalışıyor .. her şeyden önce çözüm benim için işe yaramıyor: p
Rajnish

4
Küçük dosyalar için güzel bir ipucu, ancak daha büyük dosyalar için php belleği patlayacak :(
Radon8472

10

PHP, bir dosyanın içeriğini bir dizge olarak okuyan yerleşik bir file_get_contents () işlevine sahiptir.

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

Dosyayı bir veritabanında saklamak istiyorsanız, $ content değişkenini kullanın ve dosyayı diske kaydetmeyin.


2
curl kullanmak iyi bir yöntemdir çünkü bazı sunucular güvenlik nedenleriyle file_get_contents'ı desteklemiyor
Rinto George

1
Küçük dosyalar için güzel bir ipucu, ancak daha büyük dosyalar için php belleği patlayacak :( curl de iyi bir seçim değil, çünkü standart
php'nin bir

8

Şu dört olasılığa sahipsiniz:

  • Uzak dosyalar . Bunun allow_url_fopenphp.ini'de etkinleştirilmesi gerekiyor , ancak en kolay yöntem bu.

  • Alternatif olarak , PHP kurulumunuz destekliyorsa cURL kullanabilirsiniz . Bir örnek bile var .

  • Ve bunu gerçekten manuel olarak yapmak istiyorsanız, HTTP modülünü kullanın .

  • Doğrudan priz kullanmayı denemeyin bile .


Neden "Soketleri doğrudan kullanmayı denemeyin bile." (Ben de bunu kullanıyorum, gist.github.com/0893a7ec908ff508aac6 )
Gajus

@Gajus: O pasajda doğrudan soket kullanmıyorsunuz. Uzak dosyaları açmak için php yeteneğini kullanıyorsunuz.
Georg Schölly

4

İşte en temel yol:

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

Ancak bunu çok ve çok yapıyorsanız (veya ana makineniz uzak sistemlere dosya erişimini engelliyorsanız), daha verimli, biraz daha hızlı ve daha fazla paylaşılan ana bilgisayarda kullanılabilen CURL kullanmayı düşünün.

Ayrıca kullanıcı aracısını bir bottan ziyade bir masaüstü gibi görünecek şekilde taklit edebilirsiniz!

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

Her iki durumda da, gerçekten bir resim olduğundan emin olmak için GD'den geçirmek isteyebilirsiniz.


1
Görüntüyü GD ile kontrol etmek için, dosyayı kaydettikten hemen sonra bunu çalıştırmayı düşünün: psoug.org/snippet/Check_if_an_image_exists_GD_364.htm - yanlış gelirse, dosyayı hemen silin.
Oli

4
Daha curl_exec($ch)önce kaçırdınız curl_close($ch)ve fclose($ch)öncekinden ziyade sonuna yerleştirilmelisiniz curl_close($ch), bu, dosyaya hiçbir şey yazılmadan dosyayı kapatın, bu nedenle yalnızca boş bir dosya alırsınız.
Hendra Uzia


2

klasör oluşturun ve örnek olarak adlandırın not defterini açın ve bu kodu ekleyin

yalnızca http://www.google.com/aa.zip dosyanızı dosyanızla değiştirin ve örneğin m.php olarak kaydedin

php dosyasını 666'ya ve klasör 777'ye indir

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

son olarak tarayıcınızdan şu URL'yi girin http://www.example.com/download/m.php

indirme klasöründe diğer sunucudan dosya indirildiğini göreceksiniz

Teşekkürler


0

Görüntüyü indirmek ve sunucunuzdaki web'den erişilebilir bir dizine kaydetmek için bir GET isteği kullanın.

PHP kullanırken curl, diğer sunucudan dosya indirmek için kullanabilirsiniz .


0

Sorunuzu 'php' olarak etiketlediğiniz için, sunucunuzda php çalıştırdığınızı varsayacağım. En iyi bahsiniz, kendi web sunucunuzu kontrol ediyorsanız, cURL'yi php'ye derlemenizdir. Bu, web sunucunuzun diğer web sunucularına istekte bulunmasına izin verecektir. Bu, güvenlik açısından oldukça tehlikeli olabilir, bu nedenle çoğu temel web barındırma sağlayıcısı bu seçeneği etkinleştirmez.

İşte cURL kullanımıyla ilgili php man sayfası . Yorumlarda, indirilen ve resim dosyası olan bir örnek bulabilirsiniz.

Libcurl kullanmak istemiyorsanız, fsockopen kullanarak bir şeyler kodlayabilirsiniz. Bu php'de yerleşiktir (ancak ana makinenizde devre dışı bırakılabilir) ve doğrudan soketleri okuyabilir ve bunlara yazabilir. Fsockopen man sayfasındaki Örneklere bakın .


0

Orijinal dosya adını ve uzantıyı korumaya ihtiyaç duyanlar için

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

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

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

copy($origin, $dest);

-5

Bu cevap , resmi sunucudan istemci tarafına indirmeme yardımcı oldu.

<a download="original_file.jpg" href="file/path.jpg">
  <img src="file/path.jpg" class="img-responsive" width="600" />
</a>
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.