Entwickler-Ecke

Programmiersprachen (Server) - PHP-Script hängt ab und zu


Gausi - Sa 09.07.11 15:40
Titel: PHP-Script hängt ab und zu
Hallo liebe PHP-Profis hier in der Ecke,

Ich binde auf einer Seite über ein kleines Script Inhalte einer anderen Seite ein. Das ist so erlaubt, aber das scheint ab und zu nicht so zu funktionieren, wie ich das gerne hätte. D.h. statt "Meine Seite + Inhalt aus anderer Seite" kommt nur "interner Server Error 500".

Das Script, was ich zum Einbinden verwende, sieht so aus (das ist so von dieser Seite kopiert, wenn das furchtbar schlecht ist: nicht meine Schuld. :angel:) Das Script soll die zum Tag passende Bibelstelle (z.B. "Mt. 10,24-33") ausgeben, ein ganz ähnliches liefert dann den Text dazu, da sind nur die Parameter in der URL anders.


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
<?php
$today = date('Ymd');
$url = "http://feed.evangelizo.org/reader.php?date=$today&type=reading_st&content=GSP&lang=DE"; 
$h = fopen($url,"r");
while (!feof($h)) {
  $str .= fgets($h);
}
print $str;
?>


Ursache dürfte wohl die Schleife sein, die gelegentlich eine Endlosschleife ist. Da ich von PHP keine Ahnung habe: Wie macht man das richtig?


Moderiert von user profile iconChristian S.: Topic aus Delphi4PHP-Technologien verschoben am So 15.07.2012 um 13:05


jaenicke - Sa 09.07.11 15:50

Da fehlt auf jeden Fall die Abfrage, ob das Öffnen überhaupt geklappt hat. Vielleicht ist der andere Server z.B. manchmal überlastet und antwortet nicht im Timeout.

Quelltext
1:
2:
3:
4:
if ($h = fopen($url, "r"))
  while (!feof($h)) {
    $str .= fgets($h);
  }
// EDIT:
In der Doku steht auch noch mehr in den Kommentaren:
http://php.net/manual/de/function.feof.php


BenBE - Sa 09.07.11 16:29

Zwei mögliche Ursachen:
- Netzwerk-Timeout beim Lesen des Sockets
- Fehlende Berechtigung für URL-FOpen.

Da es manchmal funktioniert, würde ich zweitens ausschließen.

Als Lösung würde ich folgendes machen:
1. Da sich die Bibel i.d.R. nicht ändert (lediglich deren Interpretation ;-)) würde ich einmal abgefragte Bibelstellen cachen. Das vermeidet nicht nur den Netzwerk-Zugriff, sondern geht sogar wesentlich schneller

2. Statt fopen/feof/fread/fclose eine All-in-One-Funktion nehmen. Anbieten würde sich hier file_get_contents mit der URL als Parameter (und ggf. dem Dateikontext).

Angenommen, wir haben also dein Script und ein Verzeichnis "cache/bible/", dann könnte man folgendes bauen:


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
define ('BIBLE_CACHE', dirname(__FILE__).'/cache/bible');

function getBibleQuote($url) {
    $cachefile = BIBLE_CACHE . '/' . md5($url) . '.quote';
    if(!file_exists($cachefile) {
        $content = file_get_contents($url);
        if(!empty($content)) {
            file_put_contents($cachefile, $content);
        }
    } else {
        $content = file_get_contents($cachefile);
    }
    return $content;
}


Und siehe da:

C#-Quelltext
1:
2:
$today = date('Ymd');
$quote = getBibleQuote("http://feed.evangelizo.org/reader.php?date=$today&type=reading_st&content=GSP&lang=DE");


Gausi - Sa 09.07.11 18:27

Ok, das komplett neue Script mit Caching gefällt mir sehr gut. Hab das mal ersetzt, und das scheint zu klappen. Mal sehen, ob der 500er Fehler jetzt seltener kommt, oder ob das doch an was anderem lag. :D