[wp-hackers] apply_filters, merge_filters and reset()

Travis Snoozy ai2097 at users.sourceforge.net
Thu Nov 8 15:51:26 GMT 2007


On Thu, 08 Nov 2007 08:12:16 -0600, Jacob <wordpress at santosj.name>
wrote:

Two separate issues have been confused and slurred together here -- let
me try and separate them back out.


1) In all cases, the array being worked on needs to be completely
iterated over. Using next() requires that reset() be called prior to
the start of iteration. Reset() is not always being called on
$wp_filter[$tag] in apply_filters. This seems wrong. This is my
original issue/question. My proposed solution to *this* problem is to
add an appropriate reset() call to each of apply_filters, do_action, and
do_action_ref_array.



The reason I came across the above, but NOT actually part of the
question, is the fact that I would like to use foreach as a
replacement. Since we have discussed it thus far, though, these are my
thoughts on this completely separate suggestion:


2) Foreach iterates over a copy of the array, while next et. al. iterate
over the array directly. Updates to the array inside the loop are only
reflected when working directly on the array in question. I understand
and do not contest this.

3) Using foreach over next would be beneficial for a number of reasons
(automatic, full iteration; more readable; faster).

4) The problem you described re. adding callbacks to the
currently-running filter/action is completely moot, because the current
implementation *already uses* foreach on the inner loop (where the
installed callbacks exist). The while(next(...)) construct is used to
iterate over priority levels only -- all that needs to be done to
support foreach for priority levels is to define indexes 1-10 in the
$wp_filters["$tag"] array when the $tag index is first created.

Removing a callback on a hook, while in a callback being invoked by the
same hook, is not a guaranteed operation -- unless the callback being
removed is in a later-run priority level. Adding a callback on a hook,
while in a callback being invoked by the same hook, is pointless --
unless (again) the callback is being added to a later-run priority
level (otherwise, you may as well just call the other callback
directly). The semantics of the current implementation do not allow
either of these scenarios, which is as it should be.

The foreach loop for handling each priority level is nested, and so the
updated data in later priority levels can be accessed directly. Here is
an example re-implementation using a foreach on the outer loop:

$wp_filter["foo"][1][] = "This is the first item in runlevel 1.\n";
$wp_filter["foo"][2][] = "This is the first item in runlevel 2.\n";


foreach($wp_filter["foo"] as $key => $value) {
    foreach($wp_filter["foo"][$key] as $item) {
        echo $item;
        $wp_filter["foo"][2][] = "This item was added to runlevel 2 in
both runlevels 1 and 2, but only the one from level 1 will show
up.\n";
        $wp_filters["foo"][3][] = "Won't work, but if we had
pre-defined this index before the outer loop, it would be fine.\n";
    }
}

[Output]
This is the first item in runlevel 1.
This is the first item in runlevel 2.
This item was added to runlevel 2 in both runlevels 1 and 2, but only
the one from level 1 will show up.
[/Output]


-- 
Travis 

In Series maintainer
Random coder & quality guy
<http://remstate.com/>


More information about the wp-hackers mailing list