【问题标题】:Wordpress get attachment of post doesn't workWordpress 获取帖子的附件不起作用
【发布时间】:2026-01-23 08:55:02
【问题描述】:

我正在尝试检索特定帖子的所有附件,但目前无法正常工作。这是代码:

    $args = array(
        'post_type' => 'attachment',
        'posts_per_page' => -1,
        'post_parent' => $id
    );
    $attachments = get_posts($args);

其中 Id 是我的帖子的 ID。我也尝试过 new WP_Query() 但它也没有奏效。两种方式都返回空结果。

有人知道我在这里做错了什么吗?

谢谢

编辑

好的,我想我知道出了什么问题。 将此参数用于 get_posts 函数时,它将返回通过特定帖子中的“添加媒体”按钮上传的图像。

所以基本上,假设在我的第一篇文章中,我已经上传了我未来所有文章所需的所有图片。如果我在第一篇文章中应用请求,我将检索所有图像,甚至是我在这篇文章中未使用的图像。 如果我将此函数应用于另一篇文章,因为我没有在这篇文章中上传任何文件,该函数将检索一个空数组。

有人知道如何检索特定帖子中使用的所有图像吗?所以不仅上传,而且真的集成到帖子中或添加到自定义字段中?

谢谢

【问题讨论】:

    标签: wordpress post attachment


    【解决方案1】:

    使用get_posts获取附件时,需要将post_status设置为inherit。另外,查看get_children 函数:

    $args = array(
        'post_type' => 'attachment',
        'post_mime_type' => 'image',
        'numberposts' => -1,
        'post_status' => 'inherit',
        'post_parent' => $id
    );
    $attachments = get_children( $args );
    

    【讨论】:

    • 嘿,事实上我刚刚看到问题不是我的问题。我在我的第一个 psot 编辑中解释它!
    【解决方案2】:

    案例:使用 ACF,我为我的图库创建了一个重复字段“resort_pics”,其中有 2 个字段“picture_title”作为文本,“picture”作为图片类型。

    然后愉快地上传了 100 张照片,其中一些帖子在几个帖子中是相同的,所以我只点击了上传图库中的那些(我将使用“引用图像”一词来表示那些)。

    问题:然后我发现我们的 api 中缺少所有“引用的图像”。

    原因: 正如“Uriahs Victor”(https://developer.wordpress.org/reference/functions/get_attached_media/) 的文档评论中所述

    需要注意的是,这个函数只返回附件 首次上传/添加到帖子中。上传图片到 Post A(ID 1) 然后将该图像稍后添加到帖子 B(ID 2) 将给出 如果使用了以下代码,则为空数组:

    $media = get_attached_media( 'image', 2 );
    var_dump( $media );
    

    真正原因: 所有这些问题的真正来源是关于“参考图像”的信息没有存储在“wp_posts”表中,但实际上存储在“wp_postmeta”中,所以只需查询“wp_posts”表或使用get_attached_media(),它只在那里查看你也不会得到所有的附件。

    解决方案: 让我们举一个带有 ID 的帖子示例 - $postId 已定义 中继器-“resort_pics”,中继器中带有图像“图片”的字段。 (使用 ACF 插件创建)

    首先以经典方式获取我们帖子(度假村)的所有附件(包括图片/pdf等)(也可以使用'get_attached_media'):

    $images = $wpdb->get_results("select ID,guid from wp_posts where post_parent = " . $postId . " and `post_type`= 'attachment'");
    

    其中 guid 是附件的“url”,让我们在数组中索引那些 key 将是附件的 post id 的索引

    $mapImages = [];
    foreach ($images as $image) {
        $mapImages[$image->ID] = $image->guid;
    }
    

    现在我们拥有所有附件,但缺少所有引用的图像/文件。

    让我们继续为我们的帖子(度假村)选择所有元数据。

    $metas = $wpdb->get_results("select meta_key,meta_value from wp_postmeta where post_id=" . $postId);
    

    并通过元键索引它们

    $mapMetas = [];
    foreach ($metas as $meta) {
        $mapMetas[$meta->meta_key] = $meta->meta_value;
    }
    

    假设我们的帖子 ($postId) 在“resort_pics”中有 9 个条目,其中一张图片已上传到其“图片”字段,那么 $mapMetas['resort_pics'] 的值为 8。 现在中继器字段键存储在 $mapMetas 数组中的方式实际上是:

    'resort_pics_0_picture' -> itsPostId (5640 for example)
    'resort_pics_1_picture' -> itsPostId (5641 for example)
    'resort_pics_2_picture' -> itsPostId (5642 for example)
    ...
    'resort_pics_8_picture' -> itsPostId (5648 for example)
    

    知道了这一点,我们可以简单地获得“resort_pics”的所有图片网址

    for ($i = 0; $i < $mapMetas['resort_pics']; $i++) {
        $picture = [];
        $picture['name'] = $mapMetas['resort_pics_' . $i . '_picture_title'];
        $picture['url'] = $mapImages[$mapMetas['resort_pics_' . $i . '_picture']];
        $pictures[] = $picture;
    }
    

    您可能已经到了这一点,只需从 $mapMetas 获取图像 ID 并使用它从 $mapImages 获取图像 url。

    假设“resort_pics_1_picture”是“引用”的(不是直接上传的图片),我们有它的 id '5641',但由于它没有连接到我们的 $postID,而是连接到实际上传时的其他一些帖子 id。它在我们的 $mapImages 数组中丢失了,所以让我们稍微编辑一下这段代码。

    for ($i = 0; $i < $mapMetas['resort_pics']; $i++) {
        $picture = [];
        $picture['name'] = $mapMetas['resort_pics_' . $i . '_picture_title'];
        $picture['url'] = getAttachmentOrItsReferenceUrl('resort_pics_' . $i . '_picture', $mapImages, $mapMetas);
        $pictures[] = $picture;
    }
    

    我们添加了一个 getAttachementOrItsReferenceUrl() 方法,它会首先检查我们是否已经有这张图片(全部上传到这篇文章),如果没有,则通过它的帖子 id 从 ' wp_posts 的表..

    function getAttachmentOrItsReferenceUrl($code, $allAttachmentById, $allPostMetaByKey) {
        global $wpdb;
        $attachmentUrl = $allAttachmentById[$allPostMetaByKey[$code]];
        if($attachmentUrl === null && isset($allPostMetaByKey[$code]) && $allPostMetaByKey[$code] !== '') {
            $attachments = $wpdb->get_results("select ID,guid from wp_posts where ID = " . $allPostMetaByKey[$code]);
            foreach ($attachments as $image) {
                return $image->guid;
                break;
            }
        } else {
            return $attachmentUrl;
        }
        return "";
    }
    

    最后的想法: 如果您知道您的字段结构,您可以非常简单地构建它的键 举个例子 'rooms' 中继器在 'room_gallery' 中继器内部具有内部 'image' 图像字段。

    'rooms_0_room_gallery_0_image'
    --
    $mapMetas['rooms'] - number of rooms
    $mapMetas['rooms_' . $i . '_room_gallery'] - number of gallery images for room 
    --
    'rooms_' . $i . '_room_gallery_' . $j . '_image'
    

    有多重?并非如此,如果您像我一样,只有少量参考图像,您甚至都不会感觉到。我们添加到加载的只是一个帖子的元查询,如果没有引用图像就是这样,那么对于每个引用的图像还有一个查询,但它对 ID 的查询应该很快。有很多方法可以减少负载,例如,不要查询每个丢失的图像,而是在末尾使用“where in (id1,id2..)”进行单个查询,以获取所有信息,或者在获取新的图像数据后,通过其 id 将其存储在某个全局数组中,并在为下一个帖子获取图像之前检查此数组(因此,如果一个图像存储在 200 个帖子中,并且您正在获取所有图像,则它只会进行 1 个查询) ,你明白了,我把它留在了想法上,因为即使没有这个,这篇文章也太长了:)

    希望这对将来的任何人都有帮助。

    【讨论】:

    • 如果你必须直接这样做的话。使用 wp acf 函数获取数据应该在后台 have_rows('resort_pics') , get_sub_field('picture')