将URL转换为附件/帖子ID

时间:2011-01-10 作者:Ankur

是否有任何方法可以获取图像的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;
}
这显然是不对的,因为具有讽刺意味的是,guid不是全局唯一的。我(之前在同一脚本中)上载了一个同名文件(为什么?因为它的分辨率更高,我正在尝试替换同一图像的低分辨率版本),虽然wordpress将使用不同的名称在目录中保存图像,但guid设置为相同。(可能是一个bug)。

我还能使用其他技术吗?

6 个回复
最合适的回答,由SO网友:Rarst 整理而成

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

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;
    }
}

SO网友:Ego Ipse

所有这些复杂函数都可以简化为一个简单函数:

attachment_url_to_postid()

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

$attachment_id = attachment_url_to_postid( $image_url );
echo $attachment_id;
这就是你所需要的。

SO网友:Luke Gedeon

我修改了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;
}

SO网友:DevTurtle

好吧,我找到了答案,我已经在网上找了好几天了。请记住,只有当您的主题或插件使用WP_Customize_Image_Control() 如果您正在使用WP_Customize_Media_Control() 这个get_theme_mod() 将返回ID而不是url。

对于我的解决方案,我使用的是更新版本WP_Customize_Image_Control()

论坛上的很多帖子都有get_attachment_id() 这已经不起作用了。我曾经attachment_url_to_postid()

下面是我如何做到这一点的。希望这对其他人有帮助

// This is getting the image / url
$feature1 = get_theme_mod(\'feature_image_1\');

// This is getting the post id
$feature1_id = attachment_url_to_postid($feature1);

// This is getting the alt text from the image that is set in the media area
$image1_alt = get_post_meta( $feature1_id, \'_wp_attachment_image_alt\', true );
标记

<a href="<?php echo $feature1_url; ?>"><img class="img-responsive center-block" src="<?php echo $feature1; ?>" alt="<?php echo $image1_alt; ?>"></a>

SO网友:Oleksa O.

以下是另一种解决方案:

$image_url = get_field(\'main_image\'); // in case of custom field usage
$image_id = attachment_url_to_postid($image_url);

// retrieve the thumbnail size of our image
$image_thumb = wp_get_attachment_image_src($image_id, \'thumbnail\');
自WP 4.0以来,他们引入了一个函数attachment_url_to_postid() 与您的行为类似find_image_post_id()

请检查this url 供您参考。

SO网友:Oleg Apanovich

自wordpress版本4.0以来,有一个wordpress核心功能attachment_url_to_postid “试图将附件URL转换为帖子ID。”但这些函数存在巨大缺陷,因为它无法转换自定义图像URL大小。

在尝试解决这些问题之前,几乎所有的答案都是最重要的,但所有这些答案都有一个非常繁重的数据库查询,试图获取所有现有的附件,然后遍历所有这些答案,试图获取附件元数据并在其中查找自定义大小。只有在wordpress项目中有少量附件时,它才能正常工作。但如果你有一个有10000多个附件的大项目,你肯定会遇到性能问题。

但您可以通过现有的过滤器attachment\\u url\\u to\\u postid扩展attachment\\u url\\u to\\u postid核心功能,然后尝试强制attachment\\u url\\u to\\u postid功能在自定义图像大小之间搜索。只需将下面的代码添加到函数中。活动wordpress主题的php文件。然后像以前一样使用attachment\\u url\\u to\\u postid函数,但使用其他自定义大小功能。

    add_filter( \'attachment_url_to_postid\', \'change_attachment_url_to_postid\', 10, 2 );
    function change_attachment_url_to_postid( $post_id, $url ) {
        if ( ! $post_id ) {
            $file  = basename( $url );
            $query = array(
                \'post_type\'  => \'attachment\',
                \'fields\'     => \'ids\',
                \'meta_query\' => array(
                    array(
                        \'key\'     => \'_wp_attachment_metadata\',
                        \'value\'   => $file,
                        \'compare\' => \'LIKE\',
                    ),
                )
            );

            $ids = get_posts( $query );

            if ( ! empty( $ids ) ) {

                foreach ( $ids as $id ) {
                    $meta = wp_get_attachment_metadata( $id );

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

        return $post_id;
    }

结束

相关推荐

Similar posts formatting

我正在使用类似的帖子插件http://wordpress.org/extend/plugins/similar-posts/, 我希望类似的帖子显示在同一行,而不是列表。。。如链路1、链路2、链路3、链路4而不是链接1链接2链接3链接4几天前,我在wordpress论坛和插件的官方网站上发布了这篇文章,但仍然没有答案。。。救救我!(我对编码知之甚少,所以请尽量具体,如果你给我代码,请解释每一行的作用,以便我可以学习)谢谢补充信息:我正在使用插件的大部分默认设置,我认为我所做的唯一更改是将其设置为只考虑标签