Marcus: Unerklärliche Warnung bei foreach

Guten Morgen, liebe Mitstreiter,

Ich wollte mir für mein Gästebuch eine Reloadsperre einbauen, die folgendermassen aufgebaut ist:

function ReloadPruefen ($IP, $Zeitstempel)
{
  $DateiZeiger = fopen ("CSV.IP.csv", "r");

if ($DateiZeiger)
  {
    flock ($DateiZeiger, LOCK_SH);
    $DateiGroesse = filesize ("CSV.IP.csv");
    $BisherigerInhalt = fread ($DateiZeiger, $DateiGroesse);
    flock ($DateiZeiger, LOCK_UN);
    fclose ($DateiZeiger);
  }

if (count ($BisherigerInhalt) > 0)
  {
    foreach ($BisherigerInhalt as $Zeile)
    {
      $GesplitteteZeile = explode ("|", $Zeile);

if (($GesplitteteZeile [0] + 86400) > $Zeitstempel)
        $NeuerInhalt [] = trim ($Zeile) . "\n";
    }

if (count ($NeuerInhalt) > 0)
    {
      foreach ($NeuerInhalt as $Zeile)
      {
        $GesplitteteZeile = explode ("|", $Zeile);

if (trim ($GesplitteteZeile [1]) == $IP)
          $Gefunden = true;
      }
    }
  }

if (!$Gefunden)
  {
    $NeuerInhalt = $BisherigerInhalt . $Zeitstempel . "|" . $IP . "|" . "\n";

$DateiZeiger = fopen ("CSV.IP.csv", "w");
    flock ($DateiZeiger, LOCK_EX);
    fwrite ($DateiZeiger, $NeuerInhalt);
    flock ($DateiZeiger, LOCK_UN);
    fclose ($DateiZeiger);
    return false;
  }
  else
    return true;
}

Diese Funktion ist in einer eigenen PHP-Datei ausgelagert, die ich über include() in die Hauptdatei einbinde.

Sie scheint soweit auch fast zu funktionieren, da die Einträge in der Zieldatei CSV.IP.csv aktualisiert werden, allerdings bekomme ich folgende Warnung:

Invalid argument supplied for foreach()

Diese Warnung wird ja ausgegeben, wenn ein Array beispielsweise vorher nicht definiert wurde, was bei mir aber nicht der Fall ist:

$BisherigerInhalt = fread ($DateiZeiger, $DateiGroesse);

Die foreach-Schleife wird erst danach ausgeführt.

Diese Warnung bekomme ich auch, wenn schon Einträge in der Datei CSV.IP.csv gespeichert wurden.

Worin liegt die Ursache der Warnung ?

Danke für Eure Mithilfe.

Gruss, Marcus

  1. Guten Morgen Marcus,

    Ich wollte mir für mein Gästebuch eine Reloadsperre einbauen, die folgendermassen aufgebaut ist:

    function ReloadPruefen ($IP, $Zeitstempel)
    {
      $DateiZeiger = fopen ("CSV.IP.csv", "r");

    if ($DateiZeiger)
      {
        flock ($DateiZeiger, LOCK_SH);
        $DateiGroesse = filesize ("CSV.IP.csv");
        $BisherigerInhalt = fread ($DateiZeiger, $DateiGroesse);

    fread funktioniert dan doch ein wenig anders als file()

    fread gibt einen string zurück, der den Inhalt der Datei

    darstellt

    file() gibt ein Datenfeld zurück, der den Inhalt indiziert

    nach Textumbrüchen darstellt

    flock ($DateiZeiger, LOCK_UN);
        fclose ($DateiZeiger);
      }

    if (count ($BisherigerInhalt) > 0)

    count("string")===1

    ergo ergibt die Prüfung true

    {
        foreach ($BisherigerInhalt as $Zeile)
        {
          $GesplitteteZeile = explode ("|", $Zeile);

    Gruß aus Berlin!
    eddi

    --
    at, wie er leibt und lebt auf ein Posting
    > > Nein, ich denke nicht.
    gepromptet
    > Das empfiehlt sich aber.
    :))))
  2. Hello Markus,

    Dein Konzept hat aber noch mehr Fehler, als Dir Eddi schon erzählt hat:

    Das Locking-Konzept ist leider nicht richtig.

    Wenn Du an einer Datei Änderungen vornehmen willst im konkurrierenden Betrieb, dann siehr dei Vorgehensweise so aus:

    ggf. Datei zerstörungsfrei anlegen mit fopen(Datei,'a')
    Datei wieder schließen

    nun (hoffentlich noch vorhandene) Datei zum Lesen und Schreiben öffnen mit fopen(Datei,'r+')
    Dateisperre beantragen und zwar EXCLUSIV
    Wenn locked werden konnte

    • datei lesen
    • daten ändern
    • datei schreiben
      Datei schließen (die Freigabe des Locking findet beim Schließen automatisch statt)

    Warum darf man eine Datei zum Auslesen nicht erst mit lock(sh) öffnen, sondern muss zum Zwecke auch den Lesevorgang mit lock(ex) durchführen?

    Weil die Prozesse konkurrieren, und ein lock(sh) niemanden davon abhalten würde, sich auch ein lock(sh) zu holen und die Datei auszulesen

    lesen         A (sh)    B (sh)   A(un)    A(ex)   B(ex)   A(un)    B(un)  A
                |  bbc       bbc                               B(ex)           bbz
                +------------------------------------------------------------------------------->
     schreiben  |                              abc             bbz

    Bemerkung                                          muss   B steht        Huch?
                                                       warten  Schlange
                                                               Lock folgt
                                                               sofort

    Das lässt sich hier nicht richtig malen.
    Wollte das noch mit drei Teilnehmern und einem Zähler zeigen. Da wird es deutlicher.
    Musst Du eben noch warten, bi der Artikel endlich mal fertig wird.

    Harzliche Grüße aus http://www.annerschbarrich.de

    Tom

    --
    Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
    Nur selber lernen macht schlau