Как использовать функцию URL_TO_POSTID() в WordPress

URL_TO_POSTID() │ WP 1.0.0

Функция url_to_postid() позволяет получить ID поста или страницы, используя переданный URL. Она анализирует URL и пытается определить, какому посту он соответствует.

Как это работает?

Сначала функция проверяет, содержит ли URL данные о ID. Если не содержит, она выполняет дополнительные проверки: пробует найти ID, используя правила переопределения WordPress (rewrite rules).

Эту функцию можно рассматривать как противоположность функции get_permalink().

Если вы используете url_to_postid() для получения ID вложения (например, изображения), необходимо, чтобы URL имел формат: example.com/?attachment_id=N. Если вы передадите ссылку на файл изображения, ID не будет определён. Чтобы определить ID по ссылке на файл изображения, можно использовать следующий код:

Получение ID вложения по URL файла

function pippin_get_image_id( $image_url ) {
    global $wpdb;
    $attachment = $wpdb->get_col($wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE guid='%s';", $image_url ));
    return $attachment[0];
}

Этот код не самый быстрый, поскольку поле guid не содержит индексов в базе данных, поэтому для поиска запросу необходимо проверять все поля guid.

С версии 4.0 была введена специальная функция, с помощью которой можно получить ID вложения, передав ссылку на вложение: attachment_url_to_postid().

Примечание:

  • Функция не возвращает ID для пользовательских типов постов.

Использование функции:

Функция используется, например, в get_oembed_response_data_for_url() и is_local_attachment().

Производительность

  • Исполнение 1 раза — 0.00195 сек (очень медленно)
  • Исполнение 50000 раз — 93.01 сек (очень медленно)

Хуки функции

  • url_to_postid

Возвращаемое значение

  • Integer: ID поста или 0 в случае ошибки.

Как использовать?

$url = 'http://example.com/our-company/news/dinner-tcworld-2010.html';
$post_ID = url_to_postid( $url );
echo "Post ID = $post_ID";

Пример использования функции

var_dump( url_to_postid( 'https://wp-kama.ru/function/url_to_postid' ) ); // int(733)
var_dump( url_to_postid( '/function/url_to_postid' ) ); // int(733)
var_dump( url_to_postid( 'https://wp-kama.ru/id_15476/dopolnitelnye-polya-dlya-wp_nav_menu.html' ) ); // int(15476)
var_dump( url_to_postid( '/id_15476/dopolnitelnye-polya-dlya-wp_nav_menu.html' ) ); // int(15476)

Примечания

  • Глобальная переменная $wp_rewrite используется для доступа к компоненту переопределения WordPress.
  • Глобальная переменная $wp представляет текущий экземпляр окружения WordPress.

Изменения

  • Версия 1.0.0 — первоначальное введение функции.

Внутренние детали реализации функции URL_TO_POSTID()

function url_to_postid( $url ) {
    global $wp_rewrite;

    // Применяем фильтры к URL для получения ID поста.
    $url = apply_filters( 'url_to_postid', $url );

    $url_host = parse_url( $url, PHP_URL_HOST );

    // Удаляем www из хоста URL.
    $url_host = is_string( $url_host ) ? str_replace( 'www.', '', $url_host ) : '';

    $home_url_host = parse_url( home_url(), PHP_URL_HOST );
    $home_url_host = is_string( $home_url_host ) ? str_replace( 'www.', '', $home_url_host ) : '';

    // Если хост URL не принадлежит этому сайту, выходим.
    if ( $url_host && $url_host !== $home_url_host ) {
        return 0;
    }

    // Проверяем наличие 'p=N' или 'page_id=N' в URL.
    if ( preg_match( '#[?&](p|page_id|attachment_id)=(d+)#', $url, $values ) ) {
        $id = absint( $values[2] );
        if ( $id ) {
            return $id;
        }
    }

    // Убираем якорь из URL.
    $url_split = explode( '#', $url );
    $url = $url_split[0];

    // Убираем параметры запроса из URL.
    $url_split = explode( '?', $url );
    $url = $url_split[0];

    // Устанавливаем корректный схему для URL.
    $scheme = parse_url( home_url(), PHP_URL_SCHEME );
    $url = set_url_scheme( $url, $scheme );

    // Добавляем 'www.' если его нет и он должен быть.
    if ( str_contains( home_url(), '://www.' ) && ! str_contains( $url, '://www.' ) ) {
        $url = str_replace( '://', '://www.', $url );
    }

    // Убираем 'www.' если он есть, но не должен быть.
    if ( ! str_contains( home_url(), '://www.' ) ) {
        $url = str_replace( '://www.', '://', $url );
    }

    // Проверяем страницу на главной, если установлен параметр 'page'.
    if ( trim( $url, '/' ) === home_url() && 'page' === get_option( 'show_on_front' ) ) {
        $page_on_front = get_option( 'page_on_front' );

        if ( $page_on_front && get_post( $page_on_front ) instanceof WP_Post ) {
            return (int) $page_on_front;
        }
    }

    // Проверяем правила переопределения.
    $rewrite = $wp_rewrite->wp_rewrite_rules();

    // Если правил нет, возвращаем 0.
    if ( empty( $rewrite ) ) {
        return 0;
    }

    // Убираем 'index.php/' если не используем пермёлки.
    if ( ! $wp_rewrite->using_index_permalinks() ) {
        $url = str_replace( $wp_rewrite->index . '/', '', $url );
    }

    // Обрабатываем URL.
    if ( str_contains( trailingslashit( $url ), home_url( '/' ) ) ) {
        $url = str_replace( home_url(), '', $url );
    } else {
        $home_path = parse_url( home_url( '/' ) );
        $home_path = isset( $home_path['path'] ) ? $home_path['path'] : '';
        $url = preg_replace( sprintf( '#^%s#', preg_quote( $home_path ) ), '', trailingslashit( $url ) );
    }

    // Убираем лишние слеши.
    $url = trim( $url, '/' );

    $request = $url;
    $post_type_query_vars = array();

    // Получаем все типы постов.
    foreach ( get_post_types( array(), 'objects' ) as $post_type => $t ) {
        if ( ! empty( $t->query_var ) ) {
            $post_type_query_vars[ $t->query_var ] = $post_type;
        }
    }

    // Ищем соответствия.
    $request_match = $request;
    foreach ( (array) $rewrite as $match => $query ) {
        // Если запрашиваемый файл является частью соответствия, включаем его в путь.
        if ( ! empty( $url ) && ( $url !== $request ) && str_starts_with( $match, $url ) ) {
            $request_match = $url . '/' . $request;
        }

        if ( preg_match( "#^$match#", $request_match, $matches ) ) {
            // Проверяем соотвествие и фильтруем не публичные переменные запроса.
            // Выполняем запрос и возвращаем ID.
            $query = preg_replace( '!^.+?!', '', $query );
            $query = addslashes( WP_MatchesMapRegex::apply( $query, $matches ) );

            global $wp;
            parse_str( $query, $query_vars );
            $query = array();
            foreach ( (array) $query_vars as $key => $value ) {
                if ( in_array( (string) $key, $wp->public_query_vars, true ) ) {
                    $query[ $key ] = $value;
                    if ( isset( $post_type_query_vars[ $key ] ) ) {
                        $query['post_type'] = $post_type_query_vars[ $key ];
                        $query['name']      = $value;
                    }
                }
            }

            // Дел��ет запрос и возвращает ID поста.
            $query = new WP_Query( $query );
            if ( ! empty( $query->posts ) && $query->is_singular ) {
                return $query->post->ID;
            } else {
                return 0;
            }
        }
    }
    return 0;
}

Связанные функции

  • admin_url()
  • attachment_url_to_postid()
  • home_url()
  • и другие.

Эти функции могут быть полезны при работе с URL и постами в WordPress.

Leave a Reply

Ваш адрес email не будет опубликован. Обязательные поля помечены *