wp_delete_attachment( int $post_id, bool $force_delete = false )

Trash or delete an attachment.


Description Description

When an attachment is permanently deleted, the file will also be removed. Deletion removes all post meta fields, taxonomy, comments, etc. associated with the attachment (except the main post).

The attachment is moved to the Trash instead of permanently deleted unless Trash for media is disabled, item is already in the Trash, or $force_delete is true.


Top ↑

Parameters Parameters

$post_id

(int) (Required) Attachment ID.

$force_delete

(bool) (Optional) Whether to bypass Trash and force deletion.

Default value: false


Top ↑

Return Return

(WP_Post|false|null) Post data on success, false or null on failure.


Top ↑

Source Source

File: wp-includes/post.php

function wp_delete_attachment( $post_id, $force_delete = false ) {
	global $wpdb;

	$post = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE ID = %d", $post_id ) );

	if ( ! $post ) {
		return $post;
	}

	$post = get_post( $post );

	if ( 'attachment' !== $post->post_type ) {
		return false;
	}

	if ( ! $force_delete && EMPTY_TRASH_DAYS && MEDIA_TRASH && 'trash' !== $post->post_status ) {
		return wp_trash_post( $post_id );
	}

	/**
	 * Filters whether an attachment deletion should take place.
	 *
	 * @since 5.5.0
	 *
	 * @param bool|null $delete       Whether to go forward with deletion.
	 * @param WP_Post   $post         Post object.
	 * @param bool      $force_delete Whether to bypass the Trash.
	 */
	$check = apply_filters( 'pre_delete_attachment', null, $post, $force_delete );
	if ( null !== $check ) {
		return $check;
	}

	delete_post_meta( $post_id, '_wp_trash_meta_status' );
	delete_post_meta( $post_id, '_wp_trash_meta_time' );

	$meta         = wp_get_attachment_metadata( $post_id );
	$backup_sizes = get_post_meta( $post->ID, '_wp_attachment_backup_sizes', true );
	$file         = get_attached_file( $post_id );

	if ( is_multisite() ) {
		clean_dirsize_cache( $file );
	}

	/**
	 * Fires before an attachment is deleted, at the start of wp_delete_attachment().
	 *
	 * @since 2.0.0
	 * @since 5.5.0 Added the `$post` parameter.
	 *
	 * @param int     $post_id Attachment ID.
	 * @param WP_Post $post    Post object.
	 */
	do_action( 'delete_attachment', $post_id, $post );

	wp_delete_object_term_relationships( $post_id, array( 'category', 'post_tag' ) );
	wp_delete_object_term_relationships( $post_id, get_object_taxonomies( $post->post_type ) );

	// Delete all for any posts.
	delete_metadata( 'post', null, '_thumbnail_id', $post_id, true );

	wp_defer_comment_counting( true );

	$comment_ids = $wpdb->get_col( $wpdb->prepare( "SELECT comment_ID FROM $wpdb->comments WHERE comment_post_ID = %d", $post_id ) );
	foreach ( $comment_ids as $comment_id ) {
		wp_delete_comment( $comment_id, true );
	}

	wp_defer_comment_counting( false );

	$post_meta_ids = $wpdb->get_col( $wpdb->prepare( "SELECT meta_id FROM $wpdb->postmeta WHERE post_id = %d ", $post_id ) );
	foreach ( $post_meta_ids as $mid ) {
		delete_metadata_by_mid( 'post', $mid );
	}

	/** This action is documented in wp-includes/post.php */
	do_action( 'delete_post', $post_id, $post );
	$result = $wpdb->delete( $wpdb->posts, array( 'ID' => $post_id ) );
	if ( ! $result ) {
		return false;
	}
	/** This action is documented in wp-includes/post.php */
	do_action( 'deleted_post', $post_id, $post );

	wp_delete_attachment_files( $post_id, $meta, $backup_sizes, $file );

	clean_post_cache( $post );

	return $post;
}


Top ↑

Changelog Changelog

Changelog
Version Description
2.0.0 Introduced.

Top ↑

User Contributed Notes User Contributed Notes

  1. Skip to note 2 content
    Contributed by strompf

    This function does approximately the same as if you would go the Media Library and trash or delete an attachment and cleanly remove the associations from posts (or other objects) to which they were associated, and subsequently remove the files from the files system (if case you choose to delete the attachment, rather than trashing it):

    • This function has nothing to do with how attachments (like images) are actually used on a site
    • When using $force_delete = false, the attachment gets moved to Trash, eventhough by default, there is no button at the media library to access Trash – This can be confusing
    • When using $force_delete = false, the attachment files (the actual files under wp-content/uploads) are kept as they are
    • When using $force_delete = true, the attachment files (the actual files under wp-content/uploads) are removed
    • Concerning the line at the top in this documentation “(except the main post)”: I’m still not sure what it means. I suspect that it means that e.g., when you remove the image for a WooCommerce product, that the image gets removed, along with all its metadata, but not the WooCommerce product itself
    • It seems that when you remove an attachment that is a thumbnail for a WooCommerce product, that an existing gallery image takes it place – Quite neat, when you are aware of this.

    Example (1) – Trash one attachment:

    <?php
    /**
     * Test wp_delete_attachment()
     *
     * Move attachment (image) to trash
     * It will still reside at wp-content/uploads
     */
    
    wp_delete_attachment( 39019 );
    

    Example (2) – Delete multiple attachments:

    <?php
    /**
     * Test wp_delete_attachment()
     *
     * Both thumbnail & all three gallery images
     * Sidepass trash - Directly delete, and remove files from file system
     */
    
    wp_delete_attachment( 54858, true );
    wp_delete_attachment( 54859, true );
    wp_delete_attachment( 54860, true );
    wp_delete_attachment( 54861, true );
    
  2. Skip to note 3 content
    Contributed by Codex

    To delete an attachment with an ID of ’76’:

    <?php wp_delete_attachment( 76 ); ?>
    
    

You must log in before being able to contribute a note or feedback.