Функция GET_PAGE_BY_PATH() │ WP 2.1.0
Эта функция позволяет получить страницу по заданному пути.
Время выполнения — 0.000868 сек (медленно) | 50000 раз — 0.59 сек (очень быстро) | PHP 7.1.2, WP 4.7.3
Без хуков.
Возврат
Функция возвращает объект WP_Post, массив или null. Если операция прошла успешно, вы получите WP_Post (или массив); в случае неудачи — null.
Применение
get_page_by_path( $page_path, $output, $post_type );
$page_path(string) (обязательно) — Путь к странице.$output(string) — Тип возвращаемого значения. Один из объектов: OBJECT, ARRAY_A или ARRAY_N. Они соответствуют объекту WP_Post, ассоциативному массиву или числовому массиву соответственно. По умолчанию: OBJECT.$post_type(string|array) — Тип поста или массив типов постов. По умолчанию: 'page'.
Примеры использования
Пример 1: Получение страницы по её пути
Предположим, у нас есть дочерняя страница, доступная по URL example.com/parent-page/sub-page: parent-page/sub-page — это путь к странице. Теперь мы можем получить эту страницу в коде:
$page = get_page_by_path( 'parent-page/sub-page' );
// Или так
$page = get_page_by_path( '/parent-page/sub-page/' );
print_r( $page );
Важно: Если вы укажете только имя страницы, функция не в��рнёт ничего:
$page = get_page_by_path( 'sub-page' ); // > NULL
Однако, если страница не является дочерней, нужно указать только имя страницы — это "slug":
$page = get_page_by_path( 'page-name' ); // > WP_Post{ ... }
Пример 2: Использование с пользовательскими типами постов
Если у вас есть новый тип поста, то путь к такому типу поста обычно формируется по его имени. Например, если тип поста называется car, URL конкретного поста будет example.com/car/lada. Чтобы получить такой пост, нужно использовать только его короткое имя:
// Правильный вариант
$page = get_page_by_path( 'lada', OBJECT, 'car' );
// Неправильный вариант (не вернёт ничего)
$page = get_page_by_path( 'car/lada', OBJECT, 'car' );
Автоматическое добавление типа вложения
Эта функция автоматически добавит тип поста "вложение" к любым случаям, где тип поста передан в виде строки. Это сделано из-за следующего кода:
if ( is_array( $post_type ) ) {
$post_types = $post_type;
} else {
$post_types = array( $post_type, 'attachment' );
}
Если вам действительно нужно получить путь только для указанного типа поста, его нужно передать в массиве следующим образом:
// Запрос будет: post_type IN ( 'car' )
$page = get_page_by_path( 'lada', OBJECT, ['car'] );
// Запрос будет: post_type IN ( 'car', 'attachment' )
$page = get_page_by_path( 'lada', OBJECT, 'car' );
Эта ситуация была обнаружена, когда вложение, хранящееся в базе данных, имело такой же путь, как и страница, которую мы хотели получить. Вложение с меньшим ID поста возвращается в первую очередь.
Получение последней части пути
Вы можете использовать функции basename() и untrailingslashit(), чтобы получить последнюю часть пути:
$page_path = 'car/lada/';
$post_name = basename( untrailingslashit( $page_path ) );
$page = get_page_by_path( $post_name , OBJECT, 'car');
Заметки
- Глобальный объект базы данных WordPress:
$wpdb— является объектом абстракции базы данных.
Изменения
С версии 2.1.0 — внедрена функция.
Код функции GET_PAGE_BY_PATH()
Функция находится в файле wp-includes/post.php.
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 ) {
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 = "
SELECT ID, post_name, post_parent, post_type
FROM $wpdb->posts
WHERE post_name IN ($in_string)
AND post_type IN ($post_type_in_string)
";
$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 ( 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;
}
}
}
}
wp_cache_set( $cache_key, $foundid, 'post-queries' );
if ( $foundid ) {
return get_post( $foundid, $output );
}
return null;
}
Связанные функции
get_page_by_title()— получение страницы по заголовку.get_all_page_ids()— получение всех идентификаторов страниц.get_page_children()— получение дочерних страниц.get_page_link()— получение ссылки на страницу.get_page_template_slug()— получение шаблона страницы.get_page_uri()— получение URI страницы.get_pages()— получение страниц.get_post_ancestors()— получение предков поста.page_template_dropdown()— выпадающий список шаблонов страниц.parent_dropdown()— выпадающий список родительских страниц.wp_dropdown_pages()— выпадающий список страниц.wp_link_pages()— навигация по страницам.wp_list_pages()— список страниц.wp_page_menu()— меню страниц.