Ankündigung

Einklappen
Keine Ankündigung bisher.

Fehlerabfrage PHP get_headers bzw. get_contents

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    Fehlerabfrage PHP get_headers bzw. get_contents

    Hallo

    Ich habe bei mir 2 LBS im Einsatz, welche eine Datei über einen URL-Pfad öffnen. Leider kommt es vor, dass diese URL (bzw. der entfernte Webserver) ab und zu offline ist oder sonstwie keine Antwort gibt.
    Normalerweise würde man ja mit einem fileexists prüfen, ob eine Datei vorhanden ist, bevor man sie öffnet. Bei einem URL-Pfad geht bekanntlich fileexists nicht.

    Ich habe mir nun folgende Prüfung eingebaut:
    PHP-Code:
    // Prüfen, ob URL-Pfad gefunden wird. Sonst wird LBS abgebrochen.
    $file_headers = @get_headers($url);
    if (
    stripos($file_headers[0],"404 Not Found") >0  || (stripos($file_headers[0], "302 Found") > && stripos($file_headers[7],"404 Not Found") > 0)) {
      if (
    $debug==1) {writeToTraceLog(0,true,"URL Pfad nicht gefunden!");}
      
    $error=1;
      
    setLogicLinkAusgang($id,6,$EdomiTime); //Timestamp Edomi
      
    setLogicLinkAusgang($id,7,$error); //Error = true
      
    setLogicElementStatus($id,0);
      
    sql_disconnect();
      exit();


    Problem ist, dass der Check offenbar nicht richtig greift. Schon beim get_headers Aufruf wird im Edomi Log der folgende Fehler geschrieben. (Und später dann noch beim file_get_contents).
    Code:
    get_headers(http://xxxx): failed to open stream: No route to host
    file_get_contents(http://xxxx): failed to open stream: No route to host
    Da dieser LBS alle paar Minuten läuft, erzeuge ich da natürlich schnell sehr viele Fehler Log Einträge. (Und seit Edomi dies ja in der Visu anzeigt, nervt es stark.)

    Wie kann ich eine URL prüfen, ob sie online ist, ohne schon bei der Prüfung einen PHP-Fehler zu erzeugen?

    #2
    https://knx-user-forum.de/forum/proj...431#post929431
    Danke und LG, Dariusz
    GIRA | ENERTEX | MDT | MEANWELL | 24VDC LED | iBEMI | EDOMI | ETS5 | DS214+ | KNX/RS232-GW-ROTEL

    Kommentar


      #3
      Was ist denn die Ursache für den Fehler? Ist der Server nicht erreichbar wenn das Problem auftritt? Das "no route to host" macht mich etwas stutzig.
      Ist das ein internes Gerät was ausgeschaltet ist wenn dieser Fehler auftritt?

      Kommentar


        #4
        Ja, das ist unser Wechselrichter im Haus (somit internes Gerät), der leider immer wieder mal durch den FI rausfliegt und dann natürlich nicht mehr verfügbar ist.

        Kommentar


          #5
          Zitat von rdeckard Beitrag anzeigen
          Und seit Edomi dies ja in der Visu anzeigt, nervt es stark.
          Tja... Ich wollte es ja nicht implementieren - aber einige Nutzer bestanden darauf

          Aber keine Sorge: Bald wird man die Meldung quittieren können und dann ist Ruhe.
          EDOMI - Intelligente Steuerung und Visualisierung KNX-basierter Elektro-Installationen (http://www.edomi.de)

          Kommentar


            #6
            coliflower
            Danke, aber ich weiss nicht, wie mir das weiterhelfen kann? Du hast zwar eine etwas andere Abfrage, aber das Grundproblem müsste bei dir auch auftreten. Siehe dein Code in deiner vorherigen Nachricht: https://knx-user-forum.de/forum/proj...360#post929360

            PHP-Code:
            $url 'http://'.$E[3]['value'].'/%7E'.$E[5]['value'].'/';
                        
                        
            $urlplayer $url.$E[11]['value'].'.json';
                        
            $headers1 get_headers($urlplayer);
                        
                        if (
            $headers1[0] == 'HTTP/1.1 404 Not Found') {
                            EXIT;
                            
            writeToTraceLog(0,true,'404er is TRUE >> EXIT Player');
                        } else {
                            
            $player__ file_get_contents('http://'.$E[3]['value'].'/%7E'.$E[5]['value'].'/'.$E[11]['value'].'.json');
                            
            writeToTraceLog(0,true,'404er do not exists / Player '.$player__);
                        } 

            Der "$headers1 = get_headers($urlplayer);" ist der Knackpunkt und ausserhalb der if-Abfrage. Sobald er mit get_headers die Header-Infos auslesen möchte und die URL nicht gefunden wird, stösst er natürlich auf einen Fehler. Und DIESEN Fehler möchte ich abfangen.
            Kann sein, dass es bei mir auch nur kommt, weil das Device offline ist und nicht nur einfach die Datei fehlt. Fehlt die Datei, kann der entfernte Webserver ja noch eine Antwort schicken (und diese kann man später dann abfragen). Ist aber der Webserver tot (oder die URL falsch), so kommt natürlich gar nichts zurück. Und dies ist offenbar mein Problem.

            Kommentar


              #7
              gaert
              Jaja...klar nervt es. Weil ich ja die Ursache des Fehlers kenne und es auch nicht so kritisch ist. Da man nicht einfach das Fehlerlog aus der Edomi Verwaltung löschen kann, muss ich dann mit einem FTP-Programm zuerst das Log löschen. Ist halt alles bisschen mühsam.

              ABER...dieser Nervfaktor zwingt einem auch dazu, dass man das Problem so lösen möchte, dass gar keine Fehler Logs mehr erzeugt werden. Und das ist ja auch immer dein Hintergedanke. Und grundsätzlich unterstütze ich dies auch. (Ein Fehlerlog sollte sauber sein!)

              Somit kritisiere ich es nicht. Es nervt, ja, aber das liegt eher an meiner Faulheit, den Fehler zu beheben. (Was mich aber immerhin zu diesem Thread geführt hat.)

              Wenn mans in Zukunft quittieren kann, bin ich aber auch nicht unglücklich. (Auch wenn dann wieder das Risiko besteht, dass man in Zukunft solche Fehler nicht mehr behebt...)

              Kommentar


                #8
                Zitat von rdeckard Beitrag anzeigen
                Wie kann ich eine URL prüfen, ob sie online ist, ohne schon bei der Prüfung einen PHP-Fehler zu erzeugen?
                Ich würde es mit curl machen statt mit get_headers() und zwar vom Prinzip her in etwa so:

                PHP-Code:

                try {
                    
                $url 'http://192.168.0.245';
                    
                $ch curl_init($url);
                    
                curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
                    
                curl_setopt($ch,CURLOPT_TIMEOUT,1);
                    
                $result curl_exec($ch);
                    if (!
                $result) throw new Exception(curl_error($ch));  
                } catch (
                Exception $e)
                {
                    echo 
                "Exception: ".$e->getMessage()."\n";

                TIMEOUT gibt in Sekunden an, wie lange auf die gewartet werden soll. Wenn erfolgreich kannst du mir $result nach dem catch Bereich weitermachen. Ansonsten kannst du im catch Bereich eine Meldung ins Tracelog schreiben. Dann sollte eigentlich kein Error und keine Warning auftreten.

                Aus dem echo() muss dann natürlich ein writeToTraceLog() werden.

                Kommentar


                  #9
                  Ich habe jetzt zwei Funktionen gefunden, die in diese Richtung gehen. Problem bei solchen Lösungen ist oft, dass sie nicht bei allen Webservern funktionieren. Es gibt Firmen, die keinen direkten Zugriff auf ihren Webserver mögen und dies dann blockieren, somit würde dies einen False Alarm geben. Dann muss man mit User Agents kommen, damit es wie ein Browser aussieht.

                  Ich habe die Funktionen mal in mein LBS eingefügt und erfolgreich getestet. In meinem Fall würde schon eine der beiden Funktionen reichen. Wenn man das Zielsystem kennt und Down und Up getestet hat, kann man mit der Funktion arbeiten, die funktioniert.
                  Ist das Zielsystem jedoch variabel, so muss man u.U. einen grösseren Aufwand betreiben und die Funktionen evtl. ZUSAMMEN verwenden. (Auch dann ist nicht immer 100% sicher, dass es funktioniert.)

                  PHP-Code:

                  if (Visit("http://xxxx"))
                         echo 
                  "Website OK";
                  else
                         echo 
                  "Website DOWN";

                  //if (isDomainAvailable('http://xxxx'))
                  //{
                  //  echo "Website OK";
                  //}
                  //else
                  //{
                  //  echo "Website DOWN";
                  //}



                  function isDomainAvailable($domain)
                  {
                    
                  //check, if a valid url is provided
                    
                  if(!filter_var($domainFILTER_VALIDATE_URL))
                    {
                      return 
                  false;
                    }

                    
                  //initialize curl
                    
                  $curlInit curl_init($domain);
                    
                  curl_setopt($curlInit,CURLOPT_CONNECTTIMEOUT,10);
                    
                  curl_setopt($curlInit,CURLOPT_HEADER,true);
                    
                  curl_setopt($curlInit,CURLOPT_NOBODY,true);
                    
                  curl_setopt($curlInit,CURLOPT_RETURNTRANSFER,true);

                    
                  //get answer
                    
                  $response curl_exec($curlInit);

                    
                  curl_close($curlInit);

                    if (
                  $response) return true;

                    return 
                  false;
                  }

                  function 
                  Visit($url){
                    
                  $agent "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)";$ch=curl_init();
                    
                  curl_setopt ($chCURLOPT_URL,$url );
                    
                  curl_setopt($chCURLOPT_USERAGENT$agent);
                    
                  curl_setopt ($chCURLOPT_RETURNTRANSFER1);
                    
                  curl_setopt ($ch,CURLOPT_VERBOSE,false);
                    
                  curl_setopt($chCURLOPT_TIMEOUT5);
                    
                  curl_setopt($ch,CURLOPT_SSL_VERIFYPEERFALSE);
                    
                  curl_setopt($ch,CURLOPT_SSLVERSION,3);
                    
                  curl_setopt($ch,CURLOPT_SSL_VERIFYHOSTFALSE);
                    
                  $page=curl_exec($ch);
                    
                  //echo curl_error($ch);
                    
                  $httpcode curl_getinfo($chCURLINFO_HTTP_CODE);
                    
                  curl_close($ch);
                    if(
                  $httpcode>=200 && $httpcode<400) return true;
                    else return 
                  false;

                  Für Edomi LBS muss der Code noch etwas angepasst werden (keine echos).

                  Kommentar


                    #10
                    jonofe
                    Danke, das mit dem exception gefällt mir. Deine Routine ist schlank und scheint mir sicherer zu sein. (Zumindest für den richtigen Server Down Fall)

                    Das bringt mich grad noch auf eine andere Idee in einem anderen LBS. Dort laufe ich ab und zu mal bei einem Array in einen ungültigen Bereich, den ich bis jetzt nicht richtig abfangen konnte und es mir dann natürlich ins Edomi Log zurückschlägt. Ein catch könnte das evtl. abfangen.

                    Kommentar


                      #11
                      Zitat von rdeckard Beitrag anzeigen
                      jonofe
                      Dort laufe ich ab und zu mal bei einem Array in einen ungültigen Bereich, den ich bis jetzt nicht richtig abfangen konnte und es mir dann natürlich ins Edomi Log zurückschlägt. Ein catch könnte das evtl. abfangen.

                      Bei arrays hilft auch oft ein

                      PHP-Code:
                      count($array); 
                      insbesondere wenn das Array mit Zahlen beginnend bei 0 indiziert ist oder

                      PHP-Code:
                      if (array_key_exists($key)) ... 
                      um zu prüfen ob ein index überhaupt existiert bevor man drauf zugreift oder

                      PHP-Code:
                      foreach ($array as $index => $value) { ... } 
                      um einfach alle Elemente zu durchlaufen.
                      Damit sollten sich Zugriffe auf ungültige Bereiche eigentlich vermeiden lassen.

                      VG
                      André
                      Zuletzt geändert von jonofe; 15.04.2016, 13:38.

                      Kommentar


                        #12
                        Zitat von rdeckard Beitrag anzeigen
                        coliflower
                        Danke, aber ich weiss nicht, wie mir das weiterhelfen kann? Du hast zwar eine etwas andere Abfrage, aber das Grundproblem müsste bei dir auch auftreten. Siehe dein Code in deiner vorherigen Nachricht: https://knx-user-forum.de/forum/proj...360#post929360
                        Ne sorry, das war dieser Code ...

                        PHP-Code:
                        if ($headers1[0] == 'HTTP/1.1 404 Not Found') {
                            
                        $player__ '{"status":"","time":""}';
                            
                        writeToTraceLog(0,true,'404er is TRUE >> EXIT Player');
                        } else {
                            
                        $player__ file_get_contents('http://'.$E[3]['value'].'/%7E'.$E[5]['value'].'/'.$E[11]['value'].'.json');
                            
                        writeToTraceLog(0,true,'404er do not exists / Player '.$player__);


                        Ich frage hier am WebServer ob eine JSON-Datei liegt oder nicht indem ich den 404er Fehlercode abfrage und wenn die Datei nicht da ist, verwende ICH einen DUMMY-Code ...
                        Anstatt dess Dummy-Codes kannst du ja eine andere Aktion auslösen ...

                        Der "$headers1 = get_headers($urlplayer);" ist der Knackpunkt und ausserhalb der if-Abfrage.
                        Nein, diese Problem habe ich nicht ... Wenn die JSON nicht da ist dann kommt eben der DUMMY zum Einsatz ...
                        Ich gehe davon aus dass du gar kein Url hast wenn sich deine Hardware verabschiedet und du somit die get_headers() in die IF-Abfrage setzten müsstest ... danke ich (sorry, bin kein Programmierer)
                        Danke und LG, Dariusz
                        GIRA | ENERTEX | MDT | MEANWELL | 24VDC LED | iBEMI | EDOMI | ETS5 | DS214+ | KNX/RS232-GW-ROTEL

                        Kommentar


                          #13
                          ABER...dieser Nervfaktor zwingt einem auch dazu, dass man das Problem so lösen möchte, dass gar keine Fehler Logs mehr erzeugt werden. Und das ist ja auch immer dein Hintergedanke. Und grundsätzlich unterstütze ich dies auch. (Ein Fehlerlog sollte sauber sein!)
                          Aber auch dann solltest du dieses mögliche Problem im LBS abfangen, für den Fall ....
                          Zuletzt geändert von coliflower; 15.04.2016, 14:06.
                          Danke und LG, Dariusz
                          GIRA | ENERTEX | MDT | MEANWELL | 24VDC LED | iBEMI | EDOMI | ETS5 | DS214+ | KNX/RS232-GW-ROTEL

                          Kommentar


                            #14
                            Ja, aber wenn der Server nicht da ist, gibt es kein 404!
                            Mfg Micha
                            Qualifizierte und richtige Antworten gibts nur von Leuten, die während des Neustarts des HS Zeit für einen Post haben!

                            Kommentar


                              #15
                              Zitat von vento66 Beitrag anzeigen
                              Ja, aber wenn der Server nicht da ist, gibt es kein 404!
                              Ich gehe davon aus dass du gar kein Url hast wenn sich deine Hardware verabschiedet und du somit die get_headers() in die IF-Abfrage setzten müsstest ... danke ich (sorry, bin kein Programmierer)
                              OK, wenn das mit IF get_geaders() nicht funkt, dann die CURL-Lösung oben (danke).

                              jonofe

                              Muss man in deinem Code auf noch etwas achten wenn man den WebServar auf UP/DOWN abgragt ?
                              Ich denke diesen Code-Schnipsel sollte man jedes Mal einbauen wenn man auf WebServer zugreift ...

                              PHP-Code:
                              try {
                                  
                              $url 'http://192.168.0.245';
                                  
                              $ch curl_init($url);
                                  
                              curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
                                  
                              curl_setopt($ch,CURLOPT_TIMEOUT,1);
                                  
                              $result curl_exec($ch);
                                  if (!
                              $result) throw new Exception(curl_error($ch));  
                              } catch (
                              Exception $e)
                              {
                                  
                              writeToTraceLog('Exception: '.$e->getMessage());

                              Danke und LG, Dariusz
                              GIRA | ENERTEX | MDT | MEANWELL | 24VDC LED | iBEMI | EDOMI | ETS5 | DS214+ | KNX/RS232-GW-ROTEL

                              Kommentar

                              Lädt...
                              X