How can I unzip a .gz file with PHP?
Asked Answered
Z

6

15

I'm using CodeIgniter and I can't figure out how to unzip files!

Zelazny answered 20/7, 2010 at 18:30 Comment(1)
A .gz file is different from a .zip file, even if normally a utility that is able to uncompress .zip files is also able to uncompress .gz files.Atmosphere
C
1

Download the Unzip library and include or autoload the unzip library

$this->load->library('unzip');
Cheadle answered 20/7, 2010 at 18:32 Comment(1)
Links are dead.. let me find the links if I can and update thisLinctus
C
55

PHP itself has a number of functions for dealing with gzip files.

If you want to create a new, uncompressed file, it would be something like this.

Note: This doesn't check if the target file exists first, doesn't delete the input file, or do any error checking. You really should fix those before using this in production code.

// This input should be from somewhere else, hard-coded in this example
$file_name = 'file.txt.gz';

// Raising this value may increase performance
$buffer_size = 4096; // read 4kb at a time
$out_file_name = str_replace('.gz', '', $file_name);

// Open our files (in binary mode)
$file = gzopen($file_name, 'rb');
$out_file = fopen($out_file_name, 'wb');

// Keep repeating until the end of the input file
while(!gzeof($file)) {
    // Read buffer-size bytes
    // Both fwrite and gzread and binary-safe
    fwrite($out_file, gzread($file, $buffer_size));
}

// Files are done, close files
fclose($out_file);
gzclose($file);

Note: This deals with gzip only. It doesn't deal with tar.

Craft answered 20/7, 2010 at 18:45 Comment(2)
I used this code and it work perfects . just asking how to make it works with folders inside gz file and how to show output folder of extracted files .Auditory
@RealMan gzip only supports single files. You need a .tar.gz for multiple files. I'm not sure if PHP has built-in support for tar or not.Craft
I
12

gzopen is way too much work. This is more intuitive:

$zipped = file_get_contents("foo.gz");
$unzipped = gzdecode($zipped);

works on http pages when the server is spitting out gzipped data also.

Illassorted answered 21/11, 2019 at 13:9 Comment(4)
This is not a good idea, as it reads the entire file into memory. Using gzopen and using a buffer is the proper way to do this.Mandate
Using gzopen would only be "better" with a huge file. We're not programming on VIC 20s or PHP 11s anymore. "proper" depends on the the application. The point of using PHP is so that we dont have to write complicated C-like code to do simple things.Illassorted
A buffer is a common data structure used in high-level programming languages, not just C. PHP has file handles that need to be closed and memory to be stewarded. Protecting users from out of memory errors is important, and it's important for programmers to know these things.Mandate
so someone wasted their time implementing gzdecode() according to you? Should no-one use json_decode or str_getcsv because the string may be too large for your liking? WHY does file_get_contents even exist if we can't use it because the file may be too large to read into memory? You're trying to be a smart guy by recognizing the 1 in a million case where the simple code may not work. Good programmers code for the 99.99% case. I can always shell to gzip for the one in million case where the file is enormousIllassorted
U
6

If you have access to system():

system("gunzip file.sql.gz");
Unexceptional answered 24/11, 2013 at 20:0 Comment(1)
Should work but most of time system() will be disabled due to security reasonsLinctus
A
3

Use the functions implemented by the Zlib Compression extension.

This snippet shows how to use some of the functions made available from the extension:

// open file for reading
$zp = gzopen($filename, "r");

// read 3 char
echo gzread($zp, 3);

// output until end of the file and close it.
gzpassthru($zp);
gzclose($zp);
Atmosphere answered 20/7, 2010 at 18:36 Comment(0)
C
1

Download the Unzip library and include or autoload the unzip library

$this->load->library('unzip');
Cheadle answered 20/7, 2010 at 18:32 Comment(1)
Links are dead.. let me find the links if I can and update thisLinctus
P
1

Complementing @Danial's answer...

$zipped = file_get_contents("foo.xlsx.gz");
$unzipped = gzdecode($zipped);
file_put_contents("foo.xlsx", $unzipped);

I agree, to use it on files with a few tens of MB is ok, I imagine this is the most frequent use, but when we reach hundreds of MB it is better to use a solution with gzopen() and gzread().

Furthermore, it is possible to have the 2 solutions together 🚀 just check the size of the gz file. If it is smaller than 70MB, for example, use file_get_contents(), if it is larger, use gzopen().

if (filesize("foo.xlsx.gz") <= (1024*1024*70)) {
  // file_get_contents() approach...
} else {
  // gzopen() approach...
}

Yes, I know that what matters most is the actual size of the decompressed file, but we can get a good idea since generally the compressed file is 30% smaller than the original file.

One line tip... to compress a file:

file_put_contents('output.gz', gzencode( file_get_contents('input.file'), 9));
Petiole answered 8/4 at 16:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.