WordPress.org

Make WordPress Core

Opened 3 years ago

Closed 3 years ago

Last modified 2 years ago

#20297 closed feature request (maybelater)

WP_Query implements IteratorAggregate

Reported by: hakre Owned by:
Milestone: Priority: normal
Severity: normal Version:
Component: General Keywords: has-patch close
Focuses: Cc:

Description

Giving WP_Query the IteratorAggregate interface would allow to deal with it more fluently the "PHP way". This is especially true for themes.

Attachments (1)

20297.diff (708 bytes) - added by hakre 3 years ago.

Download all attachments as: .zip

Change History (8)

@hakre3 years ago

comment:1 @hakre3 years ago

Related: #20296

comment:2 @johnbillion3 years ago

What would be the use case for this? You can iterate over member variables of an object without an iterator interface, so what exactly does this do?

comment:3 @nacin3 years ago

  • Keywords close added

In theory, I really like #20296 and #20297. They could significantly simplify how a loop looks. Instead of $query->have_posts() : $query->the_post(), it could be foreach ( $query as $post ). Perhaps when combined with WP_Post, they could be very powerful.

A few practical issues, however. For the main loop, you'd need to use foreach( $wp_query ) -- directly accessing a global is worse than the template tags we have now -- unless of course we introduced a wp_query() function. Also, without WP_Post (which we definitely don't have), it's not that helpful, especially if it doesn't call the_post() automatically on iteration. Also, if it doesn't implement Countable (which it can't as SPL can be disabled before 5.3), it would only be confusing for it to implement IteratorAggregate.

I like the idea. I just don't think we're at the point yet where we should do this. Especially since it is just as easy, for now, to run foreach() and count() on $wp_query->posts. I suggest closing it as maybelater.

comment:4 @scribu3 years ago

If we were to implement IteratorAggregate and ArrayAccess, we could make get_posts() just return the WP_Query instance, but that won't be much help if we still have to deal with setup_postdata().

So, yeah, WP_Post first.

comment:5 @hakre3 years ago

Yes, IteratorAggregate is a light approach here. The patch is available so it's something to play with. I also thought about the shortcomings because of setup_postdata, a much nicer thing would be to have WP_Query and an Iterator for it which can replace the ArrayIterator - an external iterator still aggregated. However I wanted to keep this first suggestion light, I think WP_Query is a potential class that could benefit from PHP's traversable features and that's the main point.

Sure this little patch can't do all the magic - would be cool, but as noted, it does not show the whole picture.

If there's something like WP_Post I think there would be some list-class like WP_Posts which is traversable anyway.

Maybe using an iterator internally in WP_Query will make future changes more feasible.

About compilter flags: The SPL is compiled in with nearly every standard distribution. As with any other compile feature, things can be disabled which are commonly not, but we don't care much about all those other compile flags as well. Just to put this into the right light, the SPL ain't some esoteric feature, it's generally available with PHP 5.2 and above so it's really safe to use.

comment:6 @nacin3 years ago

  • Milestone Awaiting Review deleted
  • Resolution set to maybelater
  • Status changed from new to closed

I like the idea. I just don't think we're at the point yet where we should do this. Especially since it is just as easy, for now, to run foreach() and count() on $wp_query->posts. I suggest closing it as maybelater.

comment:7 @hakre2 years ago

Example of a WP 3.6 compatible iterator for posts of a WP_Query: https://gist.github.com/hakre/6520715

Note: See TracTickets for help on using tickets.