Olaf Schneider: Apacheabsturz bei Nutzung von Iterator aus SPL

Hallo,

folgender Code implementiert einen Iterator und iteriert über ihn mittels foreach:

  
  
<?php  
  
class NumberListIterator implements Iterator {  
    private $list;  
    private $position;  
  
    public function __construct($string) {  
        $this->list = explode(' ', $string);  
    }  
  
    public function rewind() {  
        $this->position = 0;  
    }  
  
    public function valid() {  
        return $this->position < count($this->list);  
    }  
  
    public function key() {  
        return $this->position;  
    }  
  
    public function current() {  
        return $this->list[$this->position];  
    }  
  
    public function next() {  
        $this->position++;  
    }  
}  
  
$iterator = new NumberListIterator('11 22 33 44 55 66 77');  
  
foreach ($iterator as $value) {  
    echo "[$value]";  
}  
  

Das funktioniert auch wie gewünscht. Die Ausgabe lautet [11][22][33][44][55][66][77].

Wenn ich jetzt aber die next()-Methode wie folgt abändere:

  
  
    public function next() {  
        {  
            $this->position++;  
        } while($this->valid() && $this->current() == '55');  
    }  
  

...  (ja, das könnte man auch über FilterIterator lösen), dann holt sich Apache alles an CPU, was er bekommen kann. Auch nach Schließen des Browserfensters, in dem keine Ausgabe erfolgt (auch keine Debugmeldungen oder ähnliches) läuft Apache unter voller Last weiter und lässt sich nur durch einen Neustart wieder beruhigen.

Ersetze ich die '55' durch einen Wert, der nicht in der Liste existiert, läuft das Script wieder durch.

Mir ist nicht ganz klar, ob ich irgend einen obskuren Implementierungsfehler mache, oder einen Bug gefunden habe.

Weiss das jemand von Euch?

Ich verwende Apache/1.3.33 (Darwin) und PHP/5.1.4 unter Mac OS X

Gruß
Olaf

  1. Moin!

    Wenn ich jetzt aber die next()-Methode wie folgt abändere:

    public function next() {
            {
                $this->position++;
            } while($this->valid() && $this->current() == '55');
        }

      
    Du suchst  
      
    ~~~php
      
      
         public function next() {  
             do {  
                 $this->position++;  
             } while($this->valid() && $this->current() == '55');  
         }  
    
    

    siehe: http://de.php.net/manual/de/control-structures.do.while.php
    und
    http://de.php.net/manual/de/control-structures.while.php

    Vermutlich baust Du hiermit schlicht eine ewige Schleife:

      
    while($this->valid() && $this->current() == '55');  
    
    

    MFFG (Mit freundlich- friedfertigem Grinsen)

    fastix®

    --
    Als Freiberufler bin ich immer auf der Suche nach Aufträgen: Schulungen, Seminare, Training, Development
    1. Hallo fastix®,

      Oops – das fehlende, aber entscheidene do habe ich übersehen. Die einzeilige Endlosschleife ist auch durch meine verschiedenen Debugausgaben durchgerutscht und hat mich so zu der Annahme verleiten lassen, der Fehler sei nicht so trivial. Werch ein Illtum.

      Vielen Dank.

      Gruß
      Olaf