There’s no closing foreach for your loop above, it will naturally mess up if you fail to close it.
Example:
<?php
foreach( $something as $something_else ) :
// something
?>
That on it’s own will cause problems because the loop hasn’t been closed, to fix that it should look like..
<?php
foreach( $something as $something_else ) :
// something
endforeach;
?>
There is a closing later in the actual formatted output. Thats not the issue.
There’s alot of WordPress code that utilises get_posts to fetch content so i find it strange you’ve narrowed it down to that function being the problem and not had problems in various areas of WordPress.
Can you provide more of the problem code?
mysql> explain SELECT SQL_CALC_FOUND_ROWS wp_posts.* FROM wp_posts JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id) WHERE 1=1 AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish') AND wp_postmeta.meta_key = 'Thumbnail-150x75' GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 5\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: wp_posts
type: ref
possible_keys: PRIMARY,type_status_date
key: type_status_date
key_len: 124
ref: const,const
rows: 21058
Extra: Using where; Using temporary; Using filesort
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: wp_postmeta
type: ref
possible_keys: post_id,meta_key,meta_post_id
key: post_id
key_len: 8
ref: mm.wp_posts.ID
rows: 1
Extra: Using where
2 rows in set (0.00 sec)
Using temporary; Using filesort is the bad part
I want to use this:
mysql> explain SELECT wp_posts.* FROM wp_posts JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id) WHERE 1=1 AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish') AND wp_postmeta.meta_key = 'Thumbnail-150x75' ORDER BY wp_posts.post_date DESC LIMIT 0, 5\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: wp_posts
type: ref
possible_keys: PRIMARY,type_status_date
key: type_status_date
key_len: 124
ref: const,const
rows: 21058
Extra: Using where
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: wp_postmeta
type: ref
possible_keys: post_id,meta_key,meta_post_id
key: post_id
key_len: 8
ref: mm.wp_posts.ID
rows: 1
Extra: Using where
2 rows in set (0.00 sec)
That same query always comes up in relation to performance issues.
Take a look in wp-includes\query.php around line 2275 and onward (various interesting pieces around line 2333), you’ll notice there are various hooks and filters available there, they exist for plugins to manipulate.
Perhaps have a play around with a few filters on a test install and see if you’re able to rewrite the parts that you’re not happy with.
-> Of course you could always just write your own query using the wpdb class (perhaps i should of just suggested this first)..
eg.
$my_query = $wpdb->get_results("SELECT a,b,c FROM ETC...");
That way you can be selective over what data to query and return.
More on the wpdb class and methods here.
http://codex.ww.wp.xz.cn/Function_Reference/wpdb_Class
I usually write my own queries when i only want a few columns or a single row of data, so as to avoid needlessly querying data i don’t want, which often happens when using functions like get_posts.