kostenloser Webspace werbefrei: lima-city


PHP Endlosschleifen abfangen

lima-cityForumProgrammiersprachenPHP, MySQL & .htaccess

  1. Autor dieses Themas

    igruber

    Kostenloser Webspace von igruber

    igruber hat kostenlosen Webspace.

    Hi,

    Ich arbeite gerade an einem relativ komplexen Projekt bei dem ich viele Funktionsaufrufe habe. Teilweise mach ich kleine Fehler und dann kommt es immer zu einem Internen Server Error wegen Endlosschleife, also sehr vereinfacht sieht sowas so aus:

    <?php
    
    function run() {
     run();
    }
    run();


    Hat jmd ne Idee wie man das am einfachsten abfängt? PHP-Errors hab ich ja nicht.

    Wär sehr glücklich über ne Lösung :)

    Grüße

    Daniel
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. z**u

    Hallo igruber,

    Ich habe jetzt einige Minuten überlegt und komme zu folgendem Ergebnis:

    Obwohl PHP ja als dynamisch im Vergleich zu HTML bekannt ist, ist es dennoch fix, sprich am Code selber verändert sich während dem Gebrauch / Aufruf normalerweise nichts. Wenn du eine Endlosschleife verursachst, dann hast du ein logisches Problem in deiner Syntax, da hilft dir garantiert kein Workaround, sprich:
    <?php
    
    function run() {
     run();
    }
    run();


    Darf nicht passieren, und eine automatische Lösung, die den fehlerhaften Code quasi vor dir versteckt wäre doch eher unvorteilhaft, oder? :)
  4. m******************r

    Hallo!

    Du kannst dir zumindest deine Fehler mittels einer .htaccess-Datei in deinem root-Verzeichnis mit zumindest folgendem Inhalt
    php_flag display_errors on

    anzeigen lassen.
    Würde ich allerdings nur zu Entwicklungszwecken verwenden.

    LG
  5. igruber schrieb:
    dann kommt es immer zu einem Internen Server Error wegen Endlosschleife, also sehr vereinfacht sieht sowas so aus:
    <?php
    
    function run() {
     run();
    }
    run();

    Das ist keine Endlosschleife sondern eine Endlosrekursion. Und wenn PHP keine Tail-Calls erzeugt, läuft dir ganz schnell der Stack voll und dann kann es natürlich zum internal Server error kommen.

    Falls du das nicht verstanden hast: Keine Panik. Wichtig ist zunächst zu wissen, dass das da oben keine Endlosschleife ist. Eine Endlosschleife wäre eher sowas:
    while( 1 == 1 ) {
      //mach was
    }

    Da die Bedingung immer wieder erfolgreich überprüft wird.

    Wenn du eine Aktion hintereinander(!) wiederholt ausführen willst, solltest du sie in eine for- oder while-Schleife verpacken. Also bau am besten deine Code jetzt entsprechend um und eventuell löst sich das Problem dann von ganz alleine

    Hat jmd ne Idee wie man das am einfachsten abfängt? PHP-Errors hab ich ja nicht.

    Falls du deinen Code ausschließlich hier auf lima testest, solltest du besser bei dir zu Hause einen Webserver+PHP einrichten (Aber den Webserver so absichern dass nicht vom Internet aus zugriffen werden kann). Dafür installierst du dir am besten XAMPP und dann kannst du dir auch beliebig dein Fehlerlevel setzen.

    Und wenn du eine Endlosrekursion/Endlosschleife in deinem Code hast, dann ist das natürlich ein Bug. Das sollte man nicht abfangen, sondern korrigieren.
  6. bladehunter schrieb:
    ... Und wenn du eine Endlosrekursion/Endlosschleife in deinem Code hast, dann ist das natürlich ein Bug. Das sollte man nicht abfangen, sondern korrigieren.
    demnach ist jedes betriebsystem ein bug :o) betribsysteme sind endlosschleifen mit abbruchbedingung (shutdown). in der programmierung werden endlosschleifen außerdem noch für unzählige lösungen eingesetzt. ob die rekursion eine schleife ist oder nicht, gehört in die philososophie und nicht hierher.

    zu deinem code solltest du eine geeignete abbrucbhbedingung vorgeben. ein einfaches beispiel (mit rekursion und while zum vergleichen):
    <?php
    $limit  = 10;
    $result = '<strong>rekursion:</strong> ';
    
    run(1);
    $result .= "<hr /><strong>while:</strong> ";
    
    
    $count = 1;
    while($count <= $limit) {
      $result .= " - $count";
      $count++;
    }
    
    exit("$result<hr />und aus is' :o)");
    
    
    function run($count) {
      global $limit, $result;
    
      $result .= " - $count";
    
      if($count < $limit) {run(++$count);}
    
    }
    wobei die abbruchbedingungen für
    die rekursion: $count nicht kleiner als $limit
    und für while: $count größer als $limit
    sind.

    ACHTUNG bei der rekursion!!
    if($count < $limit) {run(++$count);}
    und nicht
    if($count < $limit) {run($count++);}
    sonst hast du wieder deine endlosschleife (hausaufgabe: über den grund nachdenken ;o)

    lg

    p.s.: siehe dazu wiki (suche dort nach 'Implementierung, implementativ rekursiv').
  7. hemiolos schrieb:
    bladehunter schrieb:
    ... Und wenn du eine Endlosrekursion/Endlosschleife in deinem Code hast, dann ist das natürlich ein Bug. Das sollte man nicht abfangen, sondern korrigieren.
    demnach ist jedes betriebsystem ein bug :o) betribsysteme sind endlosschleifen mit abbruchbedingung (shutdown). in der programmierung werden endlosschleifen außerdem noch für unzählige lösungen eingesetzt.

    Betriebssysteme werden auch nicht in PHP geschrieben :tongue:

    Und PHP hat eine max_execution_time-Direktive, die festlegt, wie lange ein Script laufen darf. Man kann diese Zeit auch auf unbegrenzt setzen, aber so eine Einstellung wirst du bei keinem nicht-VServer/nicht-root-Server Hoster antreffen. Folglich müssen alle (gängigen) PHP Programme in endlicher Zeit terminieren. Endlosschleifen sind daher im Web-Bereich praktisch nicht erwünscht und anzutreffen. Falls man eine Gtk Anwendung mit PHP schreibt, sieht die Geschichte natürlich anders aus.
  8. bladehunter schrieb:
    ... Betriebssysteme werden auch nicht in PHP geschrieben ...
    seltsame argumentation :o) -- programm ist programm und basta.

    Und PHP hat eine max_execution_time-Direktive, die festlegt, wie lange ein Script laufen darf. Man kann diese Zeit auch auf unbegrenzt setzen, aber so eine Einstellung wirst du bei keinem nicht-VServer/nicht-root-Server Hoster antreffen. Folglich müssen alle (gängigen) PHP Programme in endlicher Zeit terminieren. Endlosschleifen sind daher im Web-Bereich praktisch nicht erwünscht und anzutreffen. Falls man eine Gtk Anwendung mit PHP schreibt, sieht die Geschichte natürlich anders aus.
    ja wenn du einzig und allein von einem gratisanbieter ausgehst, kannst sowieso - so gut wie - nix realisieren was hand und fuß hat. beispiel? es gibt einen webserver in php geschrieben, der teilweise sogar schneller als apache ist (unglaublich? googeln ;o)

    außerdem kann man einiges, was hier im forum nicht mal nach namen vorkommt programmieren.

    lg

    p.s.:
    sind daher im Web-Bereich praktisch nicht erwünscht und anzutreffen
    sieht die Geschichte natürlich anders aus
    öhhhmm?

    Beitrag zuletzt geändert: 13.7.2011 20:08:32 von hemiolos
  9. hemiolos schrieb:
    bladehunter schrieb:
    ... Betriebssysteme werden auch nicht in PHP geschrieben ...
    seltsame argumentation :o) -- programm ist programm und basta.

    Ein Hammer ist ein Werkzeug. Trotzdem sollte man damit kein Loch in die Wand bohren. PHP ist trotz Turing-Vollständigkeit kein geeignetes Mittel Betriebssysteme zu schreiben. Dafür hat es andere Stärken.


    Und PHP hat eine max_execution_time-Direktive, die festlegt, wie lange ein Script laufen darf. Man kann diese Zeit auch auf unbegrenzt setzen, aber so eine Einstellung wirst du bei keinem nicht-VServer/nicht-root-Server Hoster antreffen. Folglich müssen alle (gängigen) PHP Programme in endlicher Zeit terminieren. Endlosschleifen sind daher im Web-Bereich praktisch nicht erwünscht und anzutreffen. Falls man eine Gtk Anwendung mit PHP schreibt, sieht die Geschichte natürlich anders aus.
    ja wenn du einzig und allein von einem gratisanbieter ausgehst,

    Das tue ich nicht. Ich habe kostenpflichtige Angebote wie Shared Hosting zum Beispiel nicht ausgeschlossen. Das was ich ausgeschlossen habe, sind Hoster, wo ich wirklich nahezu vollständige Kontrolle darüber habe, was installiert ist.


    kannst sowieso - so gut wie - nix realisieren was hand und fuß hat. beispiel? es gibt einen webserver in php geschrieben, der teilweise sogar schneller als apache ist (unglaublich? googeln ;o)

    Und warum ist der dann nicht weiter verbreitet? "Teilweise" kann sich auch auf eine Handvoll von Features beschränken, wo PHP einfach mal die besseren Vorraussetzungen hat, was mich jetzt nicht sonderlich überrascht. Das Googlen überlasse ich aber dir, falls du mich eines besseren belehren willst, da ich jetzt nicht die Zeit dazu habe eine weitläufigere Recherche und Analyse zu machen.


    außerdem kann man einiges, was hier im forum nicht mal nach namen vorkommt programmieren.

    Das gleiche kann man auch mit Brainfuck machen. Turing-Vollständigkeit ist ein sehr kleiner, aber mächtiger gemeinsamer Nenner. Hinzu kommt noch, dass es kein noch so elitäres Forum gibt, was alle Anwendungstypen schon einmal behandelt hat, da es einfach zu viele sind.


    sind daher im Web-Bereich praktisch nicht erwünscht und anzutreffen
    sieht die Geschichte natürlich anders aus
    öhhhmm?

    Da ist wohl was beim Zitieren schief gelaufen.
  10. Autor dieses Themas

    igruber

    Kostenloser Webspace von igruber

    igruber hat kostenlosen Webspace.

    Hi,

    Danke schonmal für die vielen Antworten.

    Also leute, bevor ihr Angst bekommt, ich Teste auf eigenem Server ;)

    Klar ist das ein logischer Fehler, nur Umso komplexer die Applikation wird, umso mehr Möglichkeiten hat man, das versehentlich zu produzieren und deswegen wärs halt hilfreich Fehlermeldungen zu bekommen Statt nen Internen.

    Was ich mich auch frag, warum kein max-Exekution-Time oder zu viel RAM-Fehler kommt, sondern 500. Das scheint da PHP selbst zu erkennen..

    Mal sehen, ob ich da noch an PHP bissl was einstellen kann, um da nen Fehler anzuzeigen.

    Also danke nochmal an alle :)

    // edit
    Das mit Count ist sinnvoll, find ich aber zu aufwendig bei meiner Anwendung.
    Also das mit dem ++ vorher ist doch klar, weil die Macher von C damals Sturzbetrunken waren ;)
    Nachgestellt gibt die gleiche Value, das wolltest du doch hören?

    Grüße

    Daniel

    Beitrag zuletzt geändert: 13.7.2011 23:38:13 von igruber
  11. igruber schrieb:
    ... Das mit Count ist sinnvoll, find ich aber zu aufwendig bei meiner Anwendung.
    wir kennen deine anwendung nicht, wir tappten alle im dunkeln ;o(

    Also das mit dem ++ vorher ist doch klar, weil die Macher von C damals Sturzbetrunken waren ;)
    die haben damals LSD praktiziert :o)). ich weiß es nicht, ob das mit sturzbetrunken gleichkommt, aber die haben sogar versucht zu fliegen, was partout nicht zustande kommen wollte.

    Nachgestellt gibt die gleiche Value, das wolltest du doch hören? ...
    NEIN. es gibt zwar die gleiche value, aber wo oder eher wann(!)???? und genau daher - endlosschleife!!!! (ja und dann denkt man sich: ist das eine feature oder ein bug von php?)
    also nochmals: think php! (aber nicht das hier!!)

    lg
  12. e**h

    Eine Endlos-Rekursion ist natürlich nicht die feine Art, denn irgendwann ist immer Schluss. - Aber du kannst (ohne weitere Änderung der Programmlogik) die Rekusion z. B. mit einer statischen Variablen (ab PHP5) kontrollieren und bei Bedarf abbrechen.
    <?php
    function run(){
    static $aufruf=0;
    echo $aufruf."\n";   //um irgendwas sichbares zu machen
    if(++$aufruf<10) run();
    }
    run();
    ?>
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
  13. Autor dieses Themas

    igruber

    Kostenloser Webspace von igruber

    igruber hat kostenlosen Webspace.

    Ja,

    Das ist ganz sicher so gedacht, auch wenn's niemand versteht warum...
    Des kommt von C, die waren die besoffenen und die anderen haben in ihrem Rausch abgeschrieben ;)

    Also ich schreib aktuell an einem CMS. Ich habe Dataclasses, die ihre Werte über ArrayAccess bereitstellen. Da hatte ich den Fehler gemacht, wenn ein Wert nicht existiert, nicht false zurückzugeben, sondern über das eigene throwerror einen Fehler. Doch in der Fehlerfunktion gab es wiederum Zugriffe auf das Objekt per ArrayAccess und naja, fertig war die Endlosrekursion.

    Ich denk das mit dem statischen Count bau ich mal an ein paar wichtige Stellen in den Code rein, um keine Endlosrekursionen zu bekommen

    Sry, dass ich die Begrifflichkeiten nicht perfekt gesagt hab, aber die sind mir ehrlich gesagt egal ;)

    Danke nochmal am alle

    Grüße

    Daniel
  14. trotz das die sache ausreichen dargestellt wurde, möchte ich dazu noch (weil von mir versehentlich unbeachtet blieb [ich bitte um entschuldigung]) kurz stellungnehmen.
    bladehunter schrieb:
    ... PHP ist ... kein geeignetes Mittel Betriebssysteme zu schreiben.
    nie gegenseitiges behauptet (postings etwas genauer lesen?)!

    ... Das was ich ausgeschlossen habe, sind Hoster, wo ich wirklich nahezu vollständige Kontrolle darüber habe, was installiert ist.
    schade, das du das beste ausschließt. (was meinst mit nahezu? ich installiere alle meine server für meine kunden wie ich will. wo liegt das problem?)

    ... Und warum ist der dann nicht weiter verbreitet?
    siehe datum der veröffentlichung. (wenn man sich registriert [und das lohnt sich wahrhaftig!], sieht man auch etwas ;o)

    ... Das Googlen überlasse ich aber dir, ...
    DANKE! DANKE! google haben einige von uns schon bedient, wo die meisten von hier in die windeln gemacht haben ;o)

    ... sind daher im Web-Bereich praktisch nicht erwünscht und anzutreffen
    sieht die Geschichte natürlich anders aus
    öhhhmm?

    Da ist wohl was beim Zitieren schief gelaufen.
    nein, nur bei gewissen leuten das gedächtnis und die kombinationsgabe fehlt. na dann mal wörtlich:
    Und PHP hat eine max_execution_time-Direktive, die festlegt, wie lange ein Script laufen darf. Man kann diese Zeit auch auf unbegrenzt setzen, aber so eine Einstellung wirst du bei keinem nicht-VServer/nicht-root-Server Hoster antreffen. Folglich müssen alle (gängigen) PHP Programme in endlicher Zeit terminieren. Endlosschleifen sind daher im Web-Bereich praktisch nicht erwünscht und anzutreffen. Falls man eine Gtk Anwendung mit PHP schreibt, sieht die Geschichte natürlich anders aus.
    kurz dazu:
    1. max_execution_time - du vergisst, dass du SELBST nicht-gratis-provider NICHT ausschließt (siehe vorher)
    2. (nicht-V)Server - ob da 'nicht-V' steht oder nicht, dass ist von der einrichtung abhängig und nicht vom 'V'.
    3. nicht-root-Server - ist ein server, der kein DNS-server ist. (du meintest eventuell einen NICHT dedizierten server? der würde passen.)
    4. Folglich müssen alle (gängigen) ... - nach 1., 2. und 3. muss nix mehr sein ;o)
    5. Endlosschleifen sind daher im Web-Bereich praktisch nicht erwünscht und anzutreffen - daher (wegen 4., aber auch das hier [ebenfalls eine endlosschleife!]) zergeht das auf der zunge
    6. WTF GTK!!?? bist du bei der posting eingepennt? (es war erst 21:07:33.)

    lg
  15. Also erstmal zum OP:
    Wenn du das ganze debuggen willst, dann nimm doch Debugfunktionen ^^
    Es gibt die tolle funktion debug_backtrace bzw. debug_print_backtrace welche dir den Aufrufstack darstellen.

    Damit kannst du dann direkt sehen, welche Funktionen durch welche aufgerufen wurden.
    Das heißt du könntest beispielsweiße mit
    count(debug_backtrace)
    herausfinden,
    wie tief du dich in einer Rekursion befindest und wenn du feststellst, dass es schon mehr als 20 Aufrufe sind(sollte für gängige Webprogrammierung mehr als ausreichend sein),
    dann brichst du ab und lässt dir den Stacktrace ausgeben.
    Dann siehst du sofort, wo sich der Zyklus befindet.

    Und jetzt zu hemiolos und bladehunter:
    Wollt ihr euch nicht woanders über den sinnvollen Einsatz von PHP und Endlosschleifen/-Rekursionen streiten?
    Ich glaube nicht, dass es den OP bei seinem aktuellen Problemen vorwärts bringen wird.

    Grüße
    Sektor

    Beitrag zuletzt geändert: 16.7.2011 10:50:56 von sektor
  16. sektor schrieb:
    Also erstmal zum OP:
    Wenn du das ganze debuggen willst, ...
    debugen ist natürlich immer gut, aber er fragte nach abbruchmölichkeiten in einer endlosschleife (dass wir bei der sache bleiben ;o) [damit ist gemeint, mann sollte möglichst die frage beantworten - in erster linie - was auch bedingt alles genau zu lesen.]

    Und jetzt zu hemiolos und bladehunter:
    Wollt ihr euch nicht woanders über den sinnvollen Einsatz von PHP und Endlosschleifen/-Rekursionen streiten?
    das ist erstens nicht DEIN thread
    zweitens hast allerdingsa recht, ich bin für Guinness Gentle Art Beer Pub :o)) [wenn auch nur mit mass!]

    lg

    p.s.: zu deiner beruhigung, jetzt bin ich echt fertig da.
  17. Hm ich war eigentlich der Meinung, dass er das Problem hat zu erkennen,
    wo sich die Schleife einschleicht.
    Aber die Abbruchbedingung habe ich ja meiner Meinung nach auch noch geliefert.

    Natürlich ist es nicht mein Thread und die Frage war nur dazu gedacht, damit sich alle nochmal sammeln und aufs Thema konzentrieren.
    Ich wollte dementsprechend damit auch weder dich noch bladehunter angreifen.

    Mal abgesehen davon wär die Diskussion sicherlich nicht schlecht und ich würde mich auch daran beteiligen, wenn sie in einem eigens dafür eröffneten Thread gehalten würde.

    So von meiner Seite jetzt auch genug, da ich sonst nichts anderes tun würde, als das, was ich "kritisiert" habe. ^^

    Grüße
    Sektor

    Beitrag zuletzt geändert: 16.7.2011 11:55:47 von sektor
  18. Bei komplexen Projekten, egal welche Sprache, sollte man immer auf ordentlich strukturierten Code wertlegen.
    Also, die Tab-Taste benutzen.
    Falsch:
    <?php
    $page = $_GET["page"];
    if( $page == "" )
    {
    $page = "home";
    }
    switch( $page )
    {
    case "home":
    require( "$lang/home.php" );
    break;
    case "downloads":
    require( "$lang/downloads.php" );
    break;
    case "Impressum":
    require( "$lang/impressum.php" );
    break;
    case "mail":
    require( "mailer.php" );
    require( "$lang/mail.php" );
    break;
    default:
    require( "$lang/404.php" );
    }
    ?>

    Richtig:
    <?php
    	$page = $_GET["page"];
    	if( $page == "" )
    	{
    		$page = "home";
    	}
    	switch( $page )
    	{
    		case "home":
    			require( "$lang/home.php" );
    			break;
    		case "downloads":
    			require( "$lang/downloads.php" );
    			break;
    		case "Impressum":
    			require( "$lang/impressum.php" );
    			break;
    		case "mail":
    				require( "mailer.php" );
    				require( "$lang/mail.php" );
    			break;
    		default:
    			require( "$lang/404.php" );
    	}
    ?>

    Außerdem hift es ungemein einen Editor mit Syntaxhervorhebung zu benutzen.

    Und um deinen Fehler zu finden:
    Leg' ein neues php-Script an und schreib' da rein:
    <?php
    	function report( $msg )
    	{
    		$statusfile = "status.txt";
    		$file = fopen( $statusfile, "a" );
    		fwrite( $file, "$msg\n" );
    		fclose( $file );
    	}
    ?>

    Dann bindest du das in jedes Script, das du aufrufst, mit "require_once" ein.
    Schließlich rufst du in jeder anderen Funktion die report-Funktion auf mit einer Nachricht, wo du grade bist, auf.

    Dann rufst du das script auf und in der Statusfile solltest du nun sehen können, wo sich das Programm aufgehangen hat.
    Allerdings solltest du die Statusfile nach dem lesen umbenennen oder löschen, da durch die Funktion nur an das Ende der Datei geschrieben wird...

    Ich hoffe, das ist hilfreich.
  19. Autor dieses Themas

    igruber

    Kostenloser Webspace von igruber

    igruber hat kostenlosen Webspace.

    da ist keine schlechte Sache mit dem Log-File, hab ich grundsätzlich schon, aber so in der Art find ich das sogar ziemlich cool.

    Danke an alle nochmal :)
    Grundsätzlich zu Code-Design: Mein Code ist sehr sauber, aber bei mehreren Tausend Zeilen verliert man schon ab und an den Überblick, solange mit nur mit 22 Zoll-Monitoren arbeitet ;)

    Grüße

    Daniel
  20. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!