unzip_file()WP 2.5.0

Unzips the specified ZIP archive to a folder on the server using the WordPress filesystem API.

It is assumed that the function WP_Filesystem() has already been called and configured.

Does not extract the folder __MACOSX, if it exists in the archive.

Attempts to increase the memory limit to 256M before starting the extraction, although the amount of RAM should not be significantly larger than the size of the unzipped archive.

The functionality is based on the filesystem API, which is based on the base class WP_Filesystem_Base. This is extended by a class suitable for the specific server. The resulting object is located in the global variable $wp_filesystem.

Read about Filesystem_API

To use the function outside of the admin area, you need to include the file:

require_once ABSPATH . 'wp-admin/includes/file.php';

Possible methods of the variable $wp_filesystem, see in the class:

And in one of its derivatives:

Hooks from the function

Returns

true|WP_Error. WP_Error in case of error, or True in case of success.

Usage

unzip_file( $file, $to );
$file(string) (required)
The full path to the archive
$to(string) (required)
The full path to the folder where the archive will be unzipped. Here you need to specify the path through the WordPress filesystem API.

Examples

1

#1 Basic example

Showing how to unzip the contents of a .zip file, that resides in the WordPress upload directory, to the same destination.

WP_Filesystem();
$destination = wp_upload_dir();
$destination_path = $destination['path'];
$unzipfile = unzip_file( "{$destination_path}/filename.zip", $destination_path );

if ( $unzipfile ) {
	echo 'Successfully unzipped the file!';       
}
else {
	echo 'There was an error unzipping the file.';       
}
0

#2 Example of unzipping an archive with unzip_file()

Although this function requires initialization of the file system API, it is not a method of the $wp_filesystem object, so it must be passed parameters with $wp_filesystem in mind.

The first parameter, $file, must be the absolute path to the file (on the server), and the parameter $to must point to the absolute path of the WordPress file system.

// even in the admin panel, check if the function is defined
if ( ! function_exists( 'unzip_file' ) ) {
	require_once ABSPATH . 'wp-admin/includes/file.php';
}

// and the global variable must contain an object
global $wp_filesystem;
if ( ! $wp_filesystem ) {
	// but if it does not, this function corrects the situation
	WP_Filesystem();
}
define( 'MY_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );

// this variable must already have been set when initializing the file system
global $wp_filesystem;

// remote path to the file system
$plugin_path = str_replace( ABSPATH, $wp_filesystem->abspath(), MY_PLUGIN_DIR );

// the RIGHT way to use the function
$file = MY_PLUGIN_DIR . '/plugin-file.zip';
$to   = $plugin_path;

$result = unzip_file( $file, $to );

if( $result === true ){
	// OK: the archive is unpacked
}

// the wrong way to use the function
// $to cannot be a direct path to the folder, otherwise the FTP and SSH methods remain inoperable
$file = MY_PLUGIN_DIR . '/plugin-file.zip';
$to   = MY_PLUGIN_DIR;

unzip_file( $file, $to );

// the wrong way to use the function
// If $file is not a "direct" absolute path,
// then users who do not use FTP and SSH methods are left out
$file = $plugin_path . '/plugin-file.zip';
$to   = $plugin_path;

unzip_file( $file, $to );

Notes

  • Global. WP_Filesystem_Base. $wp_filesystem WordPress filesystem subclass.

Changelog

Since 2.5.0 Introduced.

unzip_file() code WP 6.8.3

function unzip_file( $file, $to ) {
	global $wp_filesystem;

	if ( ! $wp_filesystem || ! is_object( $wp_filesystem ) ) {
		return new WP_Error( 'fs_unavailable', __( 'Could not access filesystem.' ) );
	}

	// Unzip can use a lot of memory, but not this much hopefully.
	wp_raise_memory_limit( 'admin' );

	$needed_dirs = array();
	$to          = trailingslashit( $to );

	// Determine any parent directories needed (of the upgrade directory).
	if ( ! $wp_filesystem->is_dir( $to ) ) { // Only do parents if no children exist.
		$path = preg_split( '![/\\\]!', untrailingslashit( $to ) );
		for ( $i = count( $path ); $i >= 0; $i-- ) {
			if ( empty( $path[ $i ] ) ) {
				continue;
			}

			$dir = implode( '/', array_slice( $path, 0, $i + 1 ) );
			if ( preg_match( '!^[a-z]:$!i', $dir ) ) { // Skip it if it looks like a Windows Drive letter.
				continue;
			}

			if ( ! $wp_filesystem->is_dir( $dir ) ) {
				$needed_dirs[] = $dir;
			} else {
				break; // A folder exists, therefore we don't need to check the levels below this.
			}
		}
	}

	/**
	 * Filters whether to use ZipArchive to unzip archives.
	 *
	 * @since 3.0.0
	 *
	 * @param bool $ziparchive Whether to use ZipArchive. Default true.
	 */
	if ( class_exists( 'ZipArchive', false ) && apply_filters( 'unzip_file_use_ziparchive', true ) ) {
		$result = _unzip_file_ziparchive( $file, $to, $needed_dirs );
		if ( true === $result ) {
			return $result;
		} elseif ( is_wp_error( $result ) ) {
			if ( 'incompatible_archive' !== $result->get_error_code() ) {
				return $result;
			}
		}
	}
	// Fall through to PclZip if ZipArchive is not available, or encountered an error opening the file.
	return _unzip_file_pclzip( $file, $to, $needed_dirs );
}