$conf, $runtime; function_exists('chdir') AND chdir(APP_PATH); $r = 'mysql' == $conf['cache']['type'] ? website_set('runtime', $runtime) : cache_set('runtime', $runtime); } function runtime_truncate() { global $conf; 'mysql' == $conf['cache']['type'] ? website_set('runtime', '') : cache_delete('runtime'); } register_shutdown_function('runtime_save'); ?>wp query - WP_Query returns wrong post when searching by title?|Programmer puzzle solving
最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

wp query - WP_Query returns wrong post when searching by title?

matteradmin8PV0评论

The comments left in my code explain what's going on.

protected function fetchLocationByTitle($title) {

    /*
     * The WP Query class returns wrong post when searching by title using the
     * structure below
     *
     * $query = new \WP_Query([
     *   'post_type' => 'location-data',
     *   'posts_per_page' => 1,
     *   'page' => 1, // Tried removing this per Tom Nowell's post, but still get wrong post.
     *   'post_status' => 'publish',
     *   'post_title' => $title
     * ]);
     *
     * So to work around we'll pull it ourselves
     */
    global $wpdb;

    // Changed to $wpdb->prepare per Tom Nowell's comment.
    $id = $wpdb->get_results($wpdb->prepare(
      "SELECT `ID` 
      FROM `wp_posts` 
      WHERE `post_title` = %s 
      AND `post_type` = 'location-data' 
      AND `post_status` = 'publish' 
      LIMIT 1", $title));
    if ($id && count($id)) {
      $id = $id[0]->ID;
      /*
       * With ID in hand we can pull a post object normally now.
       */
      return $this->parseLocation(\get_post($id));
    } else {
      return null;
    }
  }

Can anyone spot why it fetches a different post from the correct one I can get with my direct query?

The comments left in my code explain what's going on.

protected function fetchLocationByTitle($title) {

    /*
     * The WP Query class returns wrong post when searching by title using the
     * structure below
     *
     * $query = new \WP_Query([
     *   'post_type' => 'location-data',
     *   'posts_per_page' => 1,
     *   'page' => 1, // Tried removing this per Tom Nowell's post, but still get wrong post.
     *   'post_status' => 'publish',
     *   'post_title' => $title
     * ]);
     *
     * So to work around we'll pull it ourselves
     */
    global $wpdb;

    // Changed to $wpdb->prepare per Tom Nowell's comment.
    $id = $wpdb->get_results($wpdb->prepare(
      "SELECT `ID` 
      FROM `wp_posts` 
      WHERE `post_title` = %s 
      AND `post_type` = 'location-data' 
      AND `post_status` = 'publish' 
      LIMIT 1", $title));
    if ($id && count($id)) {
      $id = $id[0]->ID;
      /*
       * With ID in hand we can pull a post object normally now.
       */
      return $this->parseLocation(\get_post($id));
    } else {
      return null;
    }
  }

Can anyone spot why it fetches a different post from the correct one I can get with my direct query?

Share Improve this question edited May 22 at 16:35 Michael Morris asked May 22 at 13:00 Michael MorrisMichael Morris 11 bronze badge 5
  • note that esc_sql should never be used that way and doesn't work as an arbitrary SQL escaping function despite what its name suggests, you should instead be using wpdb->prepare to insert variables into SQL statements. Also when you say search, can you clarify if you're providing an exact match, or expecting it to find similar things? I also see your SQL statement does not specify page, page may be incorrect as the docs say: "Show the number of posts that would show up on page X of a static front page.", are you sure you didn't mean paged? I don't think it's necessary to specify – Tom J Nowell Commented May 22 at 13:33
  • $wp->prepare applied. Removing the $page argument has no effect - still pulls the wrong post. I am expecting an exact match or no match at all. This method is a fallback in case my users fail to explicitly link the post to its facility, which they've done on roughly half the pages. – Michael Morris Commented May 22 at 16:30
  • when you say it pulls in a post it shouldn't can you give examples of what you tried and what it gave instead? I wasn't aware it pulled in anything from reading your question, it looks like it gives zero results, not 1 incorrect result. Have you expanded posts_per_page to check if the result you want is found but not the first result? Have you checked for pre_get_post filters modifying the query variables? – Tom J Nowell Commented May 22 at 21:03
  • Without going into too much detail on the post details, the post it should be hitting has ID 84626, and the one it fetches through \WP_QUERY is id 91325. The two have nothing in common except their post_type – Michael Morris Commented May 23 at 11:36
  • see my updated answer, it should explain the difference – Tom J Nowell Commented May 23 at 14:55
Add a comment  | 

2 Answers 2

Reset to default 0

We should be able to fix the query by doing this instead:

$query = new \WP_Query([
  'post_type' => 'location-data',
  'posts_per_page' => 1,
  'post_status' => 'publish',
  'title' => $title
]);

This is because page is unnecessary and may not be the parameter you actually needed, paged would have been more appropriate, but it too is unnecessary.

Most importantly though, post_title is not a parameter of WP_Query according to the docs, instead it lists title. post_title is only mentioned as a parameter for search columns.

you can simply use get_posts() :

$posts = get_posts( [
  'title'          => $title,
  'post_status'    => 'publish',
  'post_type'      => 'location-data',
  'posts_per_page' => 1,
] );

https://developer.wordpress/reference/functions/get_posts/

Post a comment

comment list (0)

  1. No comments so far