Error: Probleme mit der Funktion file()

Hallo Forum, ich habe Probleme mit der Funktion file(). Die löst keinen Error aus, wenn die Datei, oder das Verzeichnis ($file) nicht vorhanden sind.

Mein Code:

if (false === ($loglines = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES)))
{
    exit (error_get_last()); 
}

Es kommt dann nur eine Seite, auf der 'Array' angezeigt wird. Ich lasse am Anfang den ersten Datensatz mit print_r($loglines[0]) ausgeben.

Könnt ihr mir helfen?

Danke

akzeptierte Antworten

  1. Hallo

    ich habe Probleme mit der Funktion file(). Die löst keinen Error aus, wenn die Datei, oder das Verzeichnis ($file) nicht vorhanden sind.

    … ganz so, wie die Doku zu file es sagt.

    Emits an E_WARNING level error if the file does not exist.

    Du solltest dir während der Entwicklung eines Skripts immer die Systemmeldungen, die PHP ausspuckt, anzeigen lassen. Das verschafft Klarheit über die Ursachen diverser Fehler, die sonst nur eine (teilweise) leere Ausgabe verursachen.

    Schreibe dazu folgenden Code an den Anfang des Skripts (bei Arbeit mit Includes ins Hauptskript).

    error_reporting(E_ALL);
    ini_set('display_errors', 1);
    

    Wenn das Skript in den Produktiveinsatz geht, muss der Code, so, wie er da steht, wieder entfernt werden. Eine Fehlerausgabe hat dann in ein internes Logfile zu gehen.

    if (false === ($loglines = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES)))
    {
        exit (error_get_last()); 
    }
    

    Es kommt dann nur eine Seite, auf der 'Array' angezeigt wird.

    Sowohl der Umstand, dass du nicht in deinem exit-Block landest, als auch die Ausgabe von Array spricht dafür, dass da eben doch Daten drinstecken, die ausgelesene Datei also doch vorhanden ist.

    Ich lasse am Anfang den ersten Datensatz mit print_r($loglines[0]) ausgeben.

    Ich würde mir gleich den gesamten Inhalt mit $check = print_r($loglines, true); und an anderer Stelle echo "<pre>". $check ."</pre>"; ausgeben lassen. Das true sorgt dafür, dass keine sofortige Ausgabe an der Stelle, an der der Code notiert ist, erfolgt, sondern die Ausgabe tatsächlich in einer Variable zwischengespeichert wird.

    Tschö, Auge

    --
    „Habe ich mir das nur eingebildet, oder kann der kleine Hund wirklich sprechen?“ fragte Schnapper. „Er behauptet, nicht dazu imstande zu sein“ erwiderte Victor. Schnapper zögerte (…) „Nun …“ sagte er schließlich, „ich schätze, er muss es am besten wissen.“ Terry Prattchett, Voll im Bilde
    1. Danke für die Antwort,

      ich habe Probleme mit der Funktion file(). Die löst keinen Error aus, wenn die Datei, oder das Verzeichnis ($file) nicht vorhanden sind.

      … ganz so, wie die Doku zu file es sagt.

      Emits an E_WARNING level error if the file does not exist.

      Du solltest dir während der Entwicklung eines Skripts immer die Systemmeldungen, die PHP ausspuckt, anzeigen lassen. Das verschafft Klarheit über die Ursachen diverser Fehler, die sonst nur eine (teilweise) leere Ausgabe verursachen.

      Schreibe dazu folgenden Code an den Anfang des Skripts (bei Arbeit mit Includes ins Hauptskript).

      error_reporting(E_ALL);
      ini_set('display_errors', 1);
      

      Das display_errors habe ich jetzt (zum Testen) aktiviert. Error_reporting(E_ALL) hatte ich schon drin.

      Der Pfad stimmt absichtlich nicht; es fehlt der führende Slash.

      Ich bekomme jetzt die Bildschirmmeldung

      Warning: file(var/log/apache2/example.com/access.log): failed to open stream: No such file or directory in /var/www/example.com/htdocs/log/index.php on line 65 Notice: Array to string conversion in /var/www/example.com/htdocs/log/index.php on line 67 Array
      
      

      Da wird aber kein false zurückgegeben, sondern 'Array'

      Das kriege ich auch nicht weg. Wo ist der Fehler?

      Kann ich zwar nicht glauben, aber könnte das auch ein Bug in PHP sein? Ich kann da nirgendwo etwas finden, auch nicht in den Bemerkungen im Handbuch.

      1. Hallo Error,

        nee, ein PHP Bug ist das bestimmt nicht. Die Sprache hat sicherlich Bugs, aber nicht an so prominenter Stelle. Welche PHP Version genau verwendest Du denn? Im Zweifelsfall bau

        echo "PHP Version: " . phpversion() . "\n";
        

        ein.

        Und: Ist das wirklich die Zeile 65, in der die file-Funktion aufgerufen wird? Ich weiß, blöde Frage, aber was Du berichtest, ist vom Typ Kannjagarnichtsein. Entweder findet er die Datei und gibt Inhalt zurück, oder er findet sie nicht, moppert und gibt false zurück. Dass er eine nicht vorhandene Datei anmeckert, aber NICHT false meldet, sollte nicht passieren.

        Rolf

        --
        sumpsi - posui - obstruxi
        1. Hallo RolfB,

          nee, ein PHP Bug ist das bestimmt nicht. Die Sprache hat sicherlich Bugs, aber nicht an so prominenter Stelle. Welche PHP Version genau verwendest Du denn? Im Zweifelsfall bau

          Ich denke schon, dass es ein Bug sein könnte.
          Ich habe das eben mal selber audprobiert.

          Da wird der Fehler einfach nicht durch die nächste Schicht nach außen durchgereicht. Ich teste jetzt mal ein paar der anderen Bequemfunktionen, wie z.B. file_get_contents().

          Mein Testcode. Ich habe den soweit von Error und Auge übernommen.

          <?php  
          
          header("Content-Type: text/plain; charset=utf8");
          error_reporting(E_ALL);
          ini_set('display_errors', 1);
          
          /* Datei ist NICHT vorhanden */
          $file = '/var/www/html/log/access.log.1';
          
          if (false === ($loglines = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES)))
          {
              exit (error_get_last());
          }
          
          print_r($loglines);
          
          ?>
          

          Antwort bei falschem Dateinamen lautet

          <br />
          <b>Warning</b>:  file(/var/www/html/log/access.log.1): failed to open stream: No such file or directory in <b>/var/www/html/test/file-test.php</b> on line <b>9</b><br />
          <br />
          <b>Notice</b>:  Array to string conversion in <b>/var/www/html/test/file-test.php</b> on line <b>11</b><br />
          Array
          

          Der Zugriffsfehler wird scheinbar noch detektiert, aber die Funktion wird dann nicht mit false als Rückgabewert abgebrochen. Da lügt das Manual leider!

          Grüße aus Duderstadt PHP-Freund

          1. Hallo PHP-Freund,

            mein Testcode:

            <?php
            echo "ich bin " . phpversion() . "\n";
            
            $cont = file("foo.txt", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
            if ($cont === false)
               echo "Dat war nix\n";
            else
               var_dump($cont);
            

            Da passt Warnung und Inhalt von $cont immer zusammen. Auch dann, wenn im Root eine Datei foo.txt stand.

            Ich muss mir also nochmal genauer das if-Konstrukt des TO anschauen, ob darin etwas anderes passiert. Es SOLLTE nicht…

            Oder hat PHP einen "Dateisuchpfad"?

            Rolf

            --
            sumpsi - posui - obstruxi
          2. Hallo

            Der Zugriffsfehler wird scheinbar noch detektiert, aber die Funktion wird dann nicht mit false als Rückgabewert abgebrochen. Da lügt das Manual leider!

            Das tut das Manual nicht. Es sagt explizit, dass die Funktion auf einen nicht existierenden Pfad mit einer Warnung und nicht mit false antwortet. Steht da so drin und habe ich für dich so zitiert.

            Tschö, Auge

            --
            „Habe ich mir das nur eingebildet, oder kann der kleine Hund wirklich sprechen?“ fragte Schnapper. „Er behauptet, nicht dazu imstande zu sein“ erwiderte Victor. Schnapper zögerte (…) „Nun …“ sagte er schließlich, „ich schätze, er muss es am besten wissen.“ Terry Prattchett, Voll im Bilde
            1. Hallo Auge,

              Der Zugriffsfehler wird scheinbar noch detektiert, aber die Funktion wird dann nicht mit false als Rückgabewert abgebrochen. Da lügt das Manual leider!

              Das tut das Manual nicht. Es sagt explizit, dass die Funktion auf einen nicht existierenden Pfad mit einer Warnung und nicht mit false antwortet. Steht da so drin und habe ich für dich so zitiert.

              Warum so aggressiv?

              Das Manual sagt aus, dass im Fehlerfall false zurückgegeben wird.

              Upon failure, file() returns false.

              Welcher Fehler dafür zu Grunde liegt, ist vollkommen irrelevant. Das funktionert bei andren Funktionen auch einwandfrei. Ich gebe allerdings zu, dass mir der Bug bisher auch nicht aufgefallen war.

              Ich benutze auf dem Testrecher zur Zeit
              PHP 7.3.31-1~deb10u6 (cli) (built: May 7 2024 00:47:26) ( NTS )

              Grüße
              PHP-Freund

              1. Hallo Forum,

                Der Zugriffsfehler wird scheinbar noch detektiert, aber die Funktion wird dann nicht mit false als Rückgabewert abgebrochen. Da lügt das Manual leider!

                Das tut das Manual nicht. Es sagt explizit, dass die Funktion auf einen nicht existierenden Pfad mit einer Warnung und nicht mit false antwortet. Steht da so drin und habe ich für dich so zitiert.

                Ich benutze auf dem Testrecher zur Zeit
                PHP 7.3.31-1~deb10u6 (cli) (built: May 7 2024 00:47:26) ( NTS )

                Auf einem alten System, das bis eben noch in der Ecke stand, habe ich noch

                PHP 5.4.45-0+deb7u8 (cli) (built: Mar 27 2017 22:43:09)
                

                Da reagiert das System auch schon/noch mackig. Ulkig, ist mir bisher nie aufgefallen. Vermutlich, weil ich meistens fgetcsv() oder str_getcsv() benutze.

                Grüße
                PHP-Freund

              2. Hallo

                Das Manual sagt aus, dass im Fehlerfall false zurückgegeben wird.

                Upon failure, file() returns false.

                Welcher Fehler dafür zu Grunde liegt, ist vollkommen irrelevant. Das funktionert bei andren Funktionen auch einwandfrei. Ich gebe allerdings zu, dass mir der Bug bisher auch nicht aufgefallen war.

                Ich vermute mittlerweile eine implizite Array-zu-String-Konversion bei der Verwendung von error_get_last.

                Tschö, Auge

                --
                „Habe ich mir das nur eingebildet, oder kann der kleine Hund wirklich sprechen?“ fragte Schnapper. „Er behauptet, nicht dazu imstande zu sein“ erwiderte Victor. Schnapper zögerte (…) „Nun …“ sagte er schließlich, „ich schätze, er muss es am besten wissen.“ Terry Prattchett, Voll im Bilde
                1. Hallo Auge,

                  Das Manual sagt aus, dass im Fehlerfall false zurückgegeben wird.

                  Upon failure, file() returns false.

                  Welcher Fehler dafür zu Grunde liegt, ist vollkommen irrelevant. Das funktionert bei andren Funktionen auch einwandfrei. Ich gebe allerdings zu, dass mir der Bug bisher auch nicht aufgefallen war.

                  Ich vermute mittlerweile eine implizite Array-zu-String-Konversion bei der Verwendung von error_get_last.

                  Mein Gott, er hat es!
                  Sooo ein blöder Fehler.

                  Da steckt in lächerlichen zwei relevanten Zeilen Code ein Typ-Fehler, obwohl PHP doch "typfrei" ist, bzw. eine "dynamisch typisierte Sprache" ist, und ich guck stundenlang daran vorbei ;-P

                  Man soll sich eben nicht primen lassen: "Probleme mit file()...".

                  Bei Java hätte man die Ausgabefunktion (echo) für Arrays überladen und gut wär's gewesen.

                  Grüße
                  PHP-Freund

                  1. Hallo PHP-Freund,

                    wie ich schrieb: die Wahrscheinlichkeit eines PHP-Fehlers ist nicht 0, aber doch recht gering. Man muss immer zuerst die eigene Nase putzen.

                    Und da mein eigenes Testprogramm klar zeigte, dass file() false zurückgibt, wenn es die Warnung wirft, musste es einen anderen Grund geben.

                    Und den hab ich dann auch übersehen. Auge - nomen est omen 😉

                    Rolf

                    --
                    sumpsi - posui - obstruxi
            2. Hallo Auge,

              da steht:

              Return Values

              Returns the file in an array. Each element of the array corresponds to a line in the file, with the newline still attached. Upon failure, file() returns false.

              Errors/Exceptions

              Emits an E_WARNING level error if the file does not exist.

              Man kann nun fragen, was "upon failure" bedeutet. Ist der Zugriff auf eine nicht existierende Datei ein Scheitern?

              In meinem Testscript gab file() entweder die Warnung aus und false zurück, oder sie gab keine Warnung aus und den Dateiinhalt zurück. Ich würde deshalb behaupten: "file does not exist" impliziert "upon failure".

              Ich habe mein Script /temp/test.php nochmal erweitert:

              <?php
              accessFile("foo.txt");
              accessFile("test.php");
              accessFile("/temp/foo.txt");
              accessFile("/temp/test.php");
              accessFile("temp/foo.txt");
              accessFile("temp/test.php");
              
              function accessFile($name) {
                 echo "\naccess $name\n\n";
              
                 if (false === ($cont = file($name, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES)))
                    echo "\nDat war nix";
                 else
                    echo "\nHabe ".count($cont)." Zeilen gefunden";
              }
              

              /temp/foo.txt gibt es nicht. Ich bekomme konsequent für foo.txt die Warnung und die Ausgabe "Dat war nix". Für test.php bekomme im Aufruf 2 und 4 Erfolg, wenn /temp das aktuelle Verzeichnis ist, und im Aufruf 4 und 6 Erfolg, wenn / das aktuelle Verzeichnis ist. Also das, was man erwarten sollte.

              Das habe ich mit PHP auf der Kommandozeile und als FCGI-Anwendung unter IIS gemacht. Mit PHP 7.4.28 und mit PHP 8.1.4 (das sind die, die auf meinem PC zum Testen rumfliegen). Ich lad's aber auch gleich auf meinen Webserver hoch.

              Rolf

              --
              sumpsi - posui - obstruxi
              1. Hallo

                [edit] eine Fußnote eingefügt und an zwei Stellen die Wortwahl korrigiert [/edit]

                Ich habe mein Script /temp/test.php nochmal erweitert:

                <?php
                accessFile("foo.txt");
                accessFile("test.php");
                accessFile("/temp/foo.txt");
                accessFile("/temp/test.php");
                accessFile("temp/foo.txt");
                accessFile("temp/test.php");
                
                function accessFile($name) {
                   echo "\naccess $name\n\n";
                
                   if (false === ($cont = file($name, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES)))
                      echo "\nDat war nix";
                   else
                      echo "\nHabe ".count($cont)." Zeilen gefunden";
                }
                

                /temp/foo.txt gibt es nicht. Ich bekomme konsequent für foo.txt die Warnung und die Ausgabe "Dat war nix".

                Und jetzt muss ich wohl einen langhalsigen Wasservogel ververben. In anderen Worten: Mir schwant etwas.

                Error spricht (mit eingeschaltetem Error-Reporting) von folgender Ausgabe.

                Warning: file(var/log/apache2/example.com/access.log): failed to open stream: No such file or directory in /var/www/example.com/htdocs/log/index.php on line 65
                Notice: Array to string conversion in /var/www/example.com/htdocs/log/index.php on line 67 Array
                

                Ich versuche das mal auseinanderzudröseln.

                Die Datei existiert nicht, woraus die offensichtliche Warnung resultiert.

                Warning: file(var/log/apache2/example.com/access.log): failed to open stream: No such file or directory in /var/www/example.com/htdocs/log/index.php on line 65
                

                Ich war fälschlicherweise davon ausgegangen, dass die Warnung alles ist, aber file generiert sowohl die Warnung, gibt aber zusätzlich auch false zurück. Womit wir bei der mutmaßlichen Ursache für die Ausgabe von „Array“ sind.

                Notice: Array to string conversion in /var/www/example.com/htdocs/log/index.php on line 67 Array
                

                Die Ausgabe stammt, so vermute ich, nicht von file, sondern aus der Fehlerbehandlung von Error[1], die laut dem Eröffnungsposting folgendermaßen aussieht.

                if (false === ($loglines = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES)))
                {
                     exit (error_get_last());
                }
                

                Der Code springt also sehr wohl in den Fehlerblock und beendet das Skript, wobei mit error_get_last eine Ausgabe der Ausgabe Fehlermeldungen erzeugt werden soll. Für die Funktion error_get_last ist als Rückgabewert ein assoziatives Array angegeben. Dieses Array wird mit exit (error_get_last()); aber in einen String umgewandelt, der schlicht „Array“ lautet.

                Kein Bug in file, sondern, wenn ich richtig liege, nur eine falsche Benutzung von error_get_last.

                Tschö, Auge

                --
                „Habe ich mir das nur eingebildet, oder kann der kleine Hund wirklich sprechen?“ fragte Schnapper. „Er behauptet, nicht dazu imstande zu sein“ erwiderte Victor. Schnapper zögerte (…) „Nun …“ sagte er schließlich, „ich schätze, er muss es am besten wissen.“ Terry Prattchett, Voll im Bilde

                1. Dazu passt auch, dass der zweite Fehler zwei Zeilen nach dem ersten auftritt. ↩︎

                1. Hallo Auge,

                  aua. AUA. Natürlich.

                  Die Ausgabe von error_get_last() hatte ich gar nicht auf dem Schirm.

                  Aber hier auch noch mal mein Letztstand (mit print_r auf den Errors):

                  https://www.borchmann-one.de/selfhtml/test.php

                  Mein Web-Rootpath bei Manitu beginnt mit /home/sites/sitennnnn, nicht /var/www.

                  Rolf

                  --
                  sumpsi - posui - obstruxi
                2. Hi,

                  Und jetzt muss ich wohl einen langhalsigen Wasservogel ververben.

                  Da war mein spontaner Gedanke: Du mußt reihern …

                  In anderen Worten: Mir schwant etwas.

                  Ach so …

                  cu,
                  Andreas a/k/a MudGuard

                  1. Hallo

                    Und jetzt muss ich wohl einen langhalsigen Wasservogel ververben.

                    Da war mein spontaner Gedanke: Du mußt reihern …

                    Das gehört auch in den Kreis der möglichen Auslegungen. 😆

                    Tschö, Auge

                    --
                    „Habe ich mir das nur eingebildet, oder kann der kleine Hund wirklich sprechen?“ fragte Schnapper. „Er behauptet, nicht dazu imstande zu sein“ erwiderte Victor. Schnapper zögerte (…) „Nun …“ sagte er schließlich, „ich schätze, er muss es am besten wissen.“ Terry Prattchett, Voll im Bilde
                3. Hallo Auge,

                  Ich versuche das mal auseinanderzudröseln.

                  Die Datei existiert nicht, woraus die offensichtliche Warnung resultiert.

                  Warning: file(var/log/apache2/example.com/access.log): failed to open stream: No such file or directory in /var/www/example.com/htdocs/log/index.php on line 65
                  

                  Ich war fälschlicherweise davon ausgegangen, dass die Warnung alles ist, aber file generiert sowohl die Warnung, gibt aber zusätzlich auch false zurück. Momit wir bei der mutmaßlichen Ursache für die Ausgabe von „Array“ sind.

                  Notice: Array to string conversion in /var/www/example.com/htdocs/log/index.php on line 67 Array
                  

                  Die Ausgabe stammt, so vermute ich, nicht von file, sondern aus der Fehlerbehandlung von Error[1], die laut dem Eröffnungsposting folgendermaßen aussieht.

                  if (false === ($loglines = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES)))
                  {
                       exit (error_get_last());
                  }
                  

                  Der Code springt also sehr wohl in den Fehlerblock und beendet das Skript, wobei mit error_get_last eine Ausgabe der Ausgabe Fehlermeldungen erzeugt werden soll. Für die Funktion error_get_last ist als Rückgabewert ein assoziatives Array angegeben. Dieses Array wird mit exit (error_get_last()); aber in einen String umgewandelt, der schlicht „Array“ lautet.

                  Kein Bug in file, sondern, wenn ich richtig liege, nur eine falsche Benutzung von error_get_last.

                  Gut erläutert!

                  Ich zieh' meinen virtuellen Hut.
                  Ich habe stundenlang an der Lösung vorbeigeschaut.

                  Man muss also jedes Statement möglichst einzeln untersuchen, wenn so einen Fehler hat.

                  Selber Tschö
                  PHP-Freund


                  1. Dazu passt auch, dass der zweite Fehler zwei Zeilen nach dem ersten auftritt. ↩︎

                4. Hallo alle,

                  herzlichen Dank für eure Hilfe. Während ich mich auf Arbeit ausgeruht habe, habt Ihr das Problem gelöst. Das finde ich Spitze!

                  Jedenfalls muss ich mir das jetzt nochmal alles genau ansehen. Die Fehlerermittlung mit error_get_last() war nur der erste Versuch für eine dynamische Fehlerbearbeitung.

                  Gibt es eigentlich konkrete Fehlernummern, oder muss man sich mit den Fehlertexten aus ['message'] abfinden?

                  Danke nochmal ganz doll

                  1. Hallo Error,

                    du bekommst lediglich den Fehlertyp, der den E_-Konstanten entspricht. Also 2 für E_WARNING, 1 für E_ERROR oder 8 für E_NOTICE.

                    Eine Nummerierung der Fehler, so dass man konkret auf einen bestimmten Fehler reagieren kann, scheint nicht vorgesehen, d.h. wenn Du auf Texte abfragst und eine neue PHP Version den Text ändert, bist Du gekniffen.

                    Es ist aber auch sehr selten, dass eine Differnzierung zwischen Fehlerursachen sinnvoll ist. Wenn Du zwischen "Datei existiert nicht" und "Datei kann nicht gelesen werden" unterscheiden willst, dann prüfe lieber exakt diesen Sachverhalt im Dateisystem. Auch wenn es dabei zu Ungenauigkeiten kommen kann, weil sich zwischen Prüfung und Verwendung die Welt geändert hat. Bei der access.log Datei des Apache kann es zum Beispiel vorkommen, dass Du die Datei auf Existenz prüfst, und JUST NUN ist der Moment, wo logrotate die Logdatei umschaltet. Dafür wird die alte access.log umbenannt und eine leere access.log angelegt. Exakt dazwischen gibt's einen Moment, wo die Datei nicht existiert. Sehr unwahrscheinlich, dass Du diesen Moment triffst, aber nicht auszuschließen. Es hängt dann auch an der logrotate-Konfiguration, ob der Apache während der Rotation gestoppt wird oder nicht. Bei uns zum Beispiel ist das nicht so, da wird umbenannt und dann dem Apache per postrotate-Script gesagt, er soll sich neu laden.

                    Rolf

                    --
                    sumpsi - posui - obstruxi
      2. Hallo

        Ich habe mal das Posting etwas umgestellt und speziell die beiden Meldungen auseinandergenommen.

        Warning: file(var/log/apache2/example.com/access.log): failed to open stream: No such file or directory in /var/www/example.com/htdocs/log/index.php on line 65
        

        Der Pfad stimmt absichtlich nicht; es fehlt der führende Slash.

        Du hast also einen nicht existierenden Pfad angesprochen, um das Verhalten im Fehlerfall zu prüfen? Die Funktion tut jedenfalls das, was das HHandbuch sagt. Existiert die Datei nicht am angegebenen Ort, reagiert die Funktion mit einer Warnung. Mit false reagiert die Funktion in einem solchen Fall jedoch nicht.

        Da wird aber kein false zurückgegeben, sondern 'Array'

        Notice: Array to string conversion in /var/www/example.com/htdocs/log/index.php on line 67 Array
        

        In Zeile 67 wird also ein Array zu einem String, weshalb deine Ausgabe auch „Array“ lautet. Das ist wohl ein Folgefehler.

        Das kriege ich auch nicht weg. Wo ist der Fehler?

        Kurzfassung: in deinem Code.

        Langfassung: da wir bisher deinen Beispielcode nur in den gezeigten Bruchstücken kennen, können wir dazu nur Vermutungen anstellen.

        Was du erst einmal prüfen solltest, ist, ob der Benutzer, mit dem PHP ausgeführt wird, auf das Log überhaupt zugreifen darf. Wenn nicht, existiert die Datei für PHP nämlich nicht. Dafür kannst du die Funktion is_readable benutzen. Die gibt true nur dann zurück, wenn die Datei existiert und lesbar ist, sonst immer false.

        Falls das das Problem nicht aufklärt, solltest du uns auch etwas mehr Code zeigen.

        Kann ich zwar nicht glauben, aber könnte das auch ein Bug in PHP sein?

        Die Funktion file ist so alt, dass ein Bug wohl nicht unbemerkt geblieben wäre.

        Tschö, Auge

        --
        „Habe ich mir das nur eingebildet, oder kann der kleine Hund wirklich sprechen?“ fragte Schnapper. „Er behauptet, nicht dazu imstande zu sein“ erwiderte Victor. Schnapper zögerte (…) „Nun …“ sagte er schließlich, „ich schätze, er muss es am besten wissen.“ Terry Prattchett, Voll im Bilde
        1. Hallo Auge,

          Du hast also einen nicht existierenden Pfad angesprochen, um das Verhalten im Fehlerfall zu prüfen? Die Funktion tut jedenfalls das, was das HHandbuch sagt. Existiert die Datei nicht am angegebenen Ort, reagiert die Funktion mit einer Warnung. Mit false reagiert die Funktion in einem solchen Fall jedoch nicht.

          [...]

          Das kriege ich auch nicht weg. Wo ist der Fehler?

          Kurzfassung: in deinem Code.

          FALSE

          Ich habe mir mal die kleine Mühe gemacht, und habe die Aussage von Error überprüft. Er/Sie hat Recht! Selbstverständlich habe ich alternativ auch auf eine vorhandene Datei zugegriffen. Die wurde dann einwandfrei wie erwartet geladen und angezeigt.

          Und die Verwendung eines vorgeschalteten is_readable() ist schlichtweg falsch, da man damit einen Zeit-Zugriffsfehler (TOCTTOU) riskiert.

          Besser wäre es daher, das FALSE abzufragen und der Funktion dafür ein @ voranzustellen, da man die Fehlerprüfung hier selber vornimmt.

          Grüße
          PHP-Freund

          1. Hallo

            Du hast also einen nicht existierenden Pfad angesprochen, um das Verhalten im Fehlerfall zu prüfen? Die Funktion tut jedenfalls das, was das HHandbuch sagt. Existiert die Datei nicht am angegebenen Ort, reagiert die Funktion mit einer Warnung. Mit false reagiert die Funktion in einem solchen Fall jedoch nicht.

            [...]

            Das kriege ich auch nicht weg. Wo ist der Fehler?

            Kurzfassung: in deinem Code.

            FALSE

            Ich habe mir mal die kleine Mühe gemacht, und habe die Aussage von Error überprüft. Er/Sie hat Recht!

            Hast du den entsprechenden Kommentar auf der Manual-Seite hinterlassen?

            Selbstverständlich habe ich alternativ auch auf eine vorhandene Datei zugegriffen. Die wurde dann einwandfrei wie erwartet geladen und angezeigt.

            Und die Verwendung eines vorgeschalteten is_readable() ist schlichtweg falsch, da man damit einen Zeit-Zugriffsfehler (TOCTTOU) riskiert.

            Häää? Die Benutzung der Funktion sollte einer einmaligen Überprüfung der Lesbarkeit einer Datei für den PHP-Systembenutzer dienen.

            Tschö, Auge

            --
            „Habe ich mir das nur eingebildet, oder kann der kleine Hund wirklich sprechen?“ fragte Schnapper. „Er behauptet, nicht dazu imstande zu sein“ erwiderte Victor. Schnapper zögerte (…) „Nun …“ sagte er schließlich, „ich schätze, er muss es am besten wissen.“ Terry Prattchett, Voll im Bilde
            1. Hallo Auge,

              Und die Verwendung eines vorgeschalteten is_readable() ist schlichtweg falsch, da man damit einen Zeit-Zugriffsfehler (TOCTTOU) riskiert.

              Häää? Die Benutzung der Funktion sollte einer einmaligen Überprüfung der Lesbarkeit einer Datei für den PHP-Systembenutzer dienen.

              Ich kenne Error nicht und weiß daher nicht, was noch entwickelt werden soll. Daher würde ich auch hier keine schlampige Programmiertechnik empfehlen, sondern ordentliche Fehlerprüfungen.

              Grüße
              PHP-Freund

              ("nach Diktat verreist")

              1. Hallo PHP-Freund,

                Und die Verwendung eines vorgeschalteten is_readable() ist schlichtweg falsch, da man damit einen Zeit-Zugriffsfehler (TOCTTOU) riskiert.

                Häää? Die Benutzung der Funktion sollte einer einmaligen Überprüfung der Lesbarkeit einer Datei für den PHP-Systembenutzer dienen.

                Ich kenne Error nicht und weiß daher nicht, was noch entwickelt werden soll. Daher würde ich auch hier keine schlampige Programmiertechnik empfehlen, sondern ordentliche Fehlerprüfungen.

                Genau diese mögliche Race-Condition war der Grund für meinen Versuch mit error_get_last().

                Zur Zeit erstelle ich diverse Listen mit Files (Bildern, Texten, usw) aus einem eigenen kleinen Kontaktforum. Der Zugriff mit file() auf *.log war nur als Beispiel gedacht. Da kann es immer Änderungen geben zwischen der Listenerstellung und der Bearbeitung von Einträgen.

                Jetzt weiß ich auch, dass ich im Netz nach "Laufzeitfehler" suchen muss. Mir war der Unterschied zwischen Programmierfehler und Laufzeitfehler bisher nicht wirklich bewusst.

                Da tut sich aber das nächste Problemchen auf. Ich vermute, dass ich dafür ein neues Posting machen muss? Ist ein anderes Thema: wie kann ich in einer Tabelle ohne Javascript Zellen als Schalter für POST sensibel machen? Ich habe das mit <button> geschafft. Das hat aber den Nachteil, dass man den Inhalt dann nicht mehr markieren kann.

                Wäre schön, wenn ich auch hierfür Hilfe bekommen könnte. Diesmal bevor ich Fehler einbaue 😀

                Mein Name ist Jens und nicht error. Das war ein Eingabefehler.

                Danke
                Jens

                1. Hallo Jens,

                  was Du mit "Tabellenzeile POST-sensibel machen" meinst, habe ich noch nicht ganz verstanden. Möchtest Du, dass bei einem Klick irgendwo in dieser Zeile ein irgendwie gearteter POST-Request an den Server geht?

                  Das ist schwierig, vor allem, wenn Du Inhalte der Zeile noch markieren und kopieren können willst.

                  Ich würde da eher pro Zeile einen Button erzeugen, der explizit für diese Zeile den POST auslöst.

                  Aber vielleicht verstehe ich Dich ja auch miss. Hast Du ein Onlinebeispiel und eine genauere Beschreibung dessen, was passieren soll?

                  Rolf

                  --
                  sumpsi - posui - obstruxi
            2. Und die Verwendung eines vorgeschalteten is_readable() ist schlichtweg falsch, da man damit einen Zeit-Zugriffsfehler (TOCTTOU) riskiert.

              Häää? Die Benutzung der Funktion sollte einer einmaligen Überprüfung der Lesbarkeit einer Datei für den PHP-Systembenutzer dienen.

              Naja. Der PHP-Freund hat nicht ganz unrecht.

              Zwischen is_readable() und dem eigentlichen Lesen kann die Datei auf Grund der Bemühungen eines anderen Prozesses verschwinden, die Rechte können sich ändern e.t.c. pp. Gerade im Hinblick auf das weiter oben gezeigte Error-Log wird es im Hinblick auf logrotate „heiß“.

              Also:

              <?php
              if ( $rows = file( '/var/log/apache2/example.com/access.log' ) ) {
                   print_r( $rows );
              } else {
                   echo 'Fehler.';
              }
              

              Die Verschachtelung ist „eher ungünstig“. Könnte man auch herumdrehen:

              <?php
              if ( ! $rows = file( '/var/log/apache2/example.com/access.log' ) ) {
                   echo 'Fehler.';
              }
              print_r( $rows );
              

              Das gibt aber Mecker(), wenn man sich an Code-Standards halten soll.

              Es geht also besser, z.B. kann man aus der Warnung einen Fehler machen, in dem man einen error-handler definiert:

              <?php
              set_error_handler(
                  function( $errNo, $errStr, $errFile, $errLine ) {
                      if (0 === error_reporting()) {
                          return false;
                      }
                      throw new ErrorException( $errStr, 0, $errNo, $errFile, $errLine );
                  }
              );
              
              try {
                  $rows = file( '/var/log/apache2/access.log' );
              } catch ( ErrorException $e ) {
                  echo 'Fehler....';    
              }
              restore_error_handler();
              print_r( $rows );
              
              

              das …

              echo 'Fehler....';
              

              … ist in beiden Varianten natürlich nur ein Platzhalter wie das

              print_r( $rows );
              
              1. Hallo

                Und die Verwendung eines vorgeschalteten is_readable() ist schlichtweg falsch, da man damit einen Zeit-Zugriffsfehler (TOCTTOU) riskiert.

                Häää? Die Benutzung der Funktion sollte einer einmaligen Überprüfung der Lesbarkeit einer Datei für den PHP-Systembenutzer dienen.

                Naja. Der PHP-Freund hat nicht ganz unrecht.

                Race Conditions hin oder her, ich ging der Einfachheit nicht davon aus, dass das auf Errors Server/Webspace andauernd passieren würde, gerade immer dann, wenn er das Skript auszuführen gedenkt. Allerdings hatte ich, als ich das Posting mit dem Vorschlag, is_readable() zu benutzen, schon nicht mehr auf dem Schirm, dass Error absichtlich einen nicht existierenden Pfad für seinen Test benutzt. Die Funktion is_readable() muss in diesem Szenario immer false zurückgeben. Aber nochmal, mir ging es nicht um einen Produktiveinsatz, sondern darum, mal schnell nachzuschauen, ob eventuell ein Berechtigungsproblem Ursache des beobachteten Verhaltens ist.

                Mittlerweile sind wir ja soweit, zu vermuten, dass die Ursache für das beobachtete Verhalten überhaupt nicht in der Funktion file zu suchen ist.

                Tschö, Auge

                --
                „Habe ich mir das nur eingebildet, oder kann der kleine Hund wirklich sprechen?“ fragte Schnapper. „Er behauptet, nicht dazu imstande zu sein“ erwiderte Victor. Schnapper zögerte (…) „Nun …“ sagte er schließlich, „ich schätze, er muss es am besten wissen.“ Terry Prattchett, Voll im Bilde
    2. Hallo Auge,

      Du solltest dir während der Entwicklung eines Skripts immer die Systemmeldungen, die PHP ausspuckt, anzeigen lassen. Das verschafft Klarheit über die Ursachen diverser Fehler, die sonst nur eine (teilweise) leere Ausgabe verursachen.

      Bitte beachte auch den Unterschied zwischen Entwicklungsfehlern und (variablen) Laufzeitfehlern. Hier soll augenscheinlich ein möglicher Laufzeitfehler abgefangen werden.

      Grüße
      PHP-Freund

  2. Hallo

    Mein Code:

    if (false === ($loglines = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES)))
    {
        exit (error_get_last()); 
    }
    

    Bau den Code zu Testzwecken mal bitte folgendermaßen um.

    if (false === ($loglines = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES)))
    {
        print_r (error_get_last()); 
        exit; 
    }
    

    Tschö, Auge

    --
    „Habe ich mir das nur eingebildet, oder kann der kleine Hund wirklich sprechen?“ fragte Schnapper. „Er behauptet, nicht dazu imstande zu sein“ erwiderte Victor. Schnapper zögerte (…) „Nun …“ sagte er schließlich, „ich schätze, er muss es am besten wissen.“ Terry Prattchett, Voll im Bilde