Felix Riesterer: fputs schreibt nix... verstehe die Welt nimmer!

Liebe PHP-Fachleute,

ich habe mir ein Script geschrieben, das eigentlich zweimal dasselbe tut. Aber einmal erreiche ich den gewünschten Effekt _nicht_, obwohl das Vorgehen in beiden Fällen identisch ist. Das Error-Log (E_ALL) schweigt stille...

Ich definiere zwei Funktionen, die jeweils dasselbe tun:
1. Einen XML-String erzeugen
2. XML-Datei zum Schreiben öffnen
3. XML-String in diese Datei schreiben (versagt bei einer Funktion aus unerklärlichen Gründen!!!)
4. XML-Datei schließen
5. Ende der Funktion

Hier mein Code:

// speichere alle Bilder  
function speichere_alle_bilder() {  
    // alte XML-Datei holen und XML-Inhalte löschen (standalone-DTD erhalten)  
    $xml = preg_replace('~^(?is)(.*<AlleBilder>[\r\n]+).*(</AlleBilder.*)$~', '\\1\\2', implode('', file($_SERVER['pg-cms']['datendatei']['alle-bilder'])));  
    $xml_bilder = '';  
    foreach ($_SERVER['pg-cms']['alle-bilder'] as $datei) {  
        $xml_bilder .= "\t<Bild ";  
        $xml_bilder .= 'URL="'.$datei['url'].'" ';  
        $xml_bilder .= 'Groesse="'.$datei['groesse'].'" ';  
        $xml_bilder .= 'Abmessungen="'.$datei['abmessungen'].'" ';  
        if ($datei['geschuetzt'] == 'ja')  
            $xml_bilder .= 'Geschuetzt="ja" ';  
        $xml_bilder .= "/>\r\n";  
    }  
  
    $xml = preg_replace('~(?is)(</AlleBilder.*)$~', $xml_bilder.'\\1', $xml);  
  
    $datei = fopen($_SERVER['pg-cms']['datendatei']['alle-bilder'], 'wb+');  
    fputs($datei, $xml); // Schreibvorgang scheint nicht ausgeführt zu werden!!! $xml ist definitv _kein_ Leerstring!  
    // weitere fputs-Anweisungen hier bewirken auch keine Befüllung der Datei  
    fclose($datei);  
}  
  
  
// speichere alle HTML-Dateien  
function speichere_alle_html_dateien() {  
    // alte XML-Datei holen und XML-Inhalte löschen (standalone-DTD erhalten)  
    $xml = preg_replace('~^(?is)(.*<AlleSeiten>[\r\n]+).*(</AlleSeiten.*)$~', '\\1\\2', implode('', file($_SERVER['pg-cms']['datendatei']['alle-html-dateien'])));  
    $xml_neu = '';  
    foreach ($_SERVER['pg-cms']['alle-html-dateien'] as $key => $value) {  
        $xml_neu .= "\t".'<Seite URL="'.$key;  
        $xml_neu .= '" Modified="'.$value['modified'].'">'."\r\n";  
        $xml_neu .= "\t\t<Titel><![CDATA[";  
        $xml_neu .= html_entity_decode($value['titel']);  
        $xml_neu .= "]]></Titel>\r\n\t</Seite>\r\n";  
    }  
  
    $xml = preg_replace('~(?is)(</AlleSeiten.*)$~', $xml_neu.'\\1', $xml);  
  
    $datei = fopen($_SERVER['pg-cms']['datendatei']['alle-html-dateien'], 'wb+');  
    fputs($datei, $xml);  
    fclose($datei);  
}

Es ist mir völlig unerklärlich, warum die Funktion "speichere_alle_html_dateien" erfolgreich ihren XML-Code in die geöffnete Datei schreiben kann, während bei der Funktion "speichere_alle_bilder" die XML-Datei eine leere (0 Bytes) Datei bleibt. Offensichtlich wird die Funktion fputs nicht korrekt ausgeführt (der XML-String ist korrekt erzeugt worden und vorhanden!).

Das Problem trat bei mir auf zweierlei Windoof-Kisten, als auch unter einer SuSE mit jeweils einem Apachen2 und PHP5 auf (genauere Versionen: win32 apache2.2.3 PHP5.1.6, SuSE10.0 Apache+PHP wie mitgeliefert(?)). Dateirechte können auch nicht das Problem erklären, denn unter SuSE stehen alle auf 0777. Ich versteh's einfach nicht. o_O

Wer weiß Rat?

Liebe Grüße aus Ellwangen,

Felix Riesterer.

  1. Hallo Felix.

    Es ist mir völlig unerklärlich, warum die Funktion "speichere_alle_html_dateien" erfolgreich ihren XML-Code in die geöffnete Datei schreiben kann, während bei der Funktion "speichere_alle_bilder" die XML-Datei eine leere (0 Bytes) Datei bleibt. Offensichtlich wird die Funktion fputs nicht korrekt ausgeführt (der XML-String ist korrekt erzeugt worden und vorhanden!).

    Was gibt fputs() im jeweiligen Fall zurück?

    Das Problem trat bei mir auf zweierlei Windoof-Kisten, als auch unter einer SuSE mit jeweils einem Apachen2 und PHP5 auf (genauere Versionen: win32 apache2.2.3 PHP5.1.6, SuSE10.0 Apache+PHP wie mitgeliefert(?)). Dateirechte können auch nicht das Problem erklären, denn unter SuSE stehen alle auf 0777.

    Warum machst du eine normale Textdatei noch immer ausführbar?

    Einen schönen Donnerstag noch.

    Gruß, Mathias

    --
    ie:% fl:| br:< va:) ls:& fo:) rl:( n4:~ ss:) de:] js:| mo:| zu:)
    debian/rules
    1. Lieber Mathias,

      Was gibt fputs() im jeweiligen Fall zurück?

      bei der "kranken" Funktion  steht da (ohne Anführungszeichen): "124968". Das ist wohl die Länge des zu schreibenden Strings...

      Warum machst du eine normale Textdatei noch immer ausführbar?

      *g*
      Weil ich im Konqueror für das komplette Stammverzeichnis rekursiv die Dateirechte setzte, nachdem ich die Dateien vom Memorystick (FAT32) herüberkopiert hatte, und Konqueror mich das Ausführbar-Bit bei Dateien nicht getrennt einstellen lies. Verzeichnisse müssen ausführbar sein, sonst komme ich nicht an ihren Inhalt, meine ich mich zu erinnern, und ich wollte sicherstellen, dass für Besitzer, Gruppe und Sonstige sowohl das Lesen, als auch das Schreiben aktiviert war, um nicht an den Dateirechten zu scheitern.

      Und über die Konsole hätte ich jetzt nicht gewusst, wie ich das mal eben auf die Schnelle hätte machen können, da meine Linux-Kenntnisse sehr begrenzt sind.

      Liebe Grüße aus Ellwangen,

      Felix Riesterer.

      1. fputs liefert einen numerischen Wert,
        fopen liefert eine "Resource ID" mit ebenfalls numerischem Wert.

        Ich verstehe es nicht. Bereits vorhandene Inhalte werden wie erwartet gelöscht, aber warum landet nix von dem String in der Datei???

        Liebe Grüße aus Ellwangen,

        Felix Riesterer.

      2. Hallo Felix.

        Was gibt fputs() im jeweiligen Fall zurück?

        bei der "kranken" Funktion  steht da (ohne Anführungszeichen): "124968". Das ist wohl die Länge des zu schreibenden Strings...

        Also *sollte* etwas erfolgreich geschrieben worden sein. Sehr merkwürdig. Kannst du deinen Testfall noch etwas weiter herunterminimieren. (Natürlich möglichst soweit, bis du den Fehler selbst entdeckst.)

        Warum machst du eine normale Textdatei noch immer ausführbar?

        […] über die Konsole hätte ich jetzt nicht gewusst, wie ich das mal eben auf die Schnelle hätte machen können, da meine Linux-Kenntnisse sehr begrenzt sind.

        Das Archiv weiß wie so oft eine Antwort.

        Einen schönen Freitag noch.

        Gruß, Mathias

        --
        ie:% fl:| br:< va:) ls:& fo:) rl:( n4:~ ss:) de:] js:| mo:| zu:)
        debian/rules
        1. Lieber Mathias,

          Also *sollte* etwas erfolgreich geschrieben worden sein. Sehr merkwürdig. Kannst du deinen Testfall noch etwas weiter herunterminimieren. (Natürlich möglichst soweit, bis du den Fehler selbst entdeckst.)

          Ach, es war einfach schon viel zu spät. Aber ich habe den Fehler gefunden. Ich hatte in einem Rest des vorherigen Scriptes, welches ich durch obiges zu ersetzen gedachte, die Schreiboperationen noch nicht entfernt. Daher pfuschte dieser Rest-Code meiner neuen Funktion ins Handwerk.

          Ich gehe jetzt schlafen.

          Das Archiv weiß wie so oft eine Antwort.

          ...ja, aber nicht, wenn ich mal eben zwischen Tür und Angel nur ein paar Dateien unter einer Linux-Umgebung testen möchte. Da dieser Rechner (ein Laptop) nicht in einem Netzwerk eingebunden ist, sehe ich zwar den Unsinn ein, aber nicht, dass ich gegen selbigen jetzt etwas unternehmen sollte. Außerdem war mir das Archiv offline gerade nicht verfügbar...

          Aber ich danke Dir trotzdem. Bist 'ne treue Seele, wie so manche Stammposter hier im Forum.

          Liebe Grüße aus Ellwangen,

          Felix Riesterer.