» PHP cURL: Vermeide CURLOPT_RETURNTRANSFER wenn möglich!

Relativen / absoluten Link in Deeplink umwandelnNeuen Thread eröffnenNeue Antwort erstellenParent-/Eltern-Verzeichnis einer URL ermitteln
AutorNachricht
Administrator 

Name: Marc
Geschlecht:
Anmeldedatum: 28.08.2004
Beiträge: 52423
Wohnort: Lohmar


Meine eBay-Auktionen:
01.04.2015, 09:14
zitieren

Mit cURL haben wir verschiedene Optionen eine URL einzulesen. z.B. können wir sie einlesen und direkt ausgeben:
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'http://example.com/');
curl_setopt($curl, CURLOPT_HEADER, false);
curl_exec($curl);
curl_close($curl);

Oder wir schreiben das Ergebnis in eine Datei:
$fp = fopen('filename.ext', 'w');
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'http://example.com/');
curl_setopt($curl, CURLOPT_FILE, $fp);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_exec($curl);
curl_close($curl);

Bis hierhin ist cURL absolut ressourcenschonend. Egal ob große oder kleine Daten, der RAM läuft nicht voll.

Jetzt möchten wir aber das Ergebnis in einer Variable haben. Also machen wir folgendes:
// write to variable
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'http://example.com/');
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($curl);
curl_close($curl);

Doch was ist wenn die Datei hinter $url 1 GB groß ist? Es gibt keine Garantie dafür, dass der Server die Datei ausliefert, die man erwartet. Und je nachdem wie viel RAM man bereits mit dem bisherigen PHP-Code belegt hat, kann es auch sein, dass bereits kleinere Dateien zur Überschreitung des memory_limit führen.

Nun könnte man an den Parameter CURLOPT_RANGE denken:
// write to variable
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'http://example.com/');
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_RANGE, '0-51200');
$result = curl_exec($curl);
curl_close($curl);

Nun überträgt cURL den range-HTTP-Header und begrenzt damit das Anfragevolumen auf 0,5 MB. Allerdings unterstützen nicht alle Server den range-Header. Es gibt auch Server, die solche Anfragen sperren, weil sie Download-Applikationen daran hindern möchten über mehrere parallele Streams schneller zu laden als ein vorgegebenes Limit erlaubt. Das ist also keine Lösung, sondern grundsätzlich ein Parameter, den ich nicht benutzen würde, außer man weiß, dass das Ziel dies erlaubt.

Was uns aber hilft ist CURLOPT_WRITEFUNCTION. Mit dem entsprechenden Callback begrenzen wir cURL bereits beim Einlesen der URL:
$result = '';
$limit = 51200;
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'http://example.com/');
curl_setopt($curl, CURLOPT_RANGE, '0-' . $limit);//not all servers support range
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_BINARYTRANSFER, 1);
curl_setopt($curl, CURLOPT_WRITEFUNCTION, function($curl, $chunk) {
global $result, $limit;
$len = strlen($result) + strlen($chunk);
if ($len >= $limit) {
// if you need corrupt files as well
//$result .= substr($chunk, 0, $limit - strlen($result));
// if you need only complete files respecting $limit
$result = '';
return -1;
}
$result .= $chunk;
return strlen($chunk);
});
curl_exec($curl);
echo $result;
curl_close($curl);

Ich habe das mit einer 1 GB großen Datei getestet. Mein Server benötigte mit der CURLOPT_FILE-Variante 24 Sekunden zur Übertragung. Mit CURLOPT_WRITEFUNCTION und Weglassen von CURLOPT_RANGE (um sicher zu gehen, dass diese Option nicht greift), war das Script in 0.07 Sekunden fertig. Es wird also wirklich die komplette Übertragung unterbrochen.

Das Problem ist jetzt nur festzulegen wie groß die größte Datei sein darf, die man einlesen möchte. Bei HTML-Seiten kann das Limit insbesondere wegen https://de.wikipedia.org/wiki/Scalable_Vector_Graphics#Beispiel und https://de.wikipedia.org/wiki/Data-URL schon mal bei mehreren MB liegen. Wobei sich Webmaster auch nicht alles erlauben können, da die Besucher ja nicht alle mit Glasfaser unterwegs sind. Ich denke mal 8 MB sind ein ausreichend großes Limit.

Will man dagegen noch größere Dateien einlesen können z.B. Bilder, die im Originalformat so hochauflösend sind, dass sie sogar über 16 MB groß sein könnten, dann bietet es sich an alle Dateien erst über CURLOPT_WRITEFUNCTION in eine lokale Datei zu schreiben und dann nach Analyse des Dateiformats und der Dateigröße in eine Variable zu übertragen. Also je nachdem wie man sie benötigt. Schließlich macht es selten Sinn alle Dateiformate grundsätzlich in den RAM zu schreiben, wenn man z.B. nur HTML verarbeiten möchte.

Demnach ist es also das Ziel gänzlich auf CURLOPT_RETURNTRANSFER zu verzichten. Und kommt bitte ja nicht erst auf die Idee ini_set('memory_limit', '1024M') einzusetzen. Das mag zwar im ersten Schritt das Problem lösen, aber der Server hat davon nichts, wenn jede Scriptausführung so viel Speicher in Anspruch nehmen kann. Darunter leidet dann nur die Gesamtperformance.


pn email
Gast 
01.04.2015, 09:14
zitieren

Mach mit!

Wenn Dir die Beiträge zum Thread "PHP cURL: Vermeide CURLOPT_RETURNTRANSFER wenn möglich!" gefallen haben oder Du noch Fragen hast oder Ergänzungen machen möchtest, solltest Du Dich gleich bei uns anmelden:



Registrierte Mitglieder genießen die folgenden Vorteile:
✔ kostenlose Mitgliedschaft
keine Werbung
✔ direkter Austausch mit Gleichgesinnten
✔ neue Fragen stellen oder Diskussionen starten
✔ schnelle Hilfe bei Problemen
✔ Bilder und Videos hochladen
✔ und vieles mehr...


Neuen Thread eröffnenNeue Antwort erstellen
Ähnliche BeiträgeRe:
Letzter Beitrag
C und cURL auf Linux mit popen
Hallo, ich möchte die Cookies einer Webseite über cURL in einer Variable speichern. Aktuell werden die Cookies in einem Textfile gespeichert mit Folgendem Befehl: curl -c cookies.txt -s -X POST 'https://www.webseite/login/' Mit popen...
[C]von Umbrecht
1
251
09.05.2022, 15:30
mgutt
ED9 started nicht direkt wenn er kalt ist, nur wenn warm!
Hallo zusammen, bin mir ziemlich sicher das paar von den vacuum schlaeuchen noch falsch sind an der ansaugbruecke, deswegen das problem: Wenn der motor kalt ist startet er fuerne sec und geht direkt aus. dann 10-14x schluessel aus wieder an bis er...
von Daniel.Werkman
2
538
05.03.2011, 19:52
uffi
Wenn ich mal alt bin
wenn ich mal alt bin bleib ich auch bei...
von Sobelin
13
973
25.10.2004, 18:15
Sobelin
wenn will er eig verarschen????
das sind doch ganz einfache lasierte rüllis oder ?? :laugh: ''Diese Rückleuchten sind sehr selten und daher sehr schwer zu...
von Andrüha1HGEJ2
3
300
28.04.2011, 22:15
Andrüha1HGEJ2
Wenn zum Tüv - was mit Fußraumbeleuchtung
Hi ! Was soll ich mit meiner FUßraumbeleuchtung machen, wenn ich zum Tüv muss ? Meint ihr es reicht, wenn ich den schalter ausbaue und da wieder die standardblende drauf mach ? a) weiss der tüver dann nicht dass ich sowas verbaut hab und b)...
von Xeal
24
1.828
25.05.2006, 12:24
toolish
so möglich? wenn ja, wie ?
hey, hab mal die google bildersuche betätigt und bin da auf einen geilen del sol gestoßen der es mir angetan hat. [img]http://www.kris.1000lecie.pl/delsolpics/honda%20del%20sol%20(1).bmp[/img] Gibts das Bodykit oder die einzelnen Dinge irgendwo zu...
von mystify mindhunter
2
1.291
07.10.2006, 09:37
Jonas | back in white
wenn man mit dem DC2 übertreibt
so sah er mal aus und so sieht er aus da bleibt auch nicht mehr viel zum schlachten übrig...
von Sobelin
12
1.993
09.11.2005, 10:29
Hondafreak!!!
Wenn mal bei der Polizeikontrolle ..
.. http://www.youtube.com/watch?v=s8yUvhSS2GE...
von Sariana
0
419
20.08.2008, 23:01
Sariana
wenn der ma net lebensmüde ist...
wie im titel schon geschrieben... :dumb:...
von VtecMac
12
923
01.08.2007, 23:24
The-COMP
Was passiert wenn?
ich die zweite lamnda bei meinem Kat die weglassen würde?Also abstecken und des wars?Wie kann ich das ganze vielleicht brücken das keine Fehlermeldung kommt da die 2. Lamnda ja auch die abgaswerte...
von Lufti
13
781
02.12.2010, 20:54
*RaZoR*
© 2004 - 2025 www.programmierer-forum.de | Communities | Impressum |