get_page_by_path

The timeline below displays how wordpress function get_page_by_path has changed across different WordPress versions. If a version is not listed, refer to the next available version below.

WordPress Version: 6.4

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. The required return type. One of OBJECT, ARRAY_A, or ARRAY_N, which
 *                                correspond to a WP_Post object, an associative array, or a numeric array,
 *                                respectively. Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|array|null WP_Post (or array) on success, or null on failure.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $last_changed = wp_cache_get_last_changed('posts');
    $hash = md5($page_path . serialize($post_type));
    $cache_key = "get_page_by_path:{$hash}:{$last_changed}";
    $cached = wp_cache_get($cache_key, 'post-queries');
    if (false !== $cached) {
        // Special case: '0' is a bad `$page_path`.
        if ('0' === $cached || 0 === $cached) {
            return;
        } else {
            return get_post($cached, $output);
        }
    }
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = array_map('sanitize_title_for_query', $parts);
    $escaped_parts = esc_sql($parts);
    $in_string = "'" . implode("','", $escaped_parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            /*
             * Loop through the given path parts from right to left,
             * ensuring each matches the post ancestry.
             */
            while (0 != $p->post_parent && isset($pages[$p->post_parent])) {
                ++$count;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if (0 == $p->post_parent && count($revparts) === $count + 1 && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    // We cache misses as well as hits.
    wp_cache_set($cache_key, $foundid, 'post-queries');
    if ($foundid) {
        return get_post($foundid, $output);
    }
    return null;
}

WordPress Version: 6.3

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. The required return type. One of OBJECT, ARRAY_A, or ARRAY_N, which
 *                                correspond to a WP_Post object, an associative array, or a numeric array,
 *                                respectively. Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|array|null WP_Post (or array) on success, or null on failure.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $last_changed = wp_cache_get_last_changed('posts');
    $hash = md5($page_path . serialize($post_type));
    $cache_key = "get_page_by_path:{$hash}:{$last_changed}";
    $cached = wp_cache_get($cache_key, 'post-queries');
    if (false !== $cached) {
        // Special case: '0' is a bad `$page_path`.
        if ('0' === $cached || 0 === $cached) {
            return;
        } else {
            return get_post($cached, $output);
        }
    }
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = array_map('sanitize_title_for_query', $parts);
    $escaped_parts = esc_sql($parts);
    $in_string = "'" . implode("','", $escaped_parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            /*
             * Loop through the given path parts from right to left,
             * ensuring each matches the post ancestry.
             */
            while (0 != $p->post_parent && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if (0 == $p->post_parent && count($revparts) === $count + 1 && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    // We cache misses as well as hits.
    wp_cache_set($cache_key, $foundid, 'post-queries');
    if ($foundid) {
        return get_post($foundid, $output);
    }
    return null;
}

WordPress Version: 5.9

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. The required return type. One of OBJECT, ARRAY_A, or ARRAY_N, which
 *                                correspond to a WP_Post object, an associative array, or a numeric array,
 *                                respectively. Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|array|null WP_Post (or array) on success, or null on failure.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $last_changed = wp_cache_get_last_changed('posts');
    $hash = md5($page_path . serialize($post_type));
    $cache_key = "get_page_by_path:{$hash}:{$last_changed}";
    $cached = wp_cache_get($cache_key, 'posts');
    if (false !== $cached) {
        // Special case: '0' is a bad `$page_path`.
        if ('0' === $cached || 0 === $cached) {
            return;
        } else {
            return get_post($cached, $output);
        }
    }
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = array_map('sanitize_title_for_query', $parts);
    $escaped_parts = esc_sql($parts);
    $in_string = "'" . implode("','", $escaped_parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            /*
             * Loop through the given path parts from right to left,
             * ensuring each matches the post ancestry.
             */
            while (0 != $p->post_parent && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if (0 == $p->post_parent && count($revparts) == $count + 1 && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    // We cache misses as well as hits.
    wp_cache_set($cache_key, $foundid, 'posts');
    if ($foundid) {
        return get_post($foundid, $output);
    }
    return null;
}

WordPress Version: 5.5

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. The required return type. One of OBJECT, ARRAY_A, or ARRAY_N, which
 *                                correspond to a WP_Post object, an associative array, or a numeric array,
 *                                respectively. Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|array|null WP_Post (or array) on success, or null on failure.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $last_changed = wp_cache_get_last_changed('posts');
    $hash = md5($page_path . serialize($post_type));
    $cache_key = "get_page_by_path:{$hash}:{$last_changed}";
    $cached = wp_cache_get($cache_key, 'posts');
    if (false !== $cached) {
        // Special case: '0' is a bad `$page_path`.
        if ('0' === $cached || 0 === $cached) {
            return;
        } else {
            return get_post($cached, $output);
        }
    }
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = array_map('sanitize_title_for_query', $parts);
    $escaped_parts = esc_sql($parts);
    $in_string = "'" . implode("','", $escaped_parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            /*
             * Loop through the given path parts from right to left,
             * ensuring each matches the post ancestry.
             */
            while (0 != $p->post_parent && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if (0 == $p->post_parent && count($revparts) == $count + 1 && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    // We cache misses as well as hits.
    wp_cache_set($cache_key, $foundid, 'posts');
    if ($foundid) {
        return get_post($foundid, $output);
    }
}

WordPress Version: 5.4

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. The required return type. One of OBJECT, ARRAY_A, or ARRAY_N, which correspond to
 *                                a WP_Post object, an associative array, or a numeric array, respectively. Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|array|null WP_Post (or array) on success, or null on failure.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $last_changed = wp_cache_get_last_changed('posts');
    $hash = md5($page_path . serialize($post_type));
    $cache_key = "get_page_by_path:{$hash}:{$last_changed}";
    $cached = wp_cache_get($cache_key, 'posts');
    if (false !== $cached) {
        // Special case: '0' is a bad `$page_path`.
        if ('0' === $cached || 0 === $cached) {
            return;
        } else {
            return get_post($cached, $output);
        }
    }
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = array_map('sanitize_title_for_query', $parts);
    $escaped_parts = esc_sql($parts);
    $in_string = "'" . implode("','", $escaped_parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            /*
             * Loop through the given path parts from right to left,
             * ensuring each matches the post ancestry.
             */
            while (0 != $p->post_parent && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if (0 == $p->post_parent && count($revparts) == $count + 1 && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    // We cache misses as well as hits.
    wp_cache_set($cache_key, $foundid, 'posts');
    if ($foundid) {
        return get_post($foundid, $output);
    }
}

WordPress Version: 8.3

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. The required return type. One of OBJECT, ARRAY_A, or ARRAY_N, which correspond to
 *                                a WP_Post object, an associative array, or a numeric array, respectively. Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|array|null WP_Post (or array) on success, or null on failure.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $last_changed = wp_cache_get_last_changed('posts');
    $hash = md5($page_path . serialize($post_type));
    $cache_key = "get_page_by_path:{$hash}:{$last_changed}";
    $cached = wp_cache_get($cache_key, 'posts');
    if (false !== $cached) {
        // Special case: '0' is a bad `$page_path`.
        if ('0' === $cached || 0 === $cached) {
            return;
        } else {
            return get_post($cached, $output);
        }
    }
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = array_map('sanitize_title_for_query', $parts);
    $escaped_parts = esc_sql($parts);
    $in_string = "'" . implode("','", $escaped_parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            /*
             * Loop through the given path parts from right to left,
             * ensuring each matches the post ancestry.
             */
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    // We cache misses as well as hits.
    wp_cache_set($cache_key, $foundid, 'posts');
    if ($foundid) {
        return get_post($foundid, $output);
    }
}

WordPress Version: 8.2

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. The required return type. One of OBJECT, ARRAY_A, or ARRAY_N, which correspond to
 *                                a WP_Post object, an associative array, or a numeric array, respectively. Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|array|null WP_Post (or array) on success, or null on failure.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $last_changed = wp_cache_get_last_changed('posts');
    $hash = md5($page_path . serialize($post_type));
    $cache_key = "get_page_by_path:{$hash}:{$last_changed}";
    $cached = wp_cache_get($cache_key, 'posts');
    if (false !== $cached) {
        // Special case: '0' is a bad `$page_path`.
        if ('0' === $cached || 0 === $cached) {
            return;
        } else {
            return get_post($cached, $output);
        }
    }
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = esc_sql($parts);
    $parts = array_map('sanitize_title_for_query', $parts);
    $in_string = "'" . implode("','", $parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            /*
             * Loop through the given path parts from right to left,
             * ensuring each matches the post ancestry.
             */
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    // We cache misses as well as hits.
    wp_cache_set($cache_key, $foundid, 'posts');
    if ($foundid) {
        return get_post($foundid, $output);
    }
}

WordPress Version: .10

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. The required return type. One of OBJECT, ARRAY_A, or ARRAY_N, which correspond to
 *                                a WP_Post object, an associative array, or a numeric array, respectively. Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|array|null WP_Post (or array) on success, or null on failure.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $last_changed = wp_cache_get_last_changed('posts');
    $hash = md5($page_path . serialize($post_type));
    $cache_key = "get_page_by_path:{$hash}:{$last_changed}";
    $cached = wp_cache_get($cache_key, 'posts');
    if (false !== $cached) {
        // Special case: '0' is a bad `$page_path`.
        if ('0' === $cached || 0 === $cached) {
            return;
        } else {
            return get_post($cached, $output);
        }
    }
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = array_map('sanitize_title_for_query', $parts);
    $escaped_parts = esc_sql($parts);
    $in_string = "'" . implode("','", $escaped_parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            /*
             * Loop through the given path parts from right to left,
             * ensuring each matches the post ancestry.
             */
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    // We cache misses as well as hits.
    wp_cache_set($cache_key, $foundid, 'posts');
    if ($foundid) {
        return get_post($foundid, $output);
    }
}

WordPress Version: 4.7

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. The required return type. One of OBJECT, ARRAY_A, or ARRAY_N, which correspond to
 *                                a WP_Post object, an associative array, or a numeric array, respectively. Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|array|null WP_Post (or array) on success, or null on failure.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $last_changed = wp_cache_get_last_changed('posts');
    $hash = md5($page_path . serialize($post_type));
    $cache_key = "get_page_by_path:{$hash}:{$last_changed}";
    $cached = wp_cache_get($cache_key, 'posts');
    if (false !== $cached) {
        // Special case: '0' is a bad `$page_path`.
        if ('0' === $cached || 0 === $cached) {
            return;
        } else {
            return get_post($cached, $output);
        }
    }
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = esc_sql($parts);
    $parts = array_map('sanitize_title_for_query', $parts);
    $in_string = "'" . implode("','", $parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            /*
             * Loop through the given path parts from right to left,
             * ensuring each matches the post ancestry.
             */
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    // We cache misses as well as hits.
    wp_cache_set($cache_key, $foundid, 'posts');
    if ($foundid) {
        return get_post($foundid, $output);
    }
}

WordPress Version: 6.8

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|array|void WP_Post on success.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $last_changed = wp_cache_get('last_changed', 'posts');
    if (false === $last_changed) {
        $last_changed = microtime();
        wp_cache_set('last_changed', $last_changed, 'posts');
    }
    $hash = md5($page_path . serialize($post_type));
    $cache_key = "get_page_by_path:{$hash}:{$last_changed}";
    $cached = wp_cache_get($cache_key, 'posts');
    if (false !== $cached) {
        // Special case: '0' is a bad `$page_path`.
        if ('0' === $cached || 0 === $cached) {
            return;
        } else {
            return get_post($cached, $output);
        }
    }
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = array_map('sanitize_title_for_query', $parts);
    $escaped_parts = esc_sql($parts);
    $in_string = "'" . implode("','", $escaped_parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            /*
             * Loop through the given path parts from right to left,
             * ensuring each matches the post ancestry.
             */
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    // We cache misses as well as hits.
    wp_cache_set($cache_key, $foundid, 'posts');
    if ($foundid) {
        return get_post($foundid, $output);
    }
}

WordPress Version: 6.3

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|array|void WP_Post on success.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $last_changed = wp_cache_get('last_changed', 'posts');
    if (false === $last_changed) {
        $last_changed = microtime();
        wp_cache_set('last_changed', $last_changed, 'posts');
    }
    $hash = md5($page_path . serialize($post_type));
    $cache_key = "get_page_by_path:{$hash}:{$last_changed}";
    $cached = wp_cache_get($cache_key, 'posts');
    if (false !== $cached) {
        // Special case: '0' is a bad `$page_path`.
        if ('0' === $cached || 0 === $cached) {
            return;
        } else {
            return get_post($cached, $output);
        }
    }
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = esc_sql($parts);
    $parts = array_map('sanitize_title_for_query', $parts);
    $in_string = "'" . implode("','", $parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            /*
             * Loop through the given path parts from right to left,
             * ensuring each matches the post ancestry.
             */
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    // We cache misses as well as hits.
    wp_cache_set($cache_key, $foundid, 'posts');
    if ($foundid) {
        return get_post($foundid, $output);
    }
}

WordPress Version: .20

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|array|void WP_Post on success.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $last_changed = wp_cache_get('last_changed', 'posts');
    if (false === $last_changed) {
        $last_changed = microtime();
        wp_cache_set('last_changed', $last_changed, 'posts');
    }
    $hash = md5($page_path . serialize($post_type));
    $cache_key = "get_page_by_path:{$hash}:{$last_changed}";
    $cached = wp_cache_get($cache_key, 'posts');
    if (false !== $cached) {
        // Special case: '0' is a bad `$page_path`.
        if ('0' === $cached || 0 === $cached) {
            return;
        } else {
            return get_post($cached, $output);
        }
    }
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = array_map('sanitize_title_for_query', $parts);
    $escaped_parts = esc_sql($parts);
    $in_string = "'" . implode("','", $escaped_parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            /*
             * Loop through the given path parts from right to left,
             * ensuring each matches the post ancestry.
             */
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    // We cache misses as well as hits.
    wp_cache_set($cache_key, $foundid, 'posts');
    if ($foundid) {
        return get_post($foundid, $output);
    }
}

WordPress Version: 6.2

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|array|void WP_Post on success.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $last_changed = wp_cache_get('last_changed', 'posts');
    if (false === $last_changed) {
        $last_changed = microtime();
        wp_cache_set('last_changed', $last_changed, 'posts');
    }
    $hash = md5($page_path . serialize($post_type));
    $cache_key = "get_page_by_path:{$hash}:{$last_changed}";
    $cached = wp_cache_get($cache_key, 'posts');
    if (false !== $cached) {
        // Special case: '0' is a bad `$page_path`.
        if ('0' === $cached || 0 === $cached) {
            return;
        } else {
            return get_post($cached, $output);
        }
    }
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = esc_sql($parts);
    $parts = array_map('sanitize_title_for_query', $parts);
    $in_string = "'" . implode("','", $parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            /*
             * Loop through the given path parts from right to left,
             * ensuring each matches the post ancestry.
             */
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    // We cache misses as well as hits.
    wp_cache_set($cache_key, $foundid, 'posts');
    if ($foundid) {
        return get_post($foundid, $output);
    }
}

WordPress Version: .10

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|array|void WP_Post on success.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $last_changed = wp_cache_get('last_changed', 'posts');
    if (false === $last_changed) {
        $last_changed = microtime();
        wp_cache_set('last_changed', $last_changed, 'posts');
    }
    $hash = md5($page_path . serialize($post_type));
    $cache_key = "get_page_by_path:{$hash}:{$last_changed}";
    $cached = wp_cache_get($cache_key, 'posts');
    if (false !== $cached) {
        // Special case: '0' is a bad `$page_path`.
        if ('0' === $cached || 0 === $cached) {
            return;
        } else {
            return get_post($cached, $output);
        }
    }
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = array_map('sanitize_title_for_query', $parts);
    $escaped_parts = esc_sql($parts);
    $in_string = "'" . implode("','", $escaped_parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            /*
             * Loop through the given path parts from right to left,
             * ensuring each matches the post ancestry.
             */
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    // We cache misses as well as hits.
    wp_cache_set($cache_key, $foundid, 'posts');
    if ($foundid) {
        return get_post($foundid, $output);
    }
}

WordPress Version: 4.6

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|array|void WP_Post on success.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $last_changed = wp_cache_get('last_changed', 'posts');
    if (false === $last_changed) {
        $last_changed = microtime();
        wp_cache_set('last_changed', $last_changed, 'posts');
    }
    $hash = md5($page_path . serialize($post_type));
    $cache_key = "get_page_by_path:{$hash}:{$last_changed}";
    $cached = wp_cache_get($cache_key, 'posts');
    if (false !== $cached) {
        // Special case: '0' is a bad `$page_path`.
        if ('0' === $cached || 0 === $cached) {
            return;
        } else {
            return get_post($cached, $output);
        }
    }
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = esc_sql($parts);
    $parts = array_map('sanitize_title_for_query', $parts);
    $in_string = "'" . implode("','", $parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            /*
             * Loop through the given path parts from right to left,
             * ensuring each matches the post ancestry.
             */
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    // We cache misses as well as hits.
    wp_cache_set($cache_key, $foundid, 'posts');
    if ($foundid) {
        return get_post($foundid, $output);
    }
}

WordPress Version: 5.4

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|array|void WP_Post on success.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = esc_sql($parts);
    $parts = array_map('sanitize_title_for_query', $parts);
    $in_string = "'" . implode("','", $parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            /*
             * Loop through the given path parts from right to left,
             * ensuring each matches the post ancestry.
             */
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
}

WordPress Version: .30

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|array|void WP_Post on success.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = array_map('sanitize_title_for_query', $parts);
    $escaped_parts = esc_sql($parts);
    $in_string = "'" . implode("','", $escaped_parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            /*
             * Loop through the given path parts from right to left,
             * ensuring each matches the post ancestry.
             */
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
}

WordPress Version: 5.3

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|array|void WP_Post on success.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = esc_sql($parts);
    $parts = array_map('sanitize_title_for_query', $parts);
    $in_string = "'" . implode("','", $parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            /*
             * Loop through the given path parts from right to left,
             * ensuring each matches the post ancestry.
             */
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
}

WordPress Version: .20

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|array|void WP_Post on success.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = array_map('sanitize_title_for_query', $parts);
    $escaped_parts = esc_sql($parts);
    $in_string = "'" . implode("','", $escaped_parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            /*
             * Loop through the given path parts from right to left,
             * ensuring each matches the post ancestry.
             */
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
}

WordPress Version: 5.2

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|array|void WP_Post on success.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = esc_sql($parts);
    $parts = array_map('sanitize_title_for_query', $parts);
    $in_string = "'" . implode("','", $parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            /*
             * Loop through the given path parts from right to left,
             * ensuring each matches the post ancestry.
             */
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
}

WordPress Version: .11

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|array|void WP_Post on success.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = array_map('sanitize_title_for_query', $parts);
    $escaped_parts = esc_sql($parts);
    $in_string = "'" . implode("','", $escaped_parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            /*
             * Loop through the given path parts from right to left,
             * ensuring each matches the post ancestry.
             */
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
}

WordPress Version: 4.5

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|array|void WP_Post on success.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = esc_sql($parts);
    $parts = array_map('sanitize_title_for_query', $parts);
    $in_string = "'" . implode("','", $parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            /*
             * Loop through the given path parts from right to left,
             * ensuring each matches the post ancestry.
             */
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
}

WordPress Version: 4.4

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|array|void WP_Post on success.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = esc_sql($parts);
    $parts = array_map('sanitize_title_for_query', $parts);
    $in_string = "'" . implode("','", $parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
}

WordPress Version: .30

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|array|void WP_Post on success.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = array_map('sanitize_title_for_query', $parts);
    $escaped_parts = esc_sql($parts);
    $in_string = "'" . implode("','", $escaped_parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
}

WordPress Version: 4.3

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|array|void WP_Post on success.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = esc_sql($parts);
    $parts = array_map('sanitize_title_for_query', $parts);
    $in_string = "'" . implode("','", $parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
}

WordPress Version: .20

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|array|void WP_Post on success.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = array_map('sanitize_title_for_query', $parts);
    $escaped_parts = esc_sql($parts);
    $in_string = "'" . implode("','", $escaped_parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
}

WordPress Version: 4.2

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|array|void WP_Post on success.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = esc_sql($parts);
    $parts = array_map('sanitize_title_for_query', $parts);
    $in_string = "'" . implode("','", $parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
}

WordPress Version: .12

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|array|void WP_Post on success.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = array_map('sanitize_title_for_query', $parts);
    $escaped_parts = esc_sql($parts);
    $in_string = "'" . implode("','", $escaped_parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
}

WordPress Version: 3.4

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|array|void WP_Post on success.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = esc_sql($parts);
    $parts = array_map('sanitize_title_for_query', $parts);
    $in_string = "'" . implode("','", $parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
}

WordPress Version: .30

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|array|void WP_Post on success.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = array_map('sanitize_title_for_query', $parts);
    $escaped_parts = esc_sql($parts);
    $in_string = "'" . implode("','", $escaped_parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
}

WordPress Version: 3.3

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|array|void WP_Post on success.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = esc_sql($parts);
    $parts = array_map('sanitize_title_for_query', $parts);
    $in_string = "'" . implode("','", $parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
}

WordPress Version: .20

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|array|void WP_Post on success.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = array_map('sanitize_title_for_query', $parts);
    $escaped_parts = esc_sql($parts);
    $in_string = "'" . implode("','", $escaped_parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
}

WordPress Version: 3.2

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|array|void WP_Post on success.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = esc_sql($parts);
    $parts = array_map('sanitize_title_for_query', $parts);
    $in_string = "'" . implode("','", $parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
}

WordPress Version: .13

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|array|void WP_Post on success.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = array_map('sanitize_title_for_query', $parts);
    $escaped_parts = esc_sql($parts);
    $in_string = "'" . implode("','", $escaped_parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
}

WordPress Version: 4.3

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|array|void WP_Post on success.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = esc_sql($parts);
    $parts = array_map('sanitize_title_for_query', $parts);
    $in_string = "'" . implode("','", $parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
}

WordPress Version: 2.4

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|null WP_Post on success or null on failure.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = esc_sql($parts);
    $parts = array_map('sanitize_title_for_query', $parts);
    $in_string = "'" . implode("','", $parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
    return null;
}

WordPress Version: .30

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|null WP_Post on success or null on failure.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = array_map('sanitize_title_for_query', $parts);
    $escaped_parts = esc_sql($parts);
    $in_string = "'" . implode("','", $escaped_parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
    return null;
}

WordPress Version: 2.3

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|null WP_Post on success or null on failure.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = esc_sql($parts);
    $parts = array_map('sanitize_title_for_query', $parts);
    $in_string = "'" . implode("','", $parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
    return null;
}

WordPress Version: .20

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|null WP_Post on success or null on failure.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = array_map('sanitize_title_for_query', $parts);
    $escaped_parts = esc_sql($parts);
    $in_string = "'" . implode("','", $escaped_parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
    return null;
}

WordPress Version: 2.2

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|null WP_Post on success or null on failure.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = esc_sql($parts);
    $parts = array_map('sanitize_title_for_query', $parts);
    $in_string = "'" . implode("','", $parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
    return null;
}

WordPress Version: .17

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|null WP_Post on success or null on failure.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = array_map('sanitize_title_for_query', $parts);
    $escaped_parts = esc_sql($parts);
    $in_string = "'" . implode("','", $escaped_parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
    return null;
}

WordPress Version: 1.5

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|null WP_Post on success or null on failure.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = esc_sql($parts);
    $parts = array_map('sanitize_title_for_query', $parts);
    $in_string = "'" . implode("','", $parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
    return null;
}

WordPress Version: .40

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|null WP_Post on success or null on failure.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = array_map('sanitize_title_for_query', $parts);
    $escaped_parts = esc_sql($parts);
    $in_string = "'" . implode("','", $escaped_parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
    return null;
}

WordPress Version: 1.4

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|null WP_Post on success or null on failure.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = esc_sql($parts);
    $parts = array_map('sanitize_title_for_query', $parts);
    $in_string = "'" . implode("','", $parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
    return null;
}

WordPress Version: .30

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|null WP_Post on success or null on failure.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = array_map('sanitize_title_for_query', $parts);
    $escaped_parts = esc_sql($parts);
    $in_string = "'" . implode("','", $escaped_parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
    return null;
}

WordPress Version: 1.3

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|null WP_Post on success or null on failure.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = esc_sql($parts);
    $parts = array_map('sanitize_title_for_query', $parts);
    $in_string = "'" . implode("','", $parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
    return null;
}

WordPress Version: .20

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|null WP_Post on success or null on failure.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = array_map('sanitize_title_for_query', $parts);
    $escaped_parts = esc_sql($parts);
    $in_string = "'" . implode("','", $escaped_parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
    return null;
}

WordPress Version: 0.4

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|null WP_Post on success or null on failure.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = esc_sql($parts);
    $parts = array_map('sanitize_title_for_query', $parts);
    $in_string = "'" . implode("','", $parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
    return null;
}

WordPress Version: .30

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|null WP_Post on success or null on failure.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = array_map('sanitize_title_for_query', $parts);
    $escaped_parts = esc_sql($parts);
    $in_string = "'" . implode("','", $escaped_parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
    return null;
}

WordPress Version: 0.3

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|null WP_Post on success or null on failure.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = esc_sql($parts);
    $parts = array_map('sanitize_title_for_query', $parts);
    $in_string = "'" . implode("','", $parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
    return null;
}

WordPress Version: .20

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|null WP_Post on success or null on failure.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = array_map('sanitize_title_for_query', $parts);
    $escaped_parts = esc_sql($parts);
    $in_string = "'" . implode("','", $escaped_parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
    return null;
}

WordPress Version: 4.0

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string       $page_path Page path.
 * @param string       $output    Optional. Output type. Accepts OBJECT, ARRAY_N, or ARRAY_A.
 *                                Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
 * @return WP_Post|null WP_Post on success or null on failure.
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = esc_sql($parts);
    $parts = array_map('sanitize_title_for_query', $parts);
    $in_string = "'" . implode("','", $parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
    return null;
}

WordPress Version: 3.9

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 * @uses $wpdb
 *
 * @param string $page_path Page path
 * @param string $output Optional. Output type. OBJECT, ARRAY_N, or ARRAY_A. Default OBJECT.
 * @param string|array $post_type Optional. Post type or array of post types. Default page.
 * @return WP_Post|null WP_Post on success or null on failure
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = esc_sql($parts);
    $parts = array_map('sanitize_title_for_query', $parts);
    $in_string = "'" . implode("','", $parts) . "'";
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type, 'attachment');
    }
    $post_types = esc_sql($post_types);
    $post_type_in_string = "'" . implode("','", $post_types) . "'";
    $sql = "\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN ({$in_string})\n\t\tAND post_type IN ({$post_type_in_string})\n\t";
    $pages = $wpdb->get_results($sql, OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
    return null;
}

WordPress Version: 8.4

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 * @uses $wpdb
 *
 * @param string $page_path Page path
 * @param string $output Optional. Output type. OBJECT, ARRAY_N, or ARRAY_A. Default OBJECT.
 * @param string $post_type Optional. Post type. Default page.
 * @return WP_Post|null WP_Post on success or null on failure
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = esc_sql($parts);
    $parts = array_map('sanitize_title_for_query', $parts);
    $in_string = "'" . implode("','", $parts) . "'";
    $post_type_sql = esc_sql($post_type);
    $pages = $wpdb->get_results("SELECT ID, post_name, post_parent, post_type FROM {$wpdb->posts} WHERE post_name IN ({$in_string}) AND (post_type = '{$post_type_sql}' OR post_type = 'attachment')", OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
    return null;
}

WordPress Version: .30

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 * @uses $wpdb
 *
 * @param string $page_path Page path
 * @param string $output Optional. Output type. OBJECT, ARRAY_N, or ARRAY_A. Default OBJECT.
 * @param string $post_type Optional. Post type. Default page.
 * @return WP_Post|null WP_Post on success or null on failure
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = array_map('sanitize_title_for_query', $parts);
    $escaped_parts = esc_sql($parts);
    $in_string = "'" . implode("','", $escaped_parts) . "'";
    $post_type_sql = esc_sql($post_type);
    $pages = $wpdb->get_results("SELECT ID, post_name, post_parent, post_type FROM {$wpdb->posts} WHERE post_name IN ({$in_string}) AND (post_type = '{$post_type_sql}' OR post_type = 'attachment')", OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
    return null;
}

WordPress Version: 8.3

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 * @uses $wpdb
 *
 * @param string $page_path Page path
 * @param string $output Optional. Output type. OBJECT, ARRAY_N, or ARRAY_A. Default OBJECT.
 * @param string $post_type Optional. Post type. Default page.
 * @return WP_Post|null WP_Post on success or null on failure
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = esc_sql($parts);
    $parts = array_map('sanitize_title_for_query', $parts);
    $in_string = "'" . implode("','", $parts) . "'";
    $post_type_sql = esc_sql($post_type);
    $pages = $wpdb->get_results("SELECT ID, post_name, post_parent, post_type FROM {$wpdb->posts} WHERE post_name IN ({$in_string}) AND (post_type = '{$post_type_sql}' OR post_type = 'attachment')", OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
    return null;
}

WordPress Version: .23

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 * @uses $wpdb
 *
 * @param string $page_path Page path
 * @param string $output Optional. Output type. OBJECT, ARRAY_N, or ARRAY_A. Default OBJECT.
 * @param string $post_type Optional. Post type. Default page.
 * @return WP_Post|null WP_Post on success or null on failure
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = array_map('sanitize_title_for_query', $parts);
    $escaped_parts = esc_sql($parts);
    $in_string = "'" . implode("','", $escaped_parts) . "'";
    $post_type_sql = esc_sql($post_type);
    $pages = $wpdb->get_results("SELECT ID, post_name, post_parent, post_type FROM {$wpdb->posts} WHERE post_name IN ({$in_string}) AND (post_type = '{$post_type_sql}' OR post_type = 'attachment')", OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
    return null;
}

WordPress Version: 7.5

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 * @uses $wpdb
 *
 * @param string $page_path Page path
 * @param string $output Optional. Output type. OBJECT, ARRAY_N, or ARRAY_A. Default OBJECT.
 * @param string $post_type Optional. Post type. Default page.
 * @return WP_Post|null WP_Post on success or null on failure
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = esc_sql($parts);
    $parts = array_map('sanitize_title_for_query', $parts);
    $in_string = "'" . implode("','", $parts) . "'";
    $post_type_sql = esc_sql($post_type);
    $pages = $wpdb->get_results("SELECT ID, post_name, post_parent, post_type FROM {$wpdb->posts} WHERE post_name IN ({$in_string}) AND (post_type = '{$post_type_sql}' OR post_type = 'attachment')", OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
    return null;
}

WordPress Version: .40

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 * @uses $wpdb
 *
 * @param string $page_path Page path
 * @param string $output Optional. Output type. OBJECT, ARRAY_N, or ARRAY_A. Default OBJECT.
 * @param string $post_type Optional. Post type. Default page.
 * @return WP_Post|null WP_Post on success or null on failure
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = array_map('sanitize_title_for_query', $parts);
    $escaped_parts = esc_sql($parts);
    $in_string = "'" . implode("','", $escaped_parts) . "'";
    $post_type_sql = esc_sql($post_type);
    $pages = $wpdb->get_results("SELECT ID, post_name, post_parent, post_type FROM {$wpdb->posts} WHERE post_name IN ({$in_string}) AND (post_type = '{$post_type_sql}' OR post_type = 'attachment')", OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
    return null;
}

WordPress Version: 7.4

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 * @uses $wpdb
 *
 * @param string $page_path Page path
 * @param string $output Optional. Output type. OBJECT, ARRAY_N, or ARRAY_A. Default OBJECT.
 * @param string $post_type Optional. Post type. Default page.
 * @return WP_Post|null WP_Post on success or null on failure
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = esc_sql($parts);
    $parts = array_map('sanitize_title_for_query', $parts);
    $in_string = "'" . implode("','", $parts) . "'";
    $post_type_sql = esc_sql($post_type);
    $pages = $wpdb->get_results("SELECT ID, post_name, post_parent, post_type FROM {$wpdb->posts} WHERE post_name IN ({$in_string}) AND (post_type = '{$post_type_sql}' OR post_type = 'attachment')", OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
    return null;
}

WordPress Version: .30

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 * @uses $wpdb
 *
 * @param string $page_path Page path
 * @param string $output Optional. Output type. OBJECT, ARRAY_N, or ARRAY_A. Default OBJECT.
 * @param string $post_type Optional. Post type. Default page.
 * @return WP_Post|null WP_Post on success or null on failure
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = array_map('sanitize_title_for_query', $parts);
    $escaped_parts = esc_sql($parts);
    $in_string = "'" . implode("','", $escaped_parts) . "'";
    $post_type_sql = esc_sql($post_type);
    $pages = $wpdb->get_results("SELECT ID, post_name, post_parent, post_type FROM {$wpdb->posts} WHERE post_name IN ({$in_string}) AND (post_type = '{$post_type_sql}' OR post_type = 'attachment')", OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
    return null;
}

WordPress Version: 7.3

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 * @uses $wpdb
 *
 * @param string $page_path Page path
 * @param string $output Optional. Output type. OBJECT, ARRAY_N, or ARRAY_A. Default OBJECT.
 * @param string $post_type Optional. Post type. Default page.
 * @return WP_Post|null WP_Post on success or null on failure
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = esc_sql($parts);
    $parts = array_map('sanitize_title_for_query', $parts);
    $in_string = "'" . implode("','", $parts) . "'";
    $post_type_sql = esc_sql($post_type);
    $pages = $wpdb->get_results("SELECT ID, post_name, post_parent, post_type FROM {$wpdb->posts} WHERE post_name IN ({$in_string}) AND (post_type = '{$post_type_sql}' OR post_type = 'attachment')", OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
    return null;
}

WordPress Version: .23

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 * @uses $wpdb
 *
 * @param string $page_path Page path
 * @param string $output Optional. Output type. OBJECT, ARRAY_N, or ARRAY_A. Default OBJECT.
 * @param string $post_type Optional. Post type. Default page.
 * @return WP_Post|null WP_Post on success or null on failure
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = array_map('sanitize_title_for_query', $parts);
    $escaped_parts = esc_sql($parts);
    $in_string = "'" . implode("','", $escaped_parts) . "'";
    $post_type_sql = esc_sql($post_type);
    $pages = $wpdb->get_results("SELECT ID, post_name, post_parent, post_type FROM {$wpdb->posts} WHERE post_name IN ({$in_string}) AND (post_type = '{$post_type_sql}' OR post_type = 'attachment')", OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
    return null;
}

WordPress Version: 3.7

/**
 * Retrieves a page given its path.
 *
 * @since 2.1.0
 * @uses $wpdb
 *
 * @param string $page_path Page path
 * @param string $output Optional. Output type. OBJECT, ARRAY_N, or ARRAY_A. Default OBJECT.
 * @param string $post_type Optional. Post type. Default page.
 * @return WP_Post|null WP_Post on success or null on failure
 */
function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page')
{
    global $wpdb;
    $page_path = rawurlencode(urldecode($page_path));
    $page_path = str_replace('%2F', '/', $page_path);
    $page_path = str_replace('%20', ' ', $page_path);
    $parts = explode('/', trim($page_path, '/'));
    $parts = esc_sql($parts);
    $parts = array_map('sanitize_title_for_query', $parts);
    $in_string = "'" . implode("','", $parts) . "'";
    $post_type_sql = esc_sql($post_type);
    $pages = $wpdb->get_results("SELECT ID, post_name, post_parent, post_type FROM {$wpdb->posts} WHERE post_name IN ({$in_string}) AND (post_type = '{$post_type_sql}' OR post_type = 'attachment')", OBJECT_K);
    $revparts = array_reverse($parts);
    $foundid = 0;
    foreach ((array) $pages as $page) {
        if ($page->post_name == $revparts[0]) {
            $count = 0;
            $p = $page;
            while ($p->post_parent != 0 && isset($pages[$p->post_parent])) {
                $count++;
                $parent = $pages[$p->post_parent];
                if (!isset($revparts[$count]) || $parent->post_name != $revparts[$count]) {
                    break;
                }
                $p = $parent;
            }
            if ($p->post_parent == 0 && $count + 1 == count($revparts) && $p->post_name == $revparts[$count]) {
                $foundid = $page->ID;
                if ($page->post_type == $post_type) {
                    break;
                }
            }
        }
    }
    if ($foundid) {
        return get_post($foundid, $output);
    }
    return null;
}