Bookmarks

Yahoo Gmail Google Facebook Delicious Twitter Reddit Stumpleupon Myspace Digg

Search queries

/proc/kallsyms format, sqldatasource dal, wwwxxxenden, convert raid5 to raid 10 mdadm, apache force chunked, nrao wwwxxx, xxxxxdup, procmail change subject header, wwwXxx not20, Wwwxxx.doks sas

Links

XODOX
Impressum

#1: Verhalten von foreach

Posted on 2008-04-19 17:32:23 by Oliver Block

Hallo Gruppe,

von Zeit zu Zeit beobachte ich Probleme in der Verwendung von foreach.
Gerade kürzlich traten dabei erneut Probleme auf. Da ich die bisher
durch Verwendung von for auffangen konnte habe ich mich bisher nicht
weiter darum gekümmert.

Nun zum Problem. In einer Funktion wird ein numerisches Array zwei Mal
nacheinander mittels foreach durchlaufen:

foreach($arr as &$val) {
....
if($bedingung == true)
$val = null;
....
}

foreach($arr as $val) {
....
if(!is_null($val))
$str .= ' ' . $val;

....
}

Beim zweiten Durchlauf war $str stets leer, obwohl $arr mindestens ein
Element hatte, das nicht null war. Eine Ãnderung der zweiten Schleife in

for($i=0,$n=count($arr); $i<$n; $i++) {
....
if(!is_null($arr[$i]))
$str .= ' ' . $arr[$i];
....
}

hat das Problem, wie erwähnt, behoben. Allerdings habe ich bisher nicht
verstanden, wo mein/der Fehler liegen könnte.

- Der interne Zeiger soll lt. Doku immer bei der Verwendung von foreach
zurückgesetzt werden.
- Es liegt kein Hinweis darauf vor, daà foreach nur mit assoziativen
Arrays verwendet werden sollte.

Hat jemand eine Erklärung?

GruÃ,

Oliver Block

Report this message

#2: Re: Verhalten von foreach

Posted on 2008-04-19 18:29:20 by Christoph Herrmann

Oliver Block schrieb:
> Hat jemand eine Erklärung?

was gibt denn "var_dump($arr);" jeweils vor den Schleifen aus?

--
Mit freundlichen GrüÃen,
Christoph Herrmann

http://dragonprojects.de/

Report this message

#3: Re: Verhalten von foreach

Posted on 2008-04-19 19:05:35 by Oliver Block

Christoph Herrmann schrieb:
> Oliver Block schrieb:
>> Hat jemand eine Erklärung?
>
> was gibt denn "var_dump($arr);" jeweils vor den Schleifen aus?
>

$arr gibt vor der zweiten foreach-Anweisung z.B. zwei Elemente, bei
denen [0] ein String ist und [1] => NULL.

Wenn dann die Schleife durchlaufen wird, gibt var_dump (innerhalb des
foreach-Blocks) für beide Elemente [0], [1] NULL aus.

Hier fällt auf, dass die Anzahl der Durchläufe passt. Allerdings ist der
Wert NULL, was eben nicht richtig ist.

Report this message

#4: Re: Verhalten von foreach

Posted on 2008-04-19 19:08:32 by Thomas Mlynarczyk

Oliver Block schrieb:

> foreach($arr as &$val) {
> ...
> if($bedingung == true)
> $val = null;
> ...
> }
>
> foreach($arr as $val) {
> ...
> if(!is_null($val))
> $str .= ' ' . $val;
>
> ...
> }

Nur ein Versuch: unset( $val ) zwischen den beiden Schleifen.

GruÃ,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)

Report this message

#5: Re: Verhalten von foreach

Posted on 2008-04-19 19:47:58 by Claus Reibenstein

Oliver Block schrieb:

> foreach($arr as &$val) {

Hier setzt Du bei jedem Schleifendurchlauf eine Referenz auf das
jeweilige Feldelement. Nach dem Schleifenende referenziert $var also das
letzte Element des Arrays.

> foreach($arr as $val) {

Hier legst Du bei jedem Schleifendurchlauf eine Kopie des aktuellen
Elements auf $var. Da $var aber noch die Referenz auf das letzte
Feldelement enthält, landet diese Kopie auf eben diesem Element.

Dieses Verhalten ist kein Bug, sondern ein wohl definiertes und
dokumentiertes Feature.

Um dieses Problem zu lösen, musst Du vor der zweiten Schleife $var löschen:

unset($var);

GruÃ. Claus

Report this message

#6: Re: Verhalten von foreach

Posted on 2008-04-19 19:56:04 by Claus Reibenstein

Oliver Block schrieb:

> foreach($arr as &$val) {

Hier setzt Du bei jedem Schleifendurchlauf eine Referenz auf das
jeweilige Feldelement. Nach dem Schleifenende referenziert $val also das
letzte Element des Arrays.

> foreach($arr as $val) {

Hier legst Du bei jedem Schleifendurchlauf eine Kopie des aktuellen
Elements auf $val. Da $val aber noch die Referenz auf das letzte
Feldelement enthält, landet diese Kopie auf eben diesem Element.

Dieses Verhalten ist kein Bug, sondern ein wohl definiertes und
dokumentiertes Feature.

Um dieses Problem zu lösen, musst Du vor der zweiten Schleife $val löschen:

unset($val);

GruÃ. Claus

Report this message

#7: Re: Verhalten von foreach

Posted on 2008-04-20 00:04:51 by Oliver Block

Claus Reibenstein schrieb:
> Hier legst Du bei jedem Schleifendurchlauf eine Kopie des aktuellen
> Elements auf $val. Da $val aber noch die Referenz auf das letzte
> Feldelement enthält, landet diese Kopie auf eben diesem Element.

Das hört sich plausibel an.:) Ich hatte ja extra eine Referenz
verwendet, um die Werte ggf. verändern zu können. Ich hatte mir nur
keine Gedanken über den Geltungsbereich gemacht.


> Dieses Verhalten ist kein Bug, sondern ein wohl definiertes und
> dokumentiertes Feature.

ACK.

Gruss,

Oliver

Report this message