Why does `get_permalink()` produces an add. DB request without $post->filter?

I’m currently working on a custom loop/query where I need to add the permalink of a post to the array of posts I’m retrieving from the DB.

Sadly get_permalink() produces one additional DB request for every call, which can get pretty intense as I’m listing all posts on one page.

I first thought it might be that calls to get_option( 'permalink_structure' ); or get_option( 'default_category' ); are no auto loaded options, but both are auto loaded. Proof here:

function wpse_list_autoloaded_opts()
{
    $results = $wpdb->get_results( "
        SELECT option_name, option_value 
        FROM $wpdb->options 
        WHERE autoload = 'yes'
    " );

    echo '<pre>';
    foreach( $results as $result ) 
        if ( 'permalink_structure' === $result->option_name OR 'default_category' === $result->option_name ) 
            echo "Name: {$result->option_name}, Value: {$result->option_value}<br />";
    echo '<pre>';
}
add_action( 'shutdown', 'wpse_list_autoloaded_opts' );

EDIT: Ok, I managed to track it down to the following lines inside the get_permalink() function.

if ( is_object($id) && isset($id->filter) && 'sample' == $id->filter ) {
        $post = $id;
        $sample = true;
    } else {
        $post = &get_post($id);
        $sample = false;
    }

So my Q is now: How would I avoid running the else part, which calls get_post() and does the additional query?


EDIT 2: Now found out that the docBlock of get_permalink() is as wrong as the Codex. You can pass the whole $post object into the function too. This solves the if ( is_object($id) part.

Still open: From where the heck would I retrieve $post->filter with a value of 'sample'?


EDIT 3: Adding $post->filter="sample" to each post object solves the problem. But what remains is a bad feeling that I might break something. The 'sample' in $id/$post->filter seems pretty strange and I can’t find out where it comes from.

1
1

My workaround for this problem:

unset( $post->filter );

$url = get_permalink( $post );

Leave a Comment