Jonny F.: Merkwürdiges lösch verhalten im Array

Hallo liebe Self-Htmler

bzw. self-paste&copyer :D,

ich habe ein merkwürdiges Problem was das löschen in einem Array angeht.

Ich lasse mir per Get einen Wert aus einem Array schicken, sprich

<a href="seite.php?suppcol=arraywert">lösche array wert</a>

Dieser Wert wird nun aus dem Array gelöscht das komische daran ist aber manchmal wenn ich einen Wert aus dem Array lösche, löscht er mir auch einen anderen mit. Das einzigste was mir aufgefallen ist und ich tüftele schon seit längeren an dem Problem, ist dass es immer der erste Wert im Array ist.

Error_reporting ist natürlich auf e_all gesetzt und per var_dump habe ich herausgefunden dass immer der erste Wert flöten geht.

Das ist nun der PHP Teil mit dem ich den Wert lösche

  
if(in_array($_GET['suppcol'], $_SESSION['allcol'])) {  
//Wert wird aus dem Array gelöscht  
unset($_SESSION['tablecolallpc'][array_search($_GET['suppcol'],$_SESSION['tablecolallpc'])]);  
}

Hat jemand einen Plan woran das liegen kann oder ist es einfach nur ein PHP Fehler.

MfG Jonny F.

  1. Hi,

    Dieser Wert wird nun aus dem Array gelöscht das komische daran ist aber manchmal wenn ich einen Wert aus dem Array lösche, löscht er mir auch einen anderen mit. Das einzigste was mir aufgefallen ist und ich tüftele schon seit längeren an dem Problem, ist dass es immer der erste Wert im Array ist.

    Manchmal, aber nur manchmal ...?

    Das ist nun der PHP Teil mit dem ich den Wert lösche

    if(in_array($_GET['suppcol'], $_SESSION['allcol'])) {
    //Wert wird aus dem Array gelöscht
    unset($_SESSION['tablecolallpc'][array_search($_GET['suppcol'],$_SESSION['tablecolallpc'])]);
    }

      
    Lass da erst mal alles weg, was nicht direkt etwas mit dem Löschen aus dem Array zu tun hat - spricht, sämtlichen GET-Krempel und die Session.  
    Teste das Verhalten mit vorgegebenen Werten.  
      
    MfG ChrisB  
      
    
    -- 
    “Whoever best describes the problem is the person most likely to solve the problem.” [Dan Roam]
    
  2. Hi!

    Error_reporting ist natürlich auf e_all gesetzt und per var_dump habe ich herausgefunden dass immer der erste Wert flöten geht.

    Hast du auch mit var_dump() herausgefunden, ob die von dir verwendeten Variablen das gewünschte enthalten und ob die Funktionen das zurückliefern, was du erwartest?

    if(in_array($_GET['suppcol'], $_SESSION['allcol'])) {

    //Wert wird aus dem Array gelöscht
    unset($_SESSION['tablecolallpc'][array_search($_GET['suppcol'],$_SESSION['tablecolallpc'])]);
    }

      
    array\_search() liefert im Nicht-gefunden-Fall false zurück, das gleich 0 ist und somit das Löschen des ersten Array-Wertes erklären könnte. Kontrollausgaben können diese Vermutung bestätigen. Außerdem testest du das Vorhandensein in $\_SESSION['allcol'], lässt aber array\_search() auf $\_SESSION['tablecolallpc'] los.  
      
      
    Lo!
    
  3. if(in_array($_GET['suppcol'], $_SESSION['allcol'])) {
    //Wert wird aus dem Array gelöscht
    unset($_SESSION['tablecolallpc'][array_search($_GET['suppcol'],$_SESSION['tablecolallpc'])]);
    }

      
    Vielen Dank für eure Tipps, aber das Problem hat sich irgendwie von selbst gelöst. Als ich die Funktion auf Fehlerbehebung umgeschrieben habe tritt er einfach nicht mehr auf und das schon seit 2 Tagen wobei er ungefgähr alle 4 min gekommen ist.  
      
    ~~~php
      
    //Colum loeschen aus Listenfeld  
    if(in_array($_GET['suppcol'], $_SESSION['allcol'])) {  
     $suppcol = array_search($_GET['suppcol'],$_SESSION['tablecolallpc']);  
     if($suppcol==false){  
      echo "Fehler beim ausblenden einer Spalte";  
     }  
     else{  
      unset($_SESSION['tablecolallpc'][$suppcol]);  
     }  
    }
    

    Das mit der Vermutung das er false also 0 ausgibt mag sein aber meine arrays identifizieren sich aus Namen also nicht aus Zahlen außerdem hat er ja immer den richtigen Wert gelöscht nur halt ab und zu auch den ersten mit.

    Naja warum es aber jetzt reibungslos funktioniert ist mir auch ein Rätsel aber naja was solls, funnzzzt ja jetzt :)

    Gruß Jonny F.

    1. Kleine Korrektur

        
      //Wert wird aus der Tabelle geloescht  
      if(false !== ($key = array_search($_GET['suppcol'], $_SESSION['tablecolallpc']))){  
       unset($_SESSION['tablecolallpc'][$key]);  
      }
      

      Dieser Code funktioniert reibungslos :D wenn ich nach den Inhalt lösche enstehen ein Paar bugs die unerklärbar sind, zumindest für mich wenn ich jedoch nach dem Index lösche funktioniert es wirklich reibungslos.

      Gruß Jonny F.

      1. Hi!

        Dieser Code funktioniert reibungslos :D wenn ich nach den Inhalt lösche enstehen ein Paar bugs die unerklärbar sind, zumindest für mich wenn ich jedoch nach dem Index lösche funktioniert es wirklich reibungslos.

        Ich kann dein Problem nicht nachvollziehen. Raten, wie bei meiner ersten Antwort, führt nicht immer zum Ziel. Du gibts keine Beispieldaten an, keine Kontrollausgabenwerte, und deine Beschreibung ist nur schwer verständlich.

        (Was ist der Unterschied zwischen "reibungslos" und "wirklich reibungslos"?)

        Lo!

        1. Also ich werde jetzt nochmal explizit das Problem und mein Vorhaben schildern + die Lösung die jetzt funktioniert.

          Also ich habe eine Weboberfläche gebastelt die mir Werte aus einer SQL Datenbank lieft.

          In der Oberfläche kann man nun Spalten hinzufügen wie auch Spalten entfernen(Spalten aus der SQL Datenbank). Nun habe ich per Get-Parameter den Spaltennamen wie er im Array vorhanden war an ein Script geschickt der den Wert aus dem Array löschen soll. Nun gut.

          Hier ist die Funktion die mir ein Listenfeld generiert die mir die noch auswählbaren Spalten anzeigt die ich Fest in ein Array geschrieben habe.

            
          // Hier sind alle Spalten die ich ausgeben kann  
          $_SESSION['allcol'] = array("Computername", "Benutzername", "Abteilung", "Inventarnummer", "Aktuelle Kostenstelle", "Alte Kostenstelle", "Seriennummer", "Anschaffungsdatum", "Bemerkung", "letzte aenderung", "MAC Adresse", "Netzwerkdose", "Seriennummer OCs", "Telefondose", "Telefonverteiler", "IP Adresse", "VM", "TC", "manueller Eintrag");  
            
          //Es gibt ein Reset Button mit dem ich einen Ursprungszustand generieren kan  
          if(isset($_GET['resetcol'])){  
           unset($_SESSION['tablecolallpc']);  //Sind alle Spalten die ausgegeben werden  
           unset($_SESSION['availcol']);       //Sind alle Spalten die noch ausgegeben werden können  
          }  
            
          //Das ist der Ursprungszustand (Standardwerte)  
          if(!isset($_SESSION['tablecolallpc'])){  
           $_SESSION['tablecolallpc'] = array("Computername", "Benutzername", "Abteilung", "Inventarnummer", "Aktuelle Kostenstelle", "Alte Kostenstelle", "Seriennummer");  
          }  
            
          //Hier kann ich per Post also aus dem Listenfeld Spalten hinzufügen  
          if(array_search($_POST['setcol'], $_SESSION['availcol'])) {  
          //Tabelle bekommt ausgewaehlten wert aus dem Listenfeld (alle Computer)  
           $_SESSION['tablecolallpc'][] = $_POST['setcol'];  
          }  
            
          //Hier kann ich nun wieder Spalten ausblenden, sprich die Spalten werden nicht mehr angezeigt  
          if(false !== ($key = array_search($_GET['suppcol'], $_SESSION['tablecolallpc']))){  
           unset($_SESSION['tablecolallpc'][$key]);  
          }  
            
          //Nun leite ich von allen Spalten und den Spalten wo angezeigt werden das Array für die noch verfügbaren Spalten ein  
           $_SESSION['availcol'] = $_SESSION['allcol'];  
           //angezeigte Columns werden aus dem Listenfeld geloescht  
           foreach($_SESSION['tablecolallpc'] AS $delcol){  
            unset($_SESSION['availcol'][array_search($delcol,$_SESSION['availcol'])]);  
           }  
            
          //Sicherheitshalber werden hier noch doppelte Einträge gelöscht  
          $_SESSION['availcol'] = array_unique ($_SESSION['availcol']);  
          $_SESSION['tablecolallpcs'] = array_unique ($_SESSION['tablecolallpcs']);  
            
          //Array wird nach dem Alphabet sortiert  
          sort($_SESSION['availcol']);  
          //Ausgabe des Listenfelds  
          foreach($_SESSION['availcol'] AS $avcol){  
           $countHl++;  
           echo "<option".($countHl%2==1?" class='newcolumnoptiona'":"").">$avcol</option>";  
          }  
            
          echo "</select>";  
            
          //Der Button zum Ursprungszustand  
          //Reset Listfield  
          echo "<a href=".( $_SERVER['PHP_SELF'])."?resetcol=true id='resetbutton'>Reset</a>";  
          
          

          Die Ausgabe erfolgt bei mir via Casefelder die durch das Array $_SESSION['tablecolallpcs'] eingeleitet wird.

          Im ersten Casekonstrukt werden werden die Zellen ausgegeben + ein Strinkonstrukt gebildet der das SQL Select statement beinhaltet, im zweiten Casekonstrukt werden dann die Zellen ausgegeben die dann den Inhalt beinhalten. Aber diesen Quellcode noch zu Posten wäre dann schon zu viel.

          Ich hoffe das ist jetzt ein wenig verständlich.

          Gruß Jonny F.

          1. Hi!

            Also ich werde jetzt nochmal explizit das Problem und mein Vorhaben schildern + die Lösung die jetzt funktioniert.

            Und an welcher Stelle konkret läuft Wunsch und Wirklichkeit auseinander? Mach Kontrollausgaben mit var_dump() und benenne die Stellen, an denen vor der Operation noch der gewünschte Inhalt da war und hinterher nicht mehr.

            //Hier kann ich per Post also aus dem Listenfeld Spalten hinzufügen
            if(array_search($_POST['setcol'], $_SESSION['availcol'])) {

            Wie auch im Handbuch zu array_search() deutlich hingewiesen wird, muss man zwischen 0 und false unterscheiden. Wenn in $_POST['setcol'] der erste Wert aus $_SESSION['availcol'] (der mit dem Key 0, wenn er noch nicht mit unset() entfernt wurde) enthalten ist, wird die Bedingung nicht wahr.

            foreach($_SESSION['tablecolallpc'] AS $delcol){
              unset($_SESSION['availcol'][array_search($delcol,$_SESSION['availcol'])]);

            Auch hier ist wieder eine Stelle, die false und 0 nicht unterscheidet. Das ist vielleicht nicht relevant, wenn $delcol garantiert in $_SESSION['availcol'] vorkommt. Aber das sieht man nicht durch einen Blick auf den Code, ohne sich den genauen Ablauf zu Gemüte zu führen. Besser ist es, hier durch Code Klarheit zu schaffen. (Siehe dein "false !== $key = array_search()"-Konstrukt.)

            //Sicherheitshalber werden hier noch doppelte Einträge gelöscht

            Sicherheit? Warum kann das passieren? Ist das unumgänglich oder durch geschicktere Programmlogik vermeidbar? Fragen, die du nicht unbedingt mir beantworten musst, aber die du dir stellen solltest. Wenn du einen plausiblen Grund findest, gib den an anstatt nichtssagend von sicherheitshalber zu reden. Da weißt du dann später beim Lesen deines eigenen Codes besser, warum das Konstrukt existiert.

            Lo!