函数文档

discover_pingback_server_uri()

💡 云策文档标注

概述

discover_pingback_server_uri() 函数用于根据给定 URL 查找 pingback 服务器 URI。它通过检查 X-Pingback 头部和 HTML 中的 rel="pingback" 链接来实现,优先返回 X-Pingback 头部以提高效率。

关键要点

  • 函数接受两个参数:$url(必需,要 ping 的 URL)和 $deprecated(已弃用,不使用)。
  • 返回值为字符串(成功时包含 URI)或 false(失败时)。
  • 优先检查 X-Pingback 头部,若存在则直接返回,否则解析 HTML 内容查找 rel="pingback" 链接。
  • 函数会跳过 WordPress 上传目录中的 URL,并处理可能的错误和内容类型检查。
  • 内部使用 wp_safe_remote_head() 和 wp_safe_remote_get() 进行 HTTP 请求,确保安全性。

代码示例

function discover_pingback_server_uri( $url, $deprecated = '' ) {
    if ( ! empty( $deprecated ) ) {
        _deprecated_argument( __FUNCTION__, '2.7.0' );
    }

    $pingback_str_dquote = 'rel="pingback"';
    $pingback_str_squote = 'rel='pingback'';

    /** @todo Should use Filter Extension or custom preg_match instead. */
    $parsed_url = parse_url( $url );

    if ( ! isset( $parsed_url['host'] ) ) { // Not a URL. This should never happen.
        return false;
    }

    // Do not search for a pingback server on our own uploads.
    $uploads_dir = wp_get_upload_dir();
    if ( str_starts_with( $url, $uploads_dir['baseurl'] ) ) {
        return false;
    }

    $response = wp_safe_remote_head(
        $url,
        array(
            'timeout'     => 2,
            'httpversion' => '1.0',
        )
    );

    if ( is_wp_error( $response ) ) {
        return false;
    }

    if ( wp_remote_retrieve_header( $response, 'X-Pingback' ) ) {
        return wp_remote_retrieve_header( $response, 'X-Pingback' );
    }

    // Not an (x)html, sgml, or xml page, no use going further.
    if ( preg_match( '#(image|audio|video|model)/#is', wp_remote_retrieve_header( $response, 'Content-Type' ) ) ) {
        return false;
    }

    // Now do a GET since we're going to look in the HTML headers (and we're sure it's not a binary file).
    $response = wp_safe_remote_get(
        $url,
        array(
            'timeout'     => 2,
            'httpversion' => '1.0',
        )
    );

    if ( is_wp_error( $response ) ) {
        return false;
    }

    $contents = wp_remote_retrieve_body( $response );

    $pingback_link_offset_dquote = strpos( $contents, $pingback_str_dquote );
    $pingback_link_offset_squote = strpos( $contents, $pingback_str_squote );

    if ( $pingback_link_offset_dquote || $pingback_link_offset_squote ) {
        $quote                   = ( $pingback_link_offset_dquote ) ? '"' : ''';
        $pingback_link_offset    = ( '"' === $quote ) ? $pingback_link_offset_dquote : $pingback_link_offset_squote;
        $pingback_href_pos       = strpos( $contents, 'href=', $pingback_link_offset );
        $pingback_href_start     = $pingback_href_pos + 6;
        $pingback_href_end       = strpos( $contents, $quote, $pingback_href_start );
        $pingback_server_url_len = $pingback_href_end - $pingback_href_start;
        $pingback_server_url     = substr( $contents, $pingback_href_start, $pingback_server_url_len );

        // We may find rel="pingback" but an incomplete pingback URL.
        if ( $pingback_server_url_len > 0 ) { // We got it!
            return $pingback_server_url;
        }
    }

    return false;
}

注意事项

  • 函数自 WordPress 1.5.0 版本引入,$deprecated 参数在 2.7.0 版本后已弃用。
  • 优先使用 X-Pingback 头部,因为检查 rel="pingback" 链接有更高的开销。
  • 函数会跳过上传目录中的 URL,避免对自身资源进行 pingback 检查。
  • 内部使用安全 HTTP 请求函数(如 wp_safe_remote_head()),确保请求的安全性。
  • 相关函数包括 wp_get_upload_dir()、wp_safe_remote_head()、wp_remote_retrieve_header() 等,用于辅助操作。

📄 原文内容

Finds a pingback server URI based on the given URL.

Description

Checks the HTML for the rel=”pingback” link and X-Pingback headers. It does a check for the X-Pingback headers first and returns that, if available.
The check for the rel=”pingback” has more overhead than just the header.

Parameters

$urlstringrequired
URL to ping.
$deprecatedstringrequired
Not Used.

Return

string|false String containing URI on success, false on failure.

Source

function discover_pingback_server_uri( $url, $deprecated = '' ) {
	if ( ! empty( $deprecated ) ) {
		_deprecated_argument( __FUNCTION__, '2.7.0' );
	}

	$pingback_str_dquote = 'rel="pingback"';
	$pingback_str_squote = 'rel='pingback'';

	/** @todo Should use Filter Extension or custom preg_match instead. */
	$parsed_url = parse_url( $url );

	if ( ! isset( $parsed_url['host'] ) ) { // Not a URL. This should never happen.
		return false;
	}

	// Do not search for a pingback server on our own uploads.
	$uploads_dir = wp_get_upload_dir();
	if ( str_starts_with( $url, $uploads_dir['baseurl'] ) ) {
		return false;
	}

	$response = wp_safe_remote_head(
		$url,
		array(
			'timeout'     => 2,
			'httpversion' => '1.0',
		)
	);

	if ( is_wp_error( $response ) ) {
		return false;
	}

	if ( wp_remote_retrieve_header( $response, 'X-Pingback' ) ) {
		return wp_remote_retrieve_header( $response, 'X-Pingback' );
	}

	// Not an (x)html, sgml, or xml page, no use going further.
	if ( preg_match( '#(image|audio|video|model)/#is', wp_remote_retrieve_header( $response, 'Content-Type' ) ) ) {
		return false;
	}

	// Now do a GET since we're going to look in the HTML headers (and we're sure it's not a binary file).
	$response = wp_safe_remote_get(
		$url,
		array(
			'timeout'     => 2,
			'httpversion' => '1.0',
		)
	);

	if ( is_wp_error( $response ) ) {
		return false;
	}

	$contents = wp_remote_retrieve_body( $response );

	$pingback_link_offset_dquote = strpos( $contents, $pingback_str_dquote );
	$pingback_link_offset_squote = strpos( $contents, $pingback_str_squote );

	if ( $pingback_link_offset_dquote || $pingback_link_offset_squote ) {
		$quote                   = ( $pingback_link_offset_dquote ) ? '"' : ''';
		$pingback_link_offset    = ( '"' === $quote ) ? $pingback_link_offset_dquote : $pingback_link_offset_squote;
		$pingback_href_pos       = strpos( $contents, 'href=', $pingback_link_offset );
		$pingback_href_start     = $pingback_href_pos + 6;
		$pingback_href_end       = strpos( $contents, $quote, $pingback_href_start );
		$pingback_server_url_len = $pingback_href_end - $pingback_href_start;
		$pingback_server_url     = substr( $contents, $pingback_href_start, $pingback_server_url_len );

		// We may find rel="pingback" but an incomplete pingback URL.
		if ( $pingback_server_url_len > 0 ) { // We got it!
			return $pingback_server_url;
		}
	}

	return false;
}

Changelog

Version Description
1.5.0 Introduced.