2010-04-18 7 views
13

Derzeit ist ich mit file_get_contents() GET-Daten zu einer Reihe von Websites zu unterbreiten, aber bei der Ausführung der Seite bekomme ich diesen Fehler:schnellere Alternative zu file_get_contents()

Fatal error: Maximale Ausführungszeit von 30 Sekunden überschritten

Alles, was ich wirklich möchte das Skript zu tun ist, laden Sie die Webseite, und dann verlassen. Es kann bis zu 5 Minuten dauern, bis jede Webseite vollständig geladen ist, und ich brauche sie nicht vollständig zu laden.

Hier ist, was ich derzeit haben:

 foreach($sites as $s) //Create one line to read from a wide array 
     { 
       file_get_contents($s['url']); // Send to the shells 
     } 

EDIT: keine Verwirrung zu löschen, dieses Skript verwendet wird, um Skripte auf anderen Servern zu starten, die keine Daten zurück.

EDIT: Ich versuche jetzt cURL, um den Trick zu tun, indem Sie eine Zeitüberschreitung von einer Sekunde, damit es die Daten senden und dann stoppen. Hier ist mein Code:

 $ch = curl_init($s['url']); //load the urls 
     curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 1); //Only send the data, don't wait. 
     curl_exec($ch); //Execute 
     curl_close($ch); //Close it off. 

Vielleicht habe ich die Option falsch eingestellt. Ich sehe gerade einige Handbücher durch, während wir sprechen. Ich gebe Ihnen nur ein Update. Danke euch allen, die mir bisher geholfen haben.

EDIT: Ah, das Problem gefunden. Ich habe CURLOPT_CONNECTTIMEOUT anstelle von CURLOPT_TIMEOUT verwendet. Hoppla.

Nun jedoch, die Skripte werden nicht ausgelöst. Sie verwenden jeweils ignore_user_abort (TRUE); so kann ich das Problem nicht verstehen

Hah, kratzen Sie das. Funktioniert jetzt. Vielen Dank jeder

+0

Haben Sie versucht, locken mit? –

+0

Nein, ich habe keine Erfahrung mit cURL. Wollte es mit etwas machen, mit dem ich zumindest ein bisschen Erfahrung habe. Du denkst ich sollte das mit php verwerfen und mit cURL gehen? – Rob

+0

Was genau macht die Webseite? Möchten Sie nur, dass es ein Skript startet, das von selbst ausgeführt werden sollte, das keine Daten zurückgibt? –

Antwort

6

Es gibt viele Möglichkeiten, dies zu lösen.

Sie könnten cURL mit seinen curl_multi_ * -Funktionen verwenden, um die Anfragen asynchron auszuführen.Oder verwenden Sie cURL den üblichen Weg aber mit 1 als Timeout-Limit, so wird es Timeout anfordern und zurückgeben, aber die Anfrage wird ausgeführt.

Wenn Sie cURL nicht installiert haben, können Sie weiterhin file_get_contents verwenden, aber Forking-Prozesse (nicht so cool, aber funktioniert) mit etwas wie ZendX_Console_Process_Unix, so dass Sie das Warten zwischen jeder Anfrage vermeiden.

+0

Yep lassen Sie mich in diese aussehen und mit ihm für ein paar Minuten – Rob

+0

Versuchte spielen diese: \t \t \t $ ch = curl_init ($ s [ 'url']); // lade die URLs \t \t \t curl_setopt ($ ch, CURLOPT_CONNECTTIMEOUT, 1); // Sende nur die Daten, warte nicht. \t \t \t curl_exec ($ ch); // Ausführen \t \t \t curl_close ($ ch); // Close it Es lädt immer noch alle – Rob

+0

Entschuldigung, ich habe keine Zeit es zu testen. Vielleicht möchten Sie die anderen Methoden ausprobieren. – Franco

2

Re Ihr Update, das Sie nur Trigger benötigen die Operation:

könnten Sie versuchen file_get_contents mit einem Timeout verwenden. Dies würde dazu führen, dass das Remote-Skript aufgerufen wird, die Verbindung jedoch nach n Sekunden (z. B. 1) beendet wird.

Wenn das Remote-Skript so konfiguriert ist, dass es auch bei einem Abbruch der Verbindung weiterläuft (in PHP wäre das ignore_user_abort), sollte es funktionieren.

Probieren Sie es aus. Wenn es nicht funktioniert, werden Sie nicht in der Lage sein, Ihre time_limit zu erhöhen oder eine externe ausführbare Datei zu verwenden. Aber von dem, was Sie sagen - Sie müssen nur die Anfrage stellen - das sollte funktionieren. Sie könnten sogar versuchen, das Timeout auf 0 zu setzen, aber das würde ich nicht glauben.

Von here:

<?php 
$ctx = stream_context_create(array(
    'http' => array(
     'timeout' => 1 
     ) 
    ) 
); 
file_get_contents("http://example.com/", 0, $ctx); 
?> 

Um fair zu sein, Chris Antwort enthält bereits diese Möglichkeit: curl hat auch einen Timeout-Schalter.

+0

Nun, ich weiß, warum der Download so lange dauert, die Seiten, die ich lade, dauern zwischen 30 Sekunden und 5 Minuten, um vollständig geladen zu werden. – Rob

1

es ist nicht file_get_contents(), die so viel Zeit aber Netzwerkverbindung selbst verbrauchen.
Sie sollten GET-Daten nicht an ein Array von Sites senden, sondern ein RSS erstellen und sie RSS-Daten erhalten lassen.

+0

+1, am besten, wenn ein Feed verfügbar ist. Aber das wird einige feed-schwache Stellen hinterlassen, wo er weiterhin blockt, was die Locken fixieren würden. –

1

Ich verstehe die Bedeutung Ihres Skripts nicht vollständig. Aber hier ist das, was Sie tun können:

  1. Um den fatalen Fehler zu vermeiden schnell können Sie einfach set_time_limit (120) am Anfang der Datei hinzufügen. Dadurch kann das Skript 2 Minuten lang ausgeführt werden. Natürlich können Sie eine beliebige Zahl und 0 für unendlich verwenden.
  2. Wenn Sie nur die URL aufrufen müssen und sich nicht um das Ergebnis kümmern, sollten Sie cUrl im asynchronen Modus verwenden. In diesem Fall wird jeder Aufruf der URL nicht bis zum Ende warten. Und Sie können sie alle sehr schnell anrufen.

BR.

1

Wenn die Remote-Seiten bis zu 5 Minuten zum Laden benötigen, wird Ihr file_get_contents sich setzen und auf diese 5 Minuten warten. Gibt es irgendeine Möglichkeit, die Remote-Skripte zu modifizieren, um sie in einen Hintergrundprozess umzuwandeln und dort die schwere Verarbeitung durchzuführen? Auf diese Weise wird Ihr ursprünglicher Treffer fast sofort zurückkehren und Sie müssen nicht auf die Startphase warten.

Eine andere Möglichkeit ist es zu untersuchen, ob eine HEAD-Anfrage den Trick machen würde. HEAD gibt keine Daten zurück, nur Header, daher reicht es aus, die Remote-Jobs auszulösen und nicht auf die volle Ausgabe zu warten.

+0

Ich mag die Idee von HEAD, könnte einen Versuch wert sein. – svens

2

Wie Franco erwähnt, und ich bin mir nicht sicher, wurde abgeholt, möchten Sie insbesondere die curl_multi Funktionen verwenden, nicht die regulären locken diejenigen. Dadurch werden mehrere curl-Objekte in einem curl_multi-Objekt zusammengefasst und gleichzeitig ausgeführt, wobei die Antworten zurückgegeben werden (oder nicht, in Ihrem Fall).

Beispiel bei http://php.net/curl_multi_init