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.
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. |