Jörg: php fwrite()

Hallo,

Kann mir einer sagen, was ich hier falsch mache?

function loggen($var,$file = '2log.txt')
{
    $fp = fopen($file,'a+');
    fwrite($fp,$var."\r\n");
    fclose($fp);
}

loggen("Test");

// ergibt: PHP Fatal error:  Uncaught TypeError: fwrite(): Argument #1 ($stream) must be of type resource, bool given in...

Jörg

  1. Hallo Jörg,

    du hast keine Fehlerprüfung. Der fopen ging schief - warum auch immer - und der fwrite bekam dann FALSE an Stelle des File Handles.

    Gründe für's Fehlschlagen

    • kein Schreibrecht
    • ungültiger Dateiname übergeben
    • Datei ist von anderem Prozess geöffnet

    Rolf

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

      ah ok. Kann es denn sein, dass php7 die Datei noch selber angelegt hat und php8 erwartet, dass die Datei schon existent ist?

      Jörg

      1. Hallo Jörg,

        Kann es denn sein, dass php7 die Datei noch selber angelegt hat und php8 erwartet, dass die Datei schon existent ist?

        nein, das Handbuch sagt hier für mode='a+' ganz klar:

        If the file does not exist, attempt to create it.

        Dein Problem muss also anders gelagert sein.

        Einen schönen Tag noch
         Martin

        --
        "Formschön, wetterfest, zweckfrei, und gegen Aufpreis auch entnehmbar."
        - Loriot, Familien-Original-Benutzer
      2. Hallo Jörg,

        Nein.

        'a+' Zum Schreiben und Lesen geöffnet; platziere den Dateizeiger auf das Dateiende. Existiert die Datei nicht, versuche, diese zu erzeugen. In diesem Modus wirkt sich fseek() nur auf die Leseposition aus; beim Schreiben wird immer angehängt.

        Sieh zu, dass Du Notices und Warnings angezeigt oder geloggt bekommst. Und wenn Du einen Dateinamen als Parameter übergibst, schau ihn Dir an.

        Rolf

        --
        sumpsi - posui - obstruxi
        1. Hallo Rolf, hallo Martin,

          Sieh zu, dass Du Notices und Warnings angezeigt oder geloggt bekommst. Und wenn Du einen Dateinamen als Parameter übergibst, schau ihn Dir an.

          $filename = 'test456.txt';
          $fp = fopen($filename,"a+");
          if(!file_exists($filename)) {
              echo "April,April!";
          } elseif(!is_writable($filename)) {
              echo "Die Datei $filename ist nicht schreibbar";
          } else {
              echo "Alles klar";
          }
          

          ergibt "April,April".

          Jörg

          1. Hallo Rolf, Hallo Martin,

            $filename = 'test456.txt';
            $fp = fopen($filename,"a+");
            if(!file_exists($filename)) {
                echo "April,April!";
            } elseif(!is_writable($filename)) {
                echo "Die Datei $filename ist nicht schreibbar";
            } else {
                echo "Alles klar";
            }
            

            ergibt "April,April".

            Ordner "logs" angelegt, mit Dateirechten 777 versehen und versucht, dorthin zu schreiben, jetzt klappt es.

            Danke für Eure Hilfe.

            Jörg

            1. Hallo,

              $filename = 'test456.txt';
              $fp = fopen($filename,"a+");
              

              du willst also in das Verzeichnis schreiben, in dem das PHP-Script liegt. Mag sein, dass das per Rechtevergabe verboten ist, damit ein Script sich nicht selbst überschreiben oder modifizieren kann.

              Ordner "logs" angelegt, mit Dateirechten 777 versehen und versucht, dorthin zu schreiben, jetzt klappt es.

              Also tatsächlich eine Frage der Berechtigungen.

              Einen schönen Tag noch
               Martin

              --
              "Formschön, wetterfest, zweckfrei, und gegen Aufpreis auch entnehmbar."
              - Loriot, Familien-Original-Benutzer
            2. Ordner "logs" angelegt, mit Dateirechten 777 versehen und versucht, dorthin zu schreiben, jetzt klappt es.

              Der Raktentyp wird Dir das besser erklären können, aber grundsätzlich schrillen bei mir die Alarmglocken, wenn "777" die Lösung sein soll...

              1. Der Raktentyp wird Dir das besser erklären können, aber grundsätzlich schrillen bei mir die Alarmglocken, wenn "777" die Lösung sein soll...

                Kommt darauf an.

                Wenn der Webserver (PHP) die Schreibrechte braucht, dann kann man als normaler Benutzer "meier" mit z.B.

                chown meier:www-data ORDNER;
                chmod 770 ORDNER
                

                die Ordner sparsamer „berechten“, wenn(sic! Der root darf das immer…) man denn Mitglied der Gruppe www-data ist. (www-data sei die Gruppe des Benutzers unter dem der Webserver läuft → Siehe unten.)

                Hat man setfacl zu Verfügung und ist das Dateisystem mit der Option acl gemounted, dann geht auch

                chown meier:meier ORDNER;
                chmod 700 ORDNER;
                setfacl -m www-data:rwx ORDNER
                

                Hat man den Krempel auf einem shared server, dann ist meist die EUID unter der die (PHP)Skripte laufen, mit der UID des Benutzers identisch... Dann reicht von Haus aus

                chmod 700 ORDNER;
                

                Wie man das rausfindet:

                <?php
                header( 'Content-Type: text/plain; charset=utf-8' );
                
                $EUID = posix_geteuid();
                $arr  = posix_getpwuid( $EUID );
                
                print_r( $arr );
                
      3. Moin Jörg,

        Kann es denn sein, dass php7 die Datei noch selber angelegt hat und php8 erwartet, dass die Datei schon existent ist?

        diese Frage könnte eventuell die E_WARNING beantworten, die im Handbuch für fopen spezifiziert wird:

        Fehler/Exceptions

        Im Fehlerfall wird eine E_WARNING ausgegeben.

        Viele Grüße
        Robert

      4. Kann es denn sein, dass php7 die Datei noch selber angelegt hat und php8 erwartet, dass die Datei schon existent ist?

        Darf denn php in dem Ordner(sic!) schreiben?

        (Das Anlegen, Umbenennen, Löschen von Dateien erfordert Schreibrechte am Ordner. Wird häufig übersehen...)

  2. @@Jörg

    Kann mir einer sagen, was ich hier falsch mache?

    Nicht in die Doku zu fopen() geschaut?

    Rückgabewerte: Gibt bei Erfolg eine Dateizeiger-Ressource zurück. Bei einem Fehler wird false zurückgegeben.

    Letzteres ist wohl bei dir der Fall, wenn fwrite() meckert.

    // ergibt: PHP Fatal error:  Uncaught TypeError: fwrite(): Argument #1 ($stream) must be of type resource, bool given in...
    

    🖖 Живіть довго і процвітайте

    --
    When the power of love overcomes the love of power the world will know peace.
    — Jimi Hendrix