mediengestalter.info
FAQ :: Mitgliederliste :: MGi Team

Willkommen auf dem Portal für Mediengestalter

Aktuelles Datum und Uhrzeit: Do 25.04.2024 09:04 Benutzername: Passwort: Auto-Login

Thema: Fehlende Kindelemente in Baumstruktur - Bug in PHP 4? vom 05.07.2006


Neues Thema eröffnen   Neue Antwort erstellen MGi Foren-Übersicht -> Programmierung -> Fehlende Kindelemente in Baumstruktur - Bug in PHP 4?
Autor Nachricht
Sarky
Threadersteller

Dabei seit: 29.06.2002
Ort: Düsseldorf
Alter: 42
Geschlecht: Männlich
Verfasst Mi 05.07.2006 16:08
Titel

Fehlende Kindelemente in Baumstruktur - Bug in PHP 4?

Antworten mit Zitat Zum Seitenanfang

Hi!

Ich habe hier ein eigenartiges Problem mit einer Baumstruktur, die ich mir gerade zu Versuchszwecken in PHP geschrieben habe. Die Baumeinträge werden unter PHP 4.X nur unvollständig angezeigt, bzw. Kindknoten ab der 2. Ebene haben plötzlich angeblich keine Nachfolger mehr, obwohl diese vorhanden sind.

Die Ausgabe müsste folgende sein, so sieht sie auf einem Server mit PHP 5.0.4 und einem anderen mit PHP 5.1.2 auch aus:

Code:

Id   Name   Parent
1   Essen   -
2   Früchte   Essen
3   Fleisch   Essen
4   Rot   Früchte
5   Kirsche   Rot
6   Schwein   Fleisch
7   Gelb   Früchte
8   Rind   Fleisch
9   Banane   Gelb

    * Essen (2)
          o Früchte (2)
                + Rot (1)
                      # Kirsche (0)
                + Gelb (1)
                      # Banane (0)
          o Fleisch (2)
                + Schwein (0)
                + Rind (0)


Jedoch weigern sich hier 3 andere Rechner mit PHP 4.2.2, 4.3.16 und 4.4.2 und geben stattdessen bei selbem Code nur folgendes aus:

Code:

Id   Name   Parent
1   Essen   -
2   Früchte   Essen
3   Fleisch   Essen
4   Rot   Früchte
5   Kirsche   Rot
6   Schwein   Fleisch
7   Gelb   Früchte
8   Rind   Fleisch
9   Banane   Gelb

    * Essen (2)
          o Früchte (0)
          o Fleisch (0)


Die ersten Kindknoten enthalten keine weiteren Kinder mehr, obwohl in der Liste darüber deutlich angezeigt wird, dass sie welche besitzen.

Die Konfiguration hinsichtlich register_globals, safe_mode etc. ist auf allen Testsystemen im wesentlichen die gleiche.

Habe ich hier tatsächlich einen Bug in PHP 4.X entdeckt oder mache ich irgendwo einen Denkfehler?

Das ist der Code:

Code:

<?php

class Node
{
    var $id;
    var $parentNode = 0;
    var $childNodes = array();
    var $pos;
    var $name;

    function Node($id, $name, $parentNode = 0, $pos = 0)
    {
        $this->id = $id;
        $this->name = $name;
        $this->pos = $pos;

        if (($parentNode != 0) && (is_a($parentNode, 'Node')))
        {
            $this->parentNode = &$parentNode;
            $this->parentNode->_addChild($this);
        }
    }

    function getId()
    {
        return $this->id;
    }

    function getParent()
    {
        return $this->parentNode;
    }

    function getPos()
    {
        return $this->pos;
    }

    function getName()
    {
        return $this->name;
    }

    function _addChild(&$childNode)
    {
        $this->childNodes[] = &$childNode;
    }

    function getChildCount()
    {
        return sizeof($this->childNodes);
    }
   
    function getChild($childNo)
    {
        return $this->childNodes[$childNo];
    }

    function output()
    {
        $output = '<ul>';
        $output .= '<li>' . $this->name . ' (' . sizeof($this->childNodes) . ')</li>';

        $numChilds = sizeof($this->childNodes);
        if ($numChilds > 0)
        {
            for ($i = 0; $i < $numChilds; $i++)
            {
                $output .= $this->childNodes[$i]->output();
            }
        }

        $output .= '</ul>';
        return $output;
    }
}

class Nodes
{
    var $nodeList = array();

    function add(&$node)
    {
        $this->nodeList[] = &$node;
    }

    function dump()
    {
        $output = '<table>';
        $output .= '<tr>';
        $output .= '<td>Id</td><td>Name</td><td>Parent</td>';
        $output .= '</tr>';

        for ($i = 0; $i < sizeof($this->nodeList); $i++)
        {
            if ($this->nodeList[$i]->getParent() != 0)
            {
                $parentNode = &$this->nodeList[$i]->getParent();
                $parentName = $parentNode->getName();
            }
            else
            {
                $parentName = '-';
            }

            $output .= '<tr>';
            $output .= '<td>' . $this->nodeList[$i]->getId() . '</td><td>' . $this->nodeList[$i]->getName() . '</td><td>' . $parentName . '</td>';
            $output .= '</tr>';
        }

        $output .= '</table>';
        return $output;
    }
   
    function output($node)
    {
        $output = '<ul>';
        $output .= '<li>' . $node->getName() . ' (' . $node->getChildCount() . ')</li>';

        $numChilds = $node->getChildCount();
        if ($numChilds > 0)
        {
            for ($i = 0; $i < $numChilds; $i++)
            {
                $childNode = $node->getChild($i);
                $output .= $this->output($childNode);
            }
        }

        $output .= '</ul>';
        return $output;   
    }
}

$node1 = new Node(1, 'Essen');
$node2 = new Node(2, 'Früchte', &$node1);
$node3 = new Node(3, 'Fleisch', &$node1);
$node4 = new Node(4, 'Rot', &$node2);
$node5 = new Node(5, 'Kirsche', &$node4);
$node6 = new Node(6, 'Schwein', &$node3);
$node7 = new Node(7, 'Gelb', &$node2);
$node8 = new Node(8, 'Rind', &$node3);
$node9 = new Node(9, 'Banane', &$node7);

$tree = new Nodes();
$tree->add(&$node1);
$tree->add(&$node2);
$tree->add(&$node3);
$tree->add(&$node4);
$tree->add(&$node5);
$tree->add(&$node6);
$tree->add(&$node7);
$tree->add(&$node8);
$tree->add(&$node9);

echo $tree->dump();

echo "<p />";

echo $tree->output($node1);

?>


Vielen Dank für Eure Ideen!


Zuletzt bearbeitet von Sarky am Mi 05.07.2006 16:10, insgesamt 1-mal bearbeitet
  View user's profile Private Nachricht senden
UNIQLab

Dabei seit: 01.07.2006
Ort: Mooon
Alter: -
Geschlecht: Männlich
Verfasst Mi 05.07.2006 17:05
Titel

Antworten mit Zitat Zum Seitenanfang

Also, bis dato:
Mach einfach mal ein:
Code:
print_r ($node1);

unter
Code:
$node1 = new Node(1, 'Essen');
$node2 = new Node(2, 'Früchte', &$node1);
$node3 = new Node(3, 'Fleisch', &$node1);
$node4 = new Node(4, 'Rot', &$node2);
$node5 = new Node(5, 'Kirsche', &$node4);
$node6 = new Node(6, 'Schwein', &$node3);
$node7 = new Node(7, 'Gelb', &$node2);
$node8 = new Node(8, 'Rind', &$node3);
$node9 = new Node(9, 'Banane', &$node7);

Dann siehst du das die Subklassen keine kinder haben.
Ich schaumal weiter * Such, Fiffi, such! *

Der Fehler ist bis jetzt, dass die Childs nur bei ihrem Parent angemeldet werden, nicht aber beim Superparent.
Ein print_r von $node2 zeigt dir dass.
Node2s Mutter kennt ihre Kinder, nicht aber die Enkelkinder, ebenso wie Node1.
du brauchst also was wie
Code:
isChild()


Das allerdings dürfte ja normalerweise kein Problem sein, denn durch die rekursive Ausgabe, sollte die Klassen mit ihren kindern ja abgearbeitet werden. Mh ..
Verdammt nochmal, mittlerweile glaub ich immer mehr an einen Bug * Ja, ja, ja... *


Zuletzt bearbeitet von UNIQLab am Mi 05.07.2006 18:35, insgesamt 9-mal bearbeitet
  View user's profile Private Nachricht senden
Anzeige
Anzeige
Sarky
Threadersteller

Dabei seit: 29.06.2002
Ort: Düsseldorf
Alter: 42
Geschlecht: Männlich
Verfasst Do 06.07.2006 08:47
Titel

Antworten mit Zitat Zum Seitenanfang

Danke für Deinen Beitrag.

UNIQLab hat geschrieben:
Also, bis dato:
Mach einfach mal ein:
Code:
print_r ($node1);

Dann siehst du das die Subklassen keine kinder haben.


Doch, unter PHP 5 haben sie Ihre Kinder, nur unter PHP 4 gerade komischerweise nicht.

Zitat:

Das allerdings dürfte ja normalerweise kein Problem sein, denn durch die rekursive Ausgabe, sollte die Klassen mit ihren kindern ja abgearbeitet werden. Mh ..


So sieht es aus, das muss funktionieren.

Zitat:
Verdammt nochmal, mittlerweile glaub ich immer mehr an einen Bug * Ja, ja, ja... *

Kann doch gar nicht sein, dass das bisher sonst noch keiner von den Millionen PHP-Entwicklern festgestellt hat? Menno!
  View user's profile Private Nachricht senden
dastef

Dabei seit: 03.11.2003
Ort: -
Alter: -
Geschlecht: Männlich
Verfasst Do 06.07.2006 08:50
Titel

Antworten mit Zitat Zum Seitenanfang

Sarky hat geschrieben:
Doch, unter PHP 5 haben sie Ihre Kinder, nur unter PHP 4 gerade komischerweise nicht.


Den Fall hatte ich früher auch des öfteren .. grad bei DOM-Elementen
oder sowas, steht irgendwo auch im Manual dass das durchaus mal
passieren kann.

entweder ab ner gewissen ebene oder anzahl von elementen, ob
das allerdings auch hier nun wirklich zutrifft .. !? * Ööhm... ja? *
  View user's profile Private Nachricht senden
UNIQLab

Dabei seit: 01.07.2006
Ort: Mooon
Alter: -
Geschlecht: Männlich
Verfasst Do 06.07.2006 16:51
Titel

Antworten mit Zitat Zum Seitenanfang

Ich bin jetzt mal zu dem Schluss gelangt, dass die Referenzen, die du als kinder anhängst gar keine Refrenzen sind, sondern nur eine "hard-copy", trotz des "&" Symbols.
Warum das so ist ... Absolut keine Idee.
  View user's profile Private Nachricht senden
Sarky
Threadersteller

Dabei seit: 29.06.2002
Ort: Düsseldorf
Alter: 42
Geschlecht: Männlich
Verfasst Fr 07.07.2006 10:01
Titel

Antworten mit Zitat Zum Seitenanfang

UNIQLab hat geschrieben:
Ich bin jetzt mal zu dem Schluss gelangt, dass die Referenzen, die du als kinder anhängst gar keine Refrenzen sind, sondern nur eine "hard-copy", trotz des "&" Symbols.
Warum das so ist ... Absolut keine Idee.


So sieht es aus, anscheinend ist PHP 4 in diesem Zusammenhang in der Tat verbuggt.
Daher nun mein Rat: Lasst es mit Referenzen unter dieser Version lieber bleiben.

Ich habe nun also alles umgeschrieben, so dass keine Referenzen mehr verwendet werden:

Code:

class Node
{
   var $id;
   var $parentNode = -1;
   var $childNodes = array();
   var $pos;
   var $name;

   function Node($id, $name, $pos = 0)
   {
      $this->id = $id;
      $this->name = $name;
      $this->pos = $pos;
   }
   
   function getId()
   {
      return $this->id;
   }

   function getName()
   {
      return $this->name;
   }
   
   function getParentId()
   {
      return $this->parentNode;
   }

   function getPos()
   {
      return $this->pos;
   }

   function getChildId($childNo)
   {
      return $this->childNodes[$childNo];
   }

   function getChildCount()
   {
      return sizeof($this->childNodes);
   }

   function _addChild($childNodeId)
   {
      $this->childNodes[] = $childNodeId;
   }   
   
   function _setParent($parentNodeId)
   {
      $this->parentNode = $parentNodeId;
   }
}

class Tree
{
   var $nodeList = array();   

   function _getNodeIndexById($nodeId)
   {
      if ($nodeId == -1) return -1;
      
      $indexInList = -1;
      for ($i = 0; $i < sizeof($this->nodeList); $i++)
      {
         if ($this->nodeList[$i]->getId() == $nodeId)
         {
            $indexInList = $i;
         }
      }
      
      return $indexInList;
   }
   
   function addNode($node, $parentNodeId = -1)
   {
      $this->nodeList[] = $node;
      $newNodePos = sizeof($this->nodeList) - 1;
      
      if ($parentNodeId != -1)
      {
         $parentNodeIndex = $this->_getNodeIndexById($parentNodeId);
      
         if (($parentNodeIndex != -1) && (isset($this->nodeList[$parentNodeIndex])))
         {
            $this->nodeList[$parentNodeIndex]->_addChild($node->getId());
            $this->nodeList[$newNodePos]->_setParent($parentNodeId);
         }
      }
   }
   
   function dump()
   {
      $output = '<table>';
      $output .= '<tr>';
      $output .= '<td>Id</td><td>Name</td><td>Parent</td>';
      $output .= '</tr>';

      for ($i = 0; $i < sizeof($this->nodeList); $i++)
      {
         $parentId = $this->nodeList[$i]->getParentId();
         $parentName = '';
         
         if ($parentId != -1)
         {
            $parentIndex = $this->_getNodeIndexById($parentId);
            
            if (isset($this->nodeList[$parentIndex]))
            {
               $parentName = $this->nodeList[$parentIndex]->getName();
            }
         }

         $output .= '<tr>';
         $output .= '<td>' . $this->nodeList[$i]->getId() . '</td>';
         $output .= '<td>' . $this->nodeList[$i]->getName() . '</td>';
         $output .= '<td>' . $parentName . '</td>';
         $output .= '</tr>';
      }

      $output .= '</table>';
      return $output;
   }
   
   function output($nodeId = 1)
   {
      $output = '';
      $nodeIndex = $this->_getNodeIndexById($nodeId);

      if (($nodeIndex != -1) && isset($this->nodeList[$nodeIndex]))
      {
            $numChilds = $this->nodeList[$nodeIndex]->getChildCount();
           
            $output .= '<ul>';
            $output .= '<li>' . $this->nodeList[$nodeIndex]->getName() . ' (' . $numChilds . ')</li>';

            if ($numChilds > 0)
            {
                   for ($i = 0; $i < $numChilds; $i++)
                   {
                          $childNodeId = $this->nodeList[$nodeIndex]->getChildId($i);
                           $output .= $this->output($childNodeId);
                   }
            }

            $output .= '</ul>';
      }
      
      return $output;   
   }
}

$tree = new Tree();
$tree->addNode(new Node(1, 'Essen'));
$tree->addNode(new Node(2, 'Früchte'), 1);
$tree->addNode(new Node(3, 'Fleisch'), 1);
$tree->addNode(new Node(4, 'Rot'), 2);
$tree->addNode(new Node(5, 'Kirsche'), 4);
$tree->addNode(new Node(6, 'Schwein'), 3);
$tree->addNode(new Node(7, 'Gelb'), 2);
$tree->addNode(new Node(8, 'Rind'), 3);
$tree->addNode(new Node(9, 'Banane'), 7);

echo $tree->dump();
echo "<p />";
echo $tree->output();


... und siehe da, diesen uneleganteren Code kapiert nun endlich auch PHP 4:

Code:

Id   Name   Parent
1   Essen   
2   Früchte   Essen
3   Fleisch   Essen
4   Rot   Früchte
5   Kirsche   Rot
6   Schwein   Fleisch
7   Gelb   Früchte
8   Rind   Fleisch
9   Banane   Gelb

    * Essen (2)
          o Früchte (2)
                + Rot (1)
                      # Kirsche (0)
                + Gelb (1)
                      # Banane (0)
          o Fleisch (2)
                + Schwein (0)
                + Rind (0)
  View user's profile Private Nachricht senden
Eistee
Administrator

Dabei seit: 31.10.2001
Ort: Grimma
Alter: 45
Geschlecht: Männlich
Verfasst Fr 07.07.2006 10:21
Titel

Antworten mit Zitat Zum Seitenanfang

Eistee: "Ist bestimmt nen PHP 4 Bug..."
Sarky: "Nee, das kann doch gar nicht sein"

Grins
  View user's profile Private Nachricht senden Website dieses Benutzers besuchen
Sarky
Threadersteller

Dabei seit: 29.06.2002
Ort: Düsseldorf
Alter: 42
Geschlecht: Männlich
Verfasst Fr 07.07.2006 10:59
Titel

Antworten mit Zitat Zum Seitenanfang

Etwas mehr Einfühlsamkeit bitte, für mich ist gerade eine Welt zusammengebrochen, dass PHP einen derartigen Fehler in einer Produktivbuild hat *hu hu huu*

*zwinker*
  View user's profile Private Nachricht senden
 
Ähnliche Themen Baumstruktur mit php und mysql
[CSS] - Kindelemente ansprechen
[jQuery] - Kindelemente ansprechen
[filesystem] baumstruktur php readdir
a:active funktioniert nicht auf kindelemente?
[PHP/mySQL] Baumstruktur anlegen bzw. verwalten ?!
Neues Thema eröffnen   Neue Antwort erstellen
MGi Foren-Übersicht -> Programmierung


Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst an Umfragen in diesem Forum nicht mitmachen.