问题描述

有什么办法可以拿到图像的 URL,并在数据库中找到该图像的附件或帖子 ID?

这是情况:

我正在循环浏览我的帖子内容中包含 「a」 标签的所有 「img」 标签。如果’img’ 标签的 src 属性与外部’a’ 标签的 href 属性不匹配,那么我想替换’img’ 标签。在这样做时,如果要删除的 「img」 在画廊中,我想删除该帖子,然后将替换’img’ 放在其位置。我尝试使用这样的功能:

function find_image_post_id($url) {
  global $wpdb;
  $postid = $wpdb->get_var($wpdb->prepare("SELECT DISTINCT ID FROM $wpdb->posts WHERE guid='$url'"));
  if ($postid) {
    return $postid;
  }
  return false;
}

这显然是不正确的,因为指南是讽刺的不是全球唯一的。我已经 (早在同一个脚本) 上传了一个同名的文件 (为什么?因为它是更高的分辨率,我正在尝试替换相同图像的低分辨率版本),虽然 wordpress 将保存图像与不同的名称该目录中,guid 的设置是相同的。 (可能是一个错误) 。

是否有其他技术可以使用?

最佳解决方案

大量改进的功能开发为插件重的图像:

if ( ! function_exists( 'get_attachment_id' ) ) {
    /**
     * Get the Attachment ID for a given image URL.
     *
     * @link   http://wordpress.stackexchange.com/a/7094
     *
     * @param  string $url
     *
     * @return boolean|integer
     */
    function get_attachment_id( $url ) {

        $dir = wp_upload_dir();

        // baseurl never has a trailing slash
        if ( false === strpos( $url, $dir['baseurl'] . '/' ) ) {
            // URL points to a place outside of upload directory
            return false;
        }

        $file  = basename( $url );
        $query = array(
            'post_type'  => 'attachment',
            'fields'     => 'ids',
            'meta_query' => array(
                array(
                    'key'     => '_wp_attached_file',
                    'value'   => $file,
                    'compare' => 'LIKE',
                ),
            )
        );

        // query attachments
        $ids = get_posts( $query );

        if ( ! empty( $ids ) ) {

            foreach ( $ids as $id ) {

                // first entry of returned array is the URL
                if ( $url === array_shift( wp_get_attachment_image_src( $id, 'full' ) ) )
                    return $id;
            }
        }

        $query['meta_query'][0]['key'] = '_wp_attachment_metadata';

        // query attachments again
        $ids = get_posts( $query );

        if ( empty( $ids) )
            return false;

        foreach ( $ids as $id ) {

            $meta = wp_get_attachment_metadata( $id );

            foreach ( $meta['sizes'] as $size => $values ) {

                if ( $values['file'] === $file && $url === array_shift( wp_get_attachment_image_src( $id, $size ) ) )
                    return $id;
            }
        }

        return false;
    }
}

次佳解决方案

所有这些复杂的功能可以简化成一个简单的功能:

 attachment_url_to_postid()

您只需解析图像 URL 即可检索附件 ID:

$attachment_id = attachment_url_to_postid( $image_url );
echo $attachment_id;

这就是你需要的。

第三种解决方案

我修改了 Rarst 的代码,让您只匹配文件名而不是完整的路径。如果您要卸载图像,如果它不存在,这是有帮助的。目前,这只有在文件名是唯一的时候才有用,但是我稍后会添加哈希检查来帮助具有相同文件名的图像。

function get_attachment_id( $url, $ignore_path = false ) {

if ( ! $ignore_path ) {

    $dir = wp_upload_dir();
    $dir = trailingslashit($dir['baseurl']);

    if( false === strpos( $url, $dir ) )
        return false;
}

$file = basename($url);

$query = array(
    'post_type' => 'attachment',
    'fields' => 'ids',
    'meta_query' => array(
        array(
            'key'     => '_wp_attached_file',
            'value'   => $file,
            'compare' => 'LIKE',
        )
    )
);

$ids = get_posts( $query );

foreach( $ids as $id ) {
    $match = array_shift( wp_get_attachment_image_src($id, 'full') );
    if( $url == $match || ( $ignore_path && strstr( $match, $file ) ) )
        return $id;
}

$query['meta_query'][0]['key'] = '_wp_attachment_metadata';
$ids = get_posts( $query );

foreach( $ids as $id ) {

    $meta = wp_get_attachment_metadata($id);

    foreach( $meta['sizes'] as $size => $values ) {
        if( $values['file'] == $file && ( $ignore_path || $url == array_shift( wp_get_attachment_image_src($id, $size) ) ) )
            return $id;
    }
}

return false;
}

参考文献

注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。