frankx: Web-Bild lokal speichern

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

  1. 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

    --
    "Love your nation - respect the others."
    1. 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...

      --
      #selfhtml hat ein Forum?
      sh:( fo:# ch:# rl:| br:> n4:& ie:{ mo:} va:) de:] zu:} fl:( ss:? ls:[ js:|
      1. 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

        1. 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

          --
          Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
          Nur selber lernen macht schlau
          Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

          1. 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

            --
            Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
            Nur selber lernen macht schlau
            Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

            1. 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

        2. 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...

          --
          #selfhtml hat ein Forum?
          sh:( fo:# ch:# rl:| br:> n4:& ie:{ mo:} va:) de:] zu:} fl:( ss:? ls:[ js:|
          1. 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

            --
            Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
            Nur selber lernen macht schlau
            Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

            1. 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...

              --
              #selfhtml hat ein Forum?
              sh:( fo:# ch:# rl:| br:> n4:& ie:{ mo:} va:) de:] zu:} fl:( ss:? ls:[ js:|
            2. 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

              1. 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...

                --
                #selfhtml hat ein Forum?
                sh:( fo:# ch:# rl:| br:> n4:& ie:{ mo:} va:) de:] zu:} fl:( ss:? ls:[ js:|
              2. 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

                --
                Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
                Nur selber lernen macht schlau
                Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

          2. 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

            --
            "Love your nation - respect the others."
        3. 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

          --
          Hinweis an Fragesteller: Fremde haben ihre Freizeit geopfert, um Dir zu helfen. Helfe Du auch im Archiv Suchenden: Beende deinen Thread mit einem "Hat geholfen" oder "Hat nicht geholfen"!
          1. Oder so ;-):

            <?php if(!copy('http://example.com/test.gif','c:/test.gif')) echo 'Fehler beim Kopieren'; ?>

            Gruß, Cybaer

            --
            Hinweis an Fragesteller: Fremde haben ihre Freizeit geopfert, um Dir zu helfen. Helfe Du auch im Archiv Suchenden: Beende deinen Thread mit einem "Hat geholfen" oder "Hat nicht geholfen"!
            1. 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

              1. Hi,

                Ja, arg fein. Hängt "copy" safe_mode?

                ?

                Gruß, Cybaer

                --
                Hinweis an Fragesteller: Fremde haben ihre Freizeit geopfert, um Dir zu helfen. Helfe Du auch im Archiv Suchenden: Beende deinen Thread mit einem "Hat geholfen" oder "Hat nicht geholfen"!
                1. 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

                  1. 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

                    --
                    Hinweis an Fragesteller: Fremde haben ihre Freizeit geopfert, um Dir zu helfen. Helfe Du auch im Archiv Suchenden: Beende deinen Thread mit einem "Hat geholfen" oder "Hat nicht geholfen"!
                    1. 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

                      1. 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

                        --
                        Hinweis an Fragesteller: Fremde haben ihre Freizeit geopfert, um Dir zu helfen. Helfe Du auch im Archiv Suchenden: Beende deinen Thread mit einem "Hat geholfen" oder "Hat nicht geholfen"!
                        1. 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

                          1. 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

                            --
                            Hinweis an Fragesteller: Fremde haben ihre Freizeit geopfert, um Dir zu helfen. Helfe Du auch im Archiv Suchenden: Beende deinen Thread mit einem "Hat geholfen" oder "Hat nicht geholfen"!