Probleme mit der Funktion file()
Error
- fehlersuche
- php
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
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
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.
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
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
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
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
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
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
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
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
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
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
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
Dazu passt auch, dass der zweite Fehler zwei Zeilen nach dem ersten auftritt. ↩︎
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
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
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
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
generiertsowohldie Warnung, gibt aber zusätzlich auchfalse
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 derAusgabeFehlermeldungen erzeugt werden soll. Für die Funktionerror_get_last
ist als Rückgabewert ein assoziatives Array angegeben. Dieses Array wird mitexit (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 vonerror_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
Dazu passt auch, dass der zweite Fehler zwei Zeilen nach dem ersten auftritt. ↩︎
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
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
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
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
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
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")
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
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
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 );
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.
Tschö, Auge
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
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