2011-07-04 20 views
5

Estoy intentando crear un iterador como this one, para obtener una lista de comentarios:la implementación de múltiples niveles "repetidor" en PHP

// the iterator class, pretty much the same as the one from the php docs... 
abstract class MyIterator implements Iterator{ 

    public $position = 0, 
     $list; 

    public function __construct($list) { 
    $this->list = $list; 
    $this->position = 0; 
    } 

    public function rewind() { 
    $this->position = 0; 
    } 

    public function current() { 
    return $this->list[$this->position]; 
    } 

    public function key() { 
    return $this->position; 
    } 

    public function next() { 
    ++$this->position; 
    } 

    public function valid() { 
    return isset($this->list[$this->position]); 
    } 
} 

El comentario iterador:

class MyCommentIterator extends MyIterator{ 

    public function current(){ 
    return new Comment($this->list[$this->position]); 
    }  
} 

Y esto es ¿Cómo lo uso:

$comments = GetComments(); // gets the comments from the db 
if($comments): ?> 

    <ol> 
    <?php foreach(new MyCommentIterator($comments) as $comment): ?> 
    <li> 
     <p class="author"><?php echo $comment->author(); ?></p> 

     <div class="content"> 
     <?php echo $comment->content(); ?> 
     </div> 

     <!-- check for child comments and display them --> 

    </li> 
    <?php endforeach; ?> 
    </ol> 

<?php endif; ?> 

Así que todo está funcionando bien, además de una cosa: no puedo averiguarlo cómo procesar n Ested comentarios :(

La matriz $comments devuelve una lista plana de los comentarios, como:

[0] => object(
    'id' => 346, 
    'parent' => 0, // top level comment 
    'author' => 'John', 
    'content' => 'bla bla'   
), 

[1] => object(
    'id' => 478, 
    'parent' => 346, // child comment of the comment with id =346 
    'author' => 'John', 
    'content' => 'bla bla'   
) 
... 

necesito estar de alguna manera capaz de comprobar si hay comentarios niño (en varios niveles) e insertarlas antes de la </li> ' s de los comentarios de sus padres ...

¿Alguna idea?

Respuesta

1

Está utilizando una matriz plana, pero en realidad, los elementos de esa matriz son un árbol o estructura de datos jerárquica.

se está mostrando básicamente una lista secuencial. Tal vez debería construir primero una estructura de árbol/datos jerárquicos, sin mostrar, y luego mostrar los datos de la lista de árboles.

/* array */ function FlatArrayToTreeArray(/* array */ $MyFlatArray) 
{ 
    ... 
} 

/* void */ function IterateTree(/* array */ $MyTreeArray) 
{ 
    ... 
} 

/* void */ function Example() { 
    $MyFlatArray = Array(
    0 => object(
     'id' => 346, 
     'parent' => 0, // top level comment 
     'author' => 'John', 
     'title' => 'Your restaurant food its too spicy', 
     'content' => 'bla bla'   
    ), 
    1 => object(
     'id' => 478, 
     'parent' => 346, // child comment of the comment with id =346 
     'author' => 'Mike', 
     'title' => 'Re: Your restaurant food its too spicy', 
     'content' => 'bla bla'   
    ), 
    2 => object(
     'id' => 479, 
     'parent' => 478, // child comment of the comment with id =346 
     'author' => 'John', 
     'title' => 'Re: Your restaurant food its too spicy', 
     'content' => 'bla bla'   
    ), 
    3 => object(
     'id' => 479, 
     'parent' => 346, // child comment of the comment with id =346 
     'author' => 'Jane', 
     'title' => 'Re: Your restaurant food its too spicy', 
     'content' => 'bla bla'   
    ) 
); 

    $MyTreeArray = FlatArrayToTreeArray($myflatarray); 

    IterateTree($MyTreeArray); 
} // function Example() 

Cheers.

3

Recursion es tu amigo.

displaycomment(comment): 
    $html .= "<ol>" . comment->html; 
    foreach comment->child: 
     $html .= "<li>" . displaycomment(child) . "</li>"; 
    $html .= "</ol>"; 
    return $html; 

Todo el código que aparece en esta publicación es pseudo. Cualquier parecido con el código real, funcionando o roto, es pura coincidencia.

3

Es posible que desee mirar en el RecursiveIterator InterfacePHP Manual. Si se extiende el iterador con los métodos de la interfaz, que es capaz de iterar sobre sus comentarios con una instancia de RecursiveIteratorIteratorPHP Manual secuencialmente.

Sin embargo, como su salida es una lista plana, tiene que cuidar de la lógica de los niveles por su cuenta, por ejemplo, insertando <ol> por profundidad, y </ol> por profundidad hacia abajo.

Utilice los indicadores para controlar el orden de cómo se atraviesan los niños.

Cuestiones relacionadas