Web-Bild lokal speichern
frankx
- php
Hellihello
kann ich mit php und httprequest ein jpg, png, gif von example.com/test.gif lokal apseichern? Oder lieber per file_get_contents()? Geht um eine lokale Anwendung (speichern von Produktbildern fürs kleinhäckseln und zurück auf eigenen Server).
Dank und Gruß,
frankx
Moin!
kann ich mit php und httprequest ein jpg, png, gif von example.com/test.gif lokal apseichern? Oder lieber per file_get_contents()? Geht um eine lokale Anwendung (speichern von Produktbildern fürs kleinhäckseln und zurück auf eigenen Server).
Kannst du (wenn allow_url_fopen eingeschaltet ist, geht viel).
- Sven Rautenberg
n'abend,
Kannst du (wenn allow_url_fopen eingeschaltet ist, geht viel).
und ist das (sinnvollerweise) nicht eingeschaltet, kannst du dir mit curl, oder fsockopen helfen, um die datei via HTTP herunterzuladen. Ersteres ist nicht überall verfügbar, letzteres erfordert Grundkenntnisse in Sachen HTTP.
weiterhin schönen abend...
Hellihello,
dank für die Antworten.
n'abend,
Kannst du (wenn allow_url_fopen eingeschaltet ist, geht viel).
und ist das (sinnvollerweise) nicht eingeschaltet, kannst du dir mit curl, oder fsockopen helfen, um die datei via HTTP herunterzuladen. Ersteres ist nicht überall verfügbar, letzteres erfordert Grundkenntnisse in Sachen HTTP.
Alles kann eingeschaltet werden, ist ja mein Heimrechner. Mit HTTP hatte ich auch schonmal Seiten mit PHP geöffnet/angefragt. Aber wie sage ich denn speicher Bild example.com/test.gif unter c:\test.gif bzw. /home/me/test.gif.
Dank und Gruß,
frankx
Hello,
Aber wie sage ich denn speicher Bild example.com/test.gif unter c:\test.gif bzw. /home/me/test.gif.
<?php ### fetch_file.php ###
$contents = file_get_contents('http://example.com/test.gif');
if ($contents) { file_put_contents('/home/me/test.gif'); }
?>
Das war's schon. Natürlich nur die Billigvariante. Ohne jegliche Sicherheit bezüglich Race Conditions, bereits vorhandenem Ziel, Schreibrechten usw. Nur, ob überhaupt gelesen wurde, ist abgefangen.
Harzliche Grüße vom Berg
http://bergpost.annerschbarrich.de
Tom
Hello,
Aber wie sage ich denn speicher Bild example.com/test.gif unter c:\test.gif bzw. /home/me/test.gif.
<?php ### fetch_file.php ###
$contents = file_get_contents('http://example.com/test.gif');
if ($contents) { file_put_contents('/home/me/test.gif', $contents); }
?>
Reintun sollte man auch 'was in das Ausgabefile :-)
Harzliche Grüße vom Berg
http://bergpost.annerschbarrich.de
Tom
Hellihello Tom,
Aber wie sage ich denn speicher Bild example.com/test.gif unter c:\test.gif bzw. /home/me/test.gif.
<?php ### fetch_file.php ###
$contents = file_get_contents('http://example.com/test.gif');
if ($contents) { file_put_contents('/home/me/test.gif', $contents); }?>
Merci, hätte ich doch selbst drauf kommen sollen. Nicht immer funzt das mit der vorauseilenden Antwort. War vielleicht Hirnträgheit. Geht auf jeden Fall und die Fehlerkontrolle ist mir schon klar, das krieg ich schon hin. Ist ja keine Anwendung für alle Fälle sondern wird nur sehr eingeschränkt genutzt. Da die Bilder ja auch überall im Netz rumstehen, ist der Prozess auch immer leicht replizierbar, im Grunde aber immer nur einmal nötig. Aber das lässt sich ja hübsch testen bzw. schon im Framework abfangen u.U..
Reintun sollte man auch 'was in das Ausgabefile :-)
Habisch auch (;-).
Dank und Gruß,
frankx
n'abend,
Alles kann eingeschaltet werden, ist ja mein Heimrechner. Mit HTTP hatte ich auch schonmal Seiten mit PHP geöffnet/angefragt. Aber wie sage ich denn speicher Bild example.com/test.gif unter c:\test.gif bzw. /home/me/test.gif.
Tom hat dir ja bereits eine Lösung mit file_get_contents() geliefert. Der Komplettheit halber hier noch eine Variante, der die Direktive allow_url_fopen egal ist [1]:
$host = 'hilfe.selfhtml.org';
$file = '/gib/mir/hilfe.png';
// Verbindung zum Webserver aufbauen
$fh = fsockopen( $host );
// Anfrage für http://hilfe.selfhtml.org/gib/mir/hilfe.png absetzen
fputs( $fh, 'GET '. $file . " HTTP/1.1\r\n" );
fputs( $fh, 'Host: '. $host . "\r\n" );
fputs( $fh, "Connection: close\r\n\r\n" );
// Antwort vom Webserver lesen
$response = '';
while( !feof( $fh ) )
$response .= fread( $fh, 8192 );
// Verbindung schliessen
fclose( $fh );
// header von content separieren
$response = explode( "\r\n\r\n", $response, 1 );
$header = explode( "\r\n", $response[0] );
$content = isset( $response[1] ) ? $response[1] : null;
// an dieser Stelle könnte mit den Headern gearbeitet werden
// z.B. Location Header verfolgen, Fehlerbehandlung falls Datei nicht vorhanden, etc
// Datei vom Server lokal speichern
$lfh = fopen( 'C:\ouput.png', 'w' );
fwrite( $lfh, $content );
fclose( $lfh );
---
[1] ungetestet, da frei runtergetippt
weiterhin schönen abend...
Hello,
// Antwort vom Webserver lesen
$response = '';
while( !feof( $fh ) )
$response .= fread( $fh, 8192 );
Ich würde die Blockgröße eher kleiner halten, als 8k, auch wenn das bei den normalen gepufferten Lesevorgängen die Puffergröße ist. Beim Lesaen aus einem Socket habe ich da schon öfter Probleme gehabt, während kleinere Einheiten (128 bytes) bisher immer geklappt haben. Ich habe noch nicht nachgeschaut, woran das liegen könnte. Jedenfalls wären es mehrere Pakete, die in 8k reinpassen...
$response = explode( "\r\n\r\n", $response, 1 );
Was passiert eigentlich, wenn man explode('$a', false) aufruft?
Hab ich auch noch nie willentlich/wissentlich gemacht...
Harzliche Grüße vom Berg
http://bergpost.annerschbarrich.de
Tom
n'abend,
Hello,
// Antwort vom Webserver lesen
$response = '';
while( !feof( $fh ) )
$response .= fread( $fh, 8192 );Ich würde die Blockgröße eher kleiner halten, als 8k, auch wenn das bei den normalen gepufferten Lesevorgängen die Puffergröße ist. Beim Lesaen aus einem Socket habe ich da schon öfter Probleme gehabt, während kleinere Einheiten (128 bytes) bisher immer geklappt haben. Ich habe noch nicht nachgeschaut, woran das liegen könnte. Jedenfalls wären es mehrere Pakete, die in 8k reinpassen...
Ist sich Beispiel von die Webseite von die PHP Leut. Warum ein 8K Puffer zu Problemen führten sollte entzieht sich mir allerdings gerade. Ein kleinerer Puffer sorgt hier nur dafür, dass die Schleife öfter durchlaufen wird.
$response = explode( "\r\n\r\n", $response, 1 );
Was passiert eigentlich, wenn man explode('$a', false) aufruft?
Hab ich auch noch nie willentlich/wissentlich gemacht...
Wie kommst du denn darauf?
print_r( explode("foobar", false) );
ergibgt
Array
(
[0] =>
)
weiterhin schönen abend...
Hellihello zusammen,
Ich würde die Blockgröße eher kleiner halten, als 8k, auch wenn das bei den normalen gepufferten Lesevorgängen die Puffergröße ist. Beim Lesaen aus einem Socket habe ich da schon öfter Probleme gehabt, während kleinere Einheiten (128 bytes) bisher immer geklappt haben. Ich habe noch nicht nachgeschaut, woran das liegen könnte. Jedenfalls wären es mehrere Pakete, die in 8k reinpassen...
$response = explode( "\r\n\r\n", $response, 1 );
Was passiert eigentlich, wenn man explode('$a', false) aufruft?
Mh, die 1 am Ende, das Limit habe ich weggelassen, sonst hat er mir nämlich header und jpg-info noch zusammengelassen.
so klappt es jetzt (inklusive Portangabe im fsockopen()):
<?php
$host = 'example.com';
$file = '/bilder/test.jpg';
// Verbindung zum Webserver aufbauen
$fh = fsockopen( $host, 80 );
// sonst läuft die whileschleife ewig bei nichverbindung
if ($fh) {
// Anfrage für http://example.com/bilder/test.jpg absetzen
fputs( $fh, 'GET '. $file . " HTTP/1.1\r\n" );
fputs( $fh, 'Host: '. $host . "\r\n" );
fputs( $fh, "Connection: close\r\n\r\n" );
// Antwort vom Webserver lesen
$response = '';
while( !feof( $fh ) )
$response .= fread( $fh, 128 );
// Verbindung schliessen
fclose( $fh );
// header von content separieren
//$response = explode( "\r\n\r\n", $response, 1 );
$response = explode( "\r\n\r\n", $response );
$header = explode( "\r\n", $response[0] );
$content = isset( $response[1] ) ? $response[1] : null;
// an dieser Stelle könnte mit den Headern gearbeitet werden
// z.B. Location Header verfolgen, Fehlerbehandlung falls Datei nicht vorhanden, etc
var_dump($response);
var_dump($content);
// Datei vom Server lokal speichern
//vielleicht noch eine abfrage, ob $content inhalt hat vorher
$lfh = fopen( 'C:\test.jpg', 'w' );
//kleine kontrollmeldung
echo "done";
fwrite( $lfh, $content );
fclose( $lfh );
}
?>
Dank und Gruß,
frankx
n'abend,
Mh, die 1 am Ende, das Limit habe ich weggelassen, sonst hat er mir nämlich header und jpg-info noch zusammengelassen.
Dummerweise hab ich mir da mal wieder den selben alten Stolperstein um den Hals gebunden. Die falsche 1 muss natürlich eine 2 sein. (2 Elemente möchtest du maximal bekommen - dein Inhalt kann ja theoretisch beliebig viele \r\n\r\n enthalten). Wann merke ich mir endlich mal, dass das Limit nicht die Anzahl der splits, sondern die Anzahl der maximal resultierenden Elemente ist? gnarf...
weiterhin schönen abend...
Hello,
Was passiert eigentlich, wenn man explode('$a', false) aufruft?
Mh, die 1 am Ende, das Limit habe ich weggelassen, sonst hat er mir nämlich header und jpg-info noch zusammengelassen.
Das ist es aber noch nicht, denn $response könnte auch immer noch false sein...
Harzliche Grüße vom Berg
http://bergpost.annerschbarrich.de
Tom
Moin!
Der Komplettheit halber hier noch eine Variante, der die Direktive allow_url_fopen egal ist [1]:
Das größte Problem deiner Lösung ist, dass du HTTP/1.1 benutzt, ohne das Protokoll in dieser Versionsstufe wirklich zu unterstützen!
Wenn du kein HTTP/1.1 sprechen kannst, nimm doch einfach HTTP/1.0 - das hat so Ekligkeiten wie "chunks" nämlich nicht, die du sonst (er)kennen müßtest.
- Sven Rautenberg
Hi,
Aber wie sage ich denn speicher Bild example.com/test.gif unter c:\test.gif bzw. /home/me/test.gif.
<?php if(!copy 'http://example.com/test.gif','c:/test.gif') echo 'Fehler beim Kopieren'; ?>
Gruß, Cybaer
Oder so ;-):
<?php if(!copy('http://example.com/test.gif','c:/test.gif')) echo 'Fehler beim Kopieren'; ?>
Gruß, Cybaer
Hellihello Cybaer,
Oder so ;-):
<?php if(!copy('http://example.com/test.gif','c:/test.gif')) echo 'Fehler beim Kopieren'; ?>
Ja, arg fein. Hängt "copy" safe_mode?
Dank und Gruß,
frankx
Hi,
Ja, arg fein. Hängt "copy" safe_mode?
?
Gruß, Cybaer
Hellihello Cybaer,
Hi,
Ja, arg fein. Hängt "copy" safe_mode?
?
Vielleicht das Gegenteil vom Deppenleerzeichen? Ob copy auch bei eingeschaltetem safe_mode klappt oder durch sonstiges eingeschränkt würde, fragte ich mich laut, zgegebenermaßen etwas unvollständig und php.net sagts mir bestimmt auch gleich (;-).
Dank und Gruß,
frankx
Hi,
Ob copy auch bei eingeschaltetem safe_mode klappt oder durch sonstiges eingeschränkt würde,
Ich dachte, das spielt bei dir keine Rolle?
fragte ich mich laut, zgegebenermaßen etwas unvollständig und php.net sagts mir bestimmt auch gleich (;-).
Bestimmt. :-)
Ansonsten: safe_mode schränkt die Schreibrechte ein - woran es scheitern könnte -, und natürlich muß url_allow_fopen erlaubt sein.
Gruß, Cybaer
Hellihello Cybaer,
Hi,
Ob copy auch bei eingeschaltetem safe_mode klappt oder durch sonstiges eingeschränkt würde,
Ich dachte, das spielt bei dir keine Rolle?
Ja, yagni. Aber man weiß ja nie (;-). Theoretisch könnte "man" "das" ja auch auf dem webserver laufen lassen.
fragte ich mich laut, zgegebenermaßen etwas unvollständig und php.net sagts mir bestimmt auch gleich (;-).
Bestimmt. :-)
Ansonsten: safe_mode schränkt die Schreibrechte ein - woran es scheitern könnte -, und natürlich muß url_allow_fopen erlaubt sein.
Merci. So gehts ja auf jeden Fall lokal.
Dank und Gruß,
frankx
Hi,
Ja, yagni. Aber man weiß ja nie (;-). Theoretisch könnte "man" "das" ja auch auf dem webserver laufen lassen.
OK. :-)
Da ich auch so denke, macht so etwas bei mir dann eine get_contents/put_contents-Kombination, wobei alles "problematische" redundant ersetzt wird (also erst File-Funktionen danach cURL und dann eigenem Request - irgendwas wird schon laufen ;-))
Gruß, Cybaer
Hellihello Cybaer,
Da ich auch so denke, macht so etwas bei mir dann eine get_contents/put_contents-Kombination, wobei alles "problematische" redundant ersetzt wird (also erst File-Funktionen danach cURL und dann eigenem Request - irgendwas wird schon laufen ;-))
Ist curl nicht ein request?
[quote]
PHP unterstützt libcurl, eine Bibiothek entwickelt von Daniel Stenberg, die es erlaubt sich mit Servern zu verbinden und über diverse Protokolle zu kommunizieren. Libcurl unterstützt zur Zeit folgende Protokolle: http,
[/quote]
Dank und Gruß,
frankx
Hi,
Ist curl nicht ein request?
Sogesehen "ist" copy() hier auch ein Request. :)
Mit "eigenem Request" meine ich die "harte", manuelle Methode via fsockopen().
cURL muß nicht Bestandteil der PHP-Installation sein.
Gruß, Cybaer