How to Zip and Unzip Files in PHP

Compressing files when transferring them over the internet has a lot of advantages. In most cases, the combined total size of all the files in the compressed format comes down by a nice margin. This means that you will save some of your bandwidth, and users will also get faster download speeds. Once the users have downloaded a file, they can decompress it whenever they want. In short, compression can make serving files over the internet a lot easier for you as well as your visitors.

One factor that can discourage you from compressing files or make the process very tiresome is the fact that you might be doing it manually. Luckily, PHP comes with a lot of extensions that deal specifically with file compression and extraction. You can use the functions available in these extensions to automatically compress files in PHP.

This tutorial will teach you how to zip and unzip (compress and extract) files to and from a zip archive in PHP. You will also learn how to delete or rename files in an archive without extracting them first.

Compress Individual Files in PHP

The PHP ZipArchive class has a lot of properties and methods which can help you compress and decompress all your files.

You can add files to your zip archive one at a time or add the whole directory at once. In either case, the first step is creating a new ZipArchive instance and then calling the open($filename, [$flags]) method. This method will open a new zip archive for reading, writing, or other modifications. There are five valid values for the optional $flag parameter which determine how to handle different situations.

  • ZipArchive::OVERWRITE—This flag will overwrite the contents in the specified archive if it already exists.
  • ZipArchive::CREATE—This flag will create a new archive if it does not already exist.
  • ZipArchive::EXCL—This flag will result in an error if the archive already exists.
  • ZipArchive::CHECKCONS—This flag will tell PHP to perform additional consistency checks on the archive and give an error if they fail.
  • ZipArchive::RDONLY—This flag became available in PHP 7.4.3 and allows you to open an archive in read only mode.

You can check the documentation of this method to learn about different error codes returned in case of failures to open the file. If the zip file was opened or created successfully, the method will return true.

You will have to use different flag combinations in different situations to avoid any unexpected results. For example, use the ZipArchive::OVERWRITE flag if you don’t care about the content of an existing archive. It will not create a new archive if none exists with that particular name.

You can use a combination of ZipArchive::OVERWRITE and ZipArchive::CREATE in order to overwrite an existing archive and create a new archive if none exists with that particular name. Here is an example:

When using the ZipArchive::CREATE flag, you will notice that it starts modifying an existing archive if one already exists. This might be what you actually want to do but it can also have some unexpected consequences. You can use a combination of ZipArchive::CREATE and ZipArchive::EXCL to make sure that you are only working with archives that did not previously exist.

Once you have opened the archive successfully, you can use the addFile($filename, $localname, $start, $length) method to add any file from a given path to your archive. The $filename parameter is the path of a file that you want to add to the archive. The $localname parameter is used to assign a name to the file to store it inside the archive. You can call addFile() every time you want to add a new file to your archive.

After adding all the necessary files to the archive, you can simply call the close() method to close it and save the changes.

Let’s say you have a website which allows users to download font files for different fonts along with the licensing information to use them. Files like these will be perfect examples of automated archiving using PHP. The following code shows you how to do exactly that.

We begin by creating a ZipArchive instance and then using the open() method to create our archive. The addFile() method adds our actual .ttf font file and the .txt license file to the archive.

You should note that the original files were inside the fonts/Monoton directory. However, the PHP code places it directly inside the root of our archive. You can change the directory structure as well as the names of files going in the archive.

Compressing Multiple Files From a Directory

Adding individual files to your archive can get tiring after a while. For example, you might want to create an archive of all .pdf or .png files in a directory. The addGlob($pattern, $flags, $options) method will prove very helpful in this case. The only disadvantage of this method is that you lose control over the location of individual files in the archive. However, you can still influence the directory structure inside the archive using the $options parameter. The options are passed in the form of an associative array.

  • add_path—The value you assign to add_path is prefixed to the local path of the file within the archive.
  • remove_path—The value you assign to remove_path is used to remove a matching prefix from the path of different files which are added to the archive.
  • remove_all_path—Setting the value of remove_all_path to true will remove everything from the path of the file besides its name. In this case, the files are added to the root of the archive.

It’s important to remember that removal of a path is done before prefixing the value specified in add_path.

The following code snippet will make the use of addGlob() and all these options clearer.

As usual, we begin by creating a ZipArchive instance and then use the open() method to create our archive. We also specify different values for the add_path key in the $options array each time before calling the addGlob() method. This way, we can deal with one specific set of files at a time and provide archiving options accordingly.

In the first case, we iterate over all .jpg files in the lights directory and place them in the light_wallpapers directory in the archive. Similarly, we iterate over all the .ttf files in the documents directory and then put them inside a folder called font_files in our archive. Finally, we iterate over all the .jpg and .png files in our documents at once and put them all together in the images directory.

As you can see, the values in the $options parameter are useful in organizing the content inside the archive.

Modifying or Overwriting Archives

You can combine different flags and options to achieve specific file and directory structure inside the archive. As I mentioned earlier, we can use the open() method to either open a new or existing archive for reading and writing.

In this section, we will learn the difference that can arise due to different combinations of flags passed to the open() method and $options passed to addGlob() method. Lets say there is no archive with the name compressed_files.zip and we run the following code.

It will take all image files from the directory files/images and put them inside the directory wallpapers at the root of the archive. The path of the image files in the archive would be wallpapers/files/images.

You can get rid of the initial path of all images by using the following set of options:

The image files will be stored directly inside wallpapers now and the original image path would be discarded.

As I mentioned earlier, ZipArchive::CREATE will either create a new archive or start modifying an existing archive if it already exists. You won’t get any warnings about an existing archive being modified. This means that if you executed the code in this section to create the archive and then executed it again after replacing the original options with new ones, you will get some unexpected results.

The archive will then contain a wallpapers directory with the sub-directories files/images as well as the images directly inside the wallpapers directory. It can be a bit confusing when first starting out and make you wonder why the $options that you are setting are not being respected.

Always make sure that you use ZipArchive::CREATE|ZipArchive::OVERWRITE if you want to overwrite everything inside an archive if it already exists but don’t want the code to throw errors if it doesn’t.

Also remember that an empty file is no longer considered a valid archive since libzip 1.6.0.

Extracting Content From an Archive

The ZipArchive class has a method called extractTo($destination, $entries) to extract the contents of an archive. You can use it to either extract everything inside the archive or just some specific files. The $entries parameter can be used to specify a single file name which is to be extracted, or you can use it to pass an array of files.

One important point to remember is that you need to specify the proper path of the file inside the archive in order to extract it. For example, we archived a font file called AlegreyaSans-Light.ttf in the previous section. The file was stored within the archive in a directory called font_files. This means that the path you need to specify in the $entries parameter would be font_files/AlegreyaSans-Light.ttf and not simply AlegreyaSans-Light.ttf.

The directory and file structure will be preserved during the extraction process, and files will be extracted in their respective directories.

If you omit the second parameter, the method will extract all files in the archive.

Get More Control Over the Archives

The ZipArchive class also has a lot of other methods and properties to help you get more information about the archive before extracting all its contents.

You can count the number of files in an archive using the count() method. Another option is to use the numFiles property. They can be used to iterate over all the files in the archive and only extract the ones you need—or you can do something else with them, like removing them from the archive.

In the following example, we are deleting all files in the archive which contain the word Italic. Similar code could be used to delete all files which don’t contain a specific word. You could also iterate over these files and replace a particular word with something else.

In the above code, we are using deleteName() to delete an individual file. However, you can also use it to delete an entire directory.

A similar function renameName($oldname, $newname) can be used to change the name of any files in the archive. You will get an error if a file titled $newname already exists.

Final Thoughts

We have covered a bunch of very useful methods of the ZipArchive class which will make automated compression and extraction of files in PHP a breeze. You should now be able to compress individual files or a group of them at once, based on your own criteria. Similarly, you should be able to extract any particular file from the archive without affecting other content.

With the help of count() and numFiles, you will get more control over the individual files, and renaming or deleting them would be super easy. You should go through the documentation at least once to read about more such functions.


This content originally appeared on Envato Tuts+ Tutorials and was authored by Monty Shokeen

Compressing files when transferring them over the internet has a lot of advantages. In most cases, the combined total size of all the files in the compressed format comes down by a nice margin. This means that you will save some of your bandwidth, and users will also get faster download speeds. Once the users have downloaded a file, they can decompress it whenever they want. In short, compression can make serving files over the internet a lot easier for you as well as your visitors.

One factor that can discourage you from compressing files or make the process very tiresome is the fact that you might be doing it manually. Luckily, PHP comes with a lot of extensions that deal specifically with file compression and extraction. You can use the functions available in these extensions to automatically compress files in PHP.

This tutorial will teach you how to zip and unzip (compress and extract) files to and from a zip archive in PHP. You will also learn how to delete or rename files in an archive without extracting them first.

Compress Individual Files in PHP

The PHP ZipArchive class has a lot of properties and methods which can help you compress and decompress all your files.

You can add files to your zip archive one at a time or add the whole directory at once. In either case, the first step is creating a new ZipArchive instance and then calling the open($filename, [$flags]) method. This method will open a new zip archive for reading, writing, or other modifications. There are five valid values for the optional $flag parameter which determine how to handle different situations.

  • ZipArchive::OVERWRITE—This flag will overwrite the contents in the specified archive if it already exists.
  • ZipArchive::CREATE—This flag will create a new archive if it does not already exist.
  • ZipArchive::EXCL—This flag will result in an error if the archive already exists.
  • ZipArchive::CHECKCONS—This flag will tell PHP to perform additional consistency checks on the archive and give an error if they fail.
  • ZipArchive::RDONLY—This flag became available in PHP 7.4.3 and allows you to open an archive in read only mode.

You can check the documentation of this method to learn about different error codes returned in case of failures to open the file. If the zip file was opened or created successfully, the method will return true.

You will have to use different flag combinations in different situations to avoid any unexpected results. For example, use the ZipArchive::OVERWRITE flag if you don't care about the content of an existing archive. It will not create a new archive if none exists with that particular name.

You can use a combination of ZipArchive::OVERWRITE and ZipArchive::CREATE in order to overwrite an existing archive and create a new archive if none exists with that particular name. Here is an example:

When using the ZipArchive::CREATE flag, you will notice that it starts modifying an existing archive if one already exists. This might be what you actually want to do but it can also have some unexpected consequences. You can use a combination of ZipArchive::CREATE and ZipArchive::EXCL to make sure that you are only working with archives that did not previously exist.

Once you have opened the archive successfully, you can use the addFile($filename, $localname, $start, $length) method to add any file from a given path to your archive. The $filename parameter is the path of a file that you want to add to the archive. The $localname parameter is used to assign a name to the file to store it inside the archive. You can call addFile() every time you want to add a new file to your archive.

After adding all the necessary files to the archive, you can simply call the close() method to close it and save the changes.

Let's say you have a website which allows users to download font files for different fonts along with the licensing information to use them. Files like these will be perfect examples of automated archiving using PHP. The following code shows you how to do exactly that.

We begin by creating a ZipArchive instance and then using the open() method to create our archive. The addFile() method adds our actual .ttf font file and the .txt license file to the archive.

You should note that the original files were inside the fonts/Monoton directory. However, the PHP code places it directly inside the root of our archive. You can change the directory structure as well as the names of files going in the archive.

Compressing Multiple Files From a Directory

Adding individual files to your archive can get tiring after a while. For example, you might want to create an archive of all .pdf or .png files in a directory. The addGlob($pattern, $flags, $options) method will prove very helpful in this case. The only disadvantage of this method is that you lose control over the location of individual files in the archive. However, you can still influence the directory structure inside the archive using the $options parameter. The options are passed in the form of an associative array.

  • add_path—The value you assign to add_path is prefixed to the local path of the file within the archive.
  • remove_path—The value you assign to remove_path is used to remove a matching prefix from the path of different files which are added to the archive.
  • remove_all_path—Setting the value of remove_all_path to true will remove everything from the path of the file besides its name. In this case, the files are added to the root of the archive.

It's important to remember that removal of a path is done before prefixing the value specified in add_path.

The following code snippet will make the use of addGlob() and all these options clearer.

As usual, we begin by creating a ZipArchive instance and then use the open() method to create our archive. We also specify different values for the add_path key in the $options array each time before calling the addGlob() method. This way, we can deal with one specific set of files at a time and provide archiving options accordingly.

In the first case, we iterate over all .jpg files in the lights directory and place them in the light_wallpapers directory in the archive. Similarly, we iterate over all the .ttf files in the documents directory and then put them inside a folder called font_files in our archive. Finally, we iterate over all the .jpg and .png files in our documents at once and put them all together in the images directory.

As you can see, the values in the $options parameter are useful in organizing the content inside the archive.

Modifying or Overwriting Archives

You can combine different flags and options to achieve specific file and directory structure inside the archive. As I mentioned earlier, we can use the open() method to either open a new or existing archive for reading and writing.

In this section, we will learn the difference that can arise due to different combinations of flags passed to the open() method and $options passed to addGlob() method. Lets say there is no archive with the name compressed_files.zip and we run the following code.

It will take all image files from the directory files/images and put them inside the directory wallpapers at the root of the archive. The path of the image files in the archive would be wallpapers/files/images.

You can get rid of the initial path of all images by using the following set of options:

The image files will be stored directly inside wallpapers now and the original image path would be discarded.

As I mentioned earlier, ZipArchive::CREATE will either create a new archive or start modifying an existing archive if it already exists. You won't get any warnings about an existing archive being modified. This means that if you executed the code in this section to create the archive and then executed it again after replacing the original options with new ones, you will get some unexpected results.

The archive will then contain a wallpapers directory with the sub-directories files/images as well as the images directly inside the wallpapers directory. It can be a bit confusing when first starting out and make you wonder why the $options that you are setting are not being respected.

Always make sure that you use ZipArchive::CREATE|ZipArchive::OVERWRITE if you want to overwrite everything inside an archive if it already exists but don't want the code to throw errors if it doesn't.

Also remember that an empty file is no longer considered a valid archive since libzip 1.6.0.

Extracting Content From an Archive

The ZipArchive class has a method called extractTo($destination, $entries) to extract the contents of an archive. You can use it to either extract everything inside the archive or just some specific files. The $entries parameter can be used to specify a single file name which is to be extracted, or you can use it to pass an array of files.

One important point to remember is that you need to specify the proper path of the file inside the archive in order to extract it. For example, we archived a font file called AlegreyaSans-Light.ttf in the previous section. The file was stored within the archive in a directory called font_files. This means that the path you need to specify in the $entries parameter would be font_files/AlegreyaSans-Light.ttf and not simply AlegreyaSans-Light.ttf.

The directory and file structure will be preserved during the extraction process, and files will be extracted in their respective directories.

If you omit the second parameter, the method will extract all files in the archive.

Get More Control Over the Archives

The ZipArchive class also has a lot of other methods and properties to help you get more information about the archive before extracting all its contents.

You can count the number of files in an archive using the count() method. Another option is to use the numFiles property. They can be used to iterate over all the files in the archive and only extract the ones you need—or you can do something else with them, like removing them from the archive.

In the following example, we are deleting all files in the archive which contain the word Italic. Similar code could be used to delete all files which don't contain a specific word. You could also iterate over these files and replace a particular word with something else.

In the above code, we are using deleteName() to delete an individual file. However, you can also use it to delete an entire directory.

A similar function renameName($oldname, $newname) can be used to change the name of any files in the archive. You will get an error if a file titled $newname already exists.

Final Thoughts

We have covered a bunch of very useful methods of the ZipArchive class which will make automated compression and extraction of files in PHP a breeze. You should now be able to compress individual files or a group of them at once, based on your own criteria. Similarly, you should be able to extract any particular file from the archive without affecting other content.

With the help of count() and numFiles, you will get more control over the individual files, and renaming or deleting them would be super easy. You should go through the documentation at least once to read about more such functions.


This content originally appeared on Envato Tuts+ Tutorials and was authored by Monty Shokeen


Print Share Comment Cite Upload Translate Updates
APA

Monty Shokeen | Sciencx (2018-10-07T11:36:06+00:00) How to Zip and Unzip Files in PHP. Retrieved from https://www.scien.cx/2018/10/07/how-to-zip-and-unzip-files-in-php/

MLA
" » How to Zip and Unzip Files in PHP." Monty Shokeen | Sciencx - Sunday October 7, 2018, https://www.scien.cx/2018/10/07/how-to-zip-and-unzip-files-in-php/
HARVARD
Monty Shokeen | Sciencx Sunday October 7, 2018 » How to Zip and Unzip Files in PHP., viewed ,<https://www.scien.cx/2018/10/07/how-to-zip-and-unzip-files-in-php/>
VANCOUVER
Monty Shokeen | Sciencx - » How to Zip and Unzip Files in PHP. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2018/10/07/how-to-zip-and-unzip-files-in-php/
CHICAGO
" » How to Zip and Unzip Files in PHP." Monty Shokeen | Sciencx - Accessed . https://www.scien.cx/2018/10/07/how-to-zip-and-unzip-files-in-php/
IEEE
" » How to Zip and Unzip Files in PHP." Monty Shokeen | Sciencx [Online]. Available: https://www.scien.cx/2018/10/07/how-to-zip-and-unzip-files-in-php/. [Accessed: ]
rf:citation
» How to Zip and Unzip Files in PHP | Monty Shokeen | Sciencx | https://www.scien.cx/2018/10/07/how-to-zip-and-unzip-files-in-php/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.