4

So I see that get_posts() function return an array of posts.

  1. If there are posts, it returns an array of posts.

  2. If there are no posts it returns an empty array().

  3. If there are posts, but the querying of the database fails (and let's say, 99.999% times it returns correct, but this time it fails for some reason), it returns an empty array. (Important: I'm not sure of this, this is what I understand when I read how this function works).

My question is this: If I use this function, when do I know if the function failed? (Like there are some functions which returns an WP_Error.)

  • What kind of failing do you mean? Like connection error? – Krzysiek Dróżdż Feb 16 at 10:51
  • Hi... I can't say exactly what kind of failing, because I really don't know what can fail, but I think there should be something that can fail. Sure, a connection is very likely to happen if the database is somewhere else... It's just strange that there is nothing to indicate if it's a fail or not, like a lot of other functions that do. Just look at a function like wp_insert_post(), has even a second argument to either return WP_Error on failure or not. – Brada Feb 16 at 19:17
2

Here's one way to check if there was an DB error within get_posts():

global $EZSQL_ERROR;

$before = isset( $EZSQL_ERROR ) ? count( $EZSQL_ERROR ) : 0;
$posts  = get_posts( $args );
$after  = isset( $EZSQL_ERROR ) ? count( $EZSQL_ERROR ) : 0;

if ( empty( $posts ) && $before < $after ) {
    // ... DB error(s) within get_posts() when it returns an empty array.
}

Here we check the number of wpdb errors before and after the get_posts() call from the global $EZSQL_ERROR errors collector (src).

But I can imagine that this might give a false positive in some cases though, e.g. if we hook a bad db calls within get_posts() that might not be the reason for empty posts array.

Update. I tested this and noticed that $wpdb->last_error is restored after each $wpdb call. I noticed the global $EZSQL_ERROR array within wpdb::print_error() that is not restored but collects the errors. I therefore updated the answer and replaced $wpdb->last_error with $EZSQL_ERROR.

  • Indeed, that's seems to be the answer for doing this. The cool part is that this global array will even have the query string that has been run... . But I can't get why It would be a false-positive. If we hook a bad database then almost the whole website will get nasty... the get_posts will query the database from which we get to the post we call this function from(or something relative, I use this in a wp-cron, So if this fails, I will just reprogram the cron). So for first that would be the one that will get the error... with every post on the website down... So can you explain what u meant? – Brada Feb 16 at 20:11
  • 1
    Glad to hear you found it somewhat useful @Brada. Ps: There are many ways to hook into ` get_posts()` (wrapper of WP_Query) and we could e.g. hook our own custom wpdb query call inside it with some error (maybe someone deleted a custom table that it depended on or something else) that would not be related to the empty array of ` get_posts()`. That was the case that first came to mind. – birgire Feb 16 at 23:59
  • Ah... I see, and that's true... but If It's a bad hook, then I think I couldn't retrieve in the first case the post from whom to start... anyway thanks for answering this. I have a new a little offtopic question... I want to get the related/recommended posts for a post. And to "not reinvent the wheel again" maybe It's happen for you to know a git a something for doing it?. I want to implement this on a theme, So I need only the Id's, and to not calculate everytime a page load(cache the things)... Thanks. – Brada Feb 17 at 5:06
  • I recall some of the related posts plugins used to be very resourceful on large sites, so many preferred to offload it to 3rd party services. I think that's e..g why JetPack started to offer it as a service and generate it offsite. I guess you could store the post ids in the post meta together with the unix time of generation time or expire time and add a basic logic to handle that. It would also depend on the available caching solutions. I don't think I would use the WordPress transients API, as it would store it in the options table, unless you're using external caching. – birgire Feb 17 at 10:15
  • That's exactly what I'm doing... I store an array with posts id's, and the last time it was calculated. Then I store in an option all posts when they have been updated/deleted/. If I need to recalculate(I will do this maxim only one time a day per post). Then I will just fetch the modified/added/deleted posts from option and calculate only for them. The calculate method will start with an WP-Cron ( using background-process-async api from github if you know what I'm speaking). – Brada Feb 17 at 10:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.