This was just a quick hack to a problem I had, so it is not clean ready-to-use polished software with manuals installers an helpfiles... Anyway I thought it might be useful to someone, and is a good starting point for similar things, so it is here, published for free. Feel free to use it, modify it, trash it... If you do something useful with it, please do let me know, I will be glad to hear it's been useful for something.
This software is distributed as is with no warranties. Use at your own risk.
It has been tested on a linux box with a preinstalled unzip, and on a Windows 98 laptop with the unzip.exe binary that is included in the package, in the same folder of the script. It ran unchanged with the default configuration and without the need of uploading anything else. Let me know if it works or doesn't on other platforms.
Download the m-zip.zip file (at http://esurfers.com/m-zip/). See below under "Installing" for more info.
It may be called an "emulation layer" of the PHP ZIP library. It lets your PHP scripts do almost the same things you would do with the standard ZIP library (opening ZIP files for read access and extracting file contents).
It is not a replacement to the standard library, which is of course faster and more reliable.
So why would you use this? If you can't have the ZIP lib installed onto some server or do not want to rebuild PHP or use dynamic libraries, you now have a chance to read ZIP files. If your big project relies in some minor part to ZIP file uncompressing, you may still install it on a server that does not have the ZIP library installed or available. Just find an appropriate UNZIP tool for your server and upload it with the script.
M-LIB might also be considered a possible extension to the standard ZIP lib. As it only requires a commandline expansion tool, and the script for calling it is completely configurable, you might use it to do on most other kinds of archives the same things you do with the ZIP lib on ZIP files. So alongside with ZIP files, you will also be able to accept TAR, GZIP... etc. Actually, any command that creates a directory tree can be conveniently used with it. There are tools (some are commercial) that uncompress many kinds of files, so you might be able to use this as an archive-kind-independent library.
This library implements all the functions of the ZIP lib (the names are identical except for an m_ in front).
When you call the m_zip_open() function, the library will create a folder somewhere and unzip all the contents of the zipfile.
It will walk the directory structure of the ZIP file as you call m_zip_read() getting into subdirectories and then out again.
Then you will be able to read chunks of (or the whole) files with m_zip_entry_read().
When you have finished, it will get rid of all the unzipped things when you call m_zip_close().
DO NOT FORGET TO CALL m_zip_close()!!!
- Once the zipfile is unzipped, I will have no way to know the original size of the entries or the compression methods, so the functions m_zip_entry_compressedsize() and m_zip_entry_compressionmethod() just return a '?'.
If you really need the original size you might consider reading the ZIP file contents before expansion in the m_zip_open() (for the standard UNZIP tool use the -l option) saving the results and recalling them later. I thought this was too much a work (considering subdirectories and all) and I didn't really need it, so... let me know if you think it is important.
- Of course what zipfiles will be compatible and what not will depend on the command line tool you choose to use. InfoZip code is used in products such as WinZip, so if you use their free unzip tool, compatibility is quite granted. Other tools might be less compatible than the ZIP library, or also "more" compatible, supporting even different kinds of files.
M-LIB has just come out, so history is a bit limited. If you let me know of bugs, I will try to fix them.
- I have appended a long number in front of the directory name where the library will unzip the file, to make this library thread safe (in other words, let two users unzip a file with the SAME NAME together at the same time, with no problems). The number is the current microtime() with some more random appended.
This way two users unzipping the same file will work on different folders.
This means that if you forget to call m_zip_close() or stop for an error before calling m_zip_close() you will leave folders full of data around, even if you always unzip the same file!!!
- I have fixed a bug that prevented the creation of the folder to unzip the file if its name was a full path with slashes. This may seem stupid, but I had only tested it with SampleFile.zip and never with /path/to/SampleFile.zip! Now it does work with both!
You will need an unzip commandline tool for your server platform. Most Unixes have already one preinstalled and a Windows one is included in the package. If you need one you may find it here:
http://www.info-zip.org/pub/infozip/UnZip.html
Supported platforms are more than you would probably need:
Most flavors of Unix / Linux / etc..
Windows 9x / ME / NT / 2000 / XP / etc.
Windows 3.x
Macintosh
It comes preinstalled on Mac OS X
MS-DOS / PC-DOS / DR-DOS / FreeDOS
...and another 14+ Computers/OSs.
If it is not already installed (as I said most of the unix distributions have it), download the prebuilt binary for your server . Putting it in the same directory of your PHP scripts will be ok (just call unzip ... on Windows and ./unzip ... on unix). In another directory (i.e. usr/bin/unzip ...) will be ok too. The unzip.exe for windows is already included in the same directory of the scripts (I hope this does not infringe any licence!)
There are two main parameters you might have to configure. You will find them both at the beginning of the libray file:
- We have to create folders and unzip files, so we will need a space where we can do all these things.
This must be done by changing the UNZIP_DIR parameter
define('UNZIP_DIR','/path/to/folder/where/files/can/be/unzipped/');
Some examples:
// an unzipped folder where your script is
define('UNZIP_DIR','unzipped/');
// inside the temp folder at the root of your HD
define('UNZIP_DIR','/tmp/unzipped/');
Remember to create the folder and to make it writable by the php user!
- We call a commandline tool of the system, so we need to specify what command "unzip/untar/un..." and with what parameters/options
This is done by changing the UNZIP_CMD parameter but most of the times, if you use the unzip tool downloaded at http://www.info-zip.org/ you will not need to change this!
define('UNZIP_CMD','unzip -o @_SRC_@ -x -d @_DST_@');
@_SRC_@ is a placeholder for the name of the zipfile
@_DST_@ is a placeholder for the destination directory
The library will search for these placeholders and insert the correct parameters where needed.
- Download the m-zip.zip file and expand it somewhere on your computer. Rename tha m-zip folder as you like.
- If necessary open m-zip.php and modify the UNZIP_DIR parameter as said above, one folder is already prepared in the package. Make the folder writable by PHP!
- If necessary Download the tool if not installed (the windows tool unxip.exe is already included in the package)
- If necessary change the UNZIP_CMD parameter to point to it (unzip... or ./unzip... or /usr/bin/unzip... etc.) with correct parameters (write @_SRC_@ where the command requires the name of the zip file and @_DST_@ as destination directory)
- Upload to server and test opening the m-zip-test.php file with your preferred browser.
- Modify the m-zip-test.php or paste its code into your existing files.
You may find this document and all m-zip related info at http://esurfers.com/m-zip/
I cannot guarantee real support for this, I must confess I have spent much more time on it than allowed by my job. But if you have doubts or questions on this or anything else, just drop me a quick email and I will try to answer or help. Please also let me know if this document is not clear or correct.
Francesco M. Munafò
Comunication Software Development and Consulting
Via Vittor Pisani 10
20124 - Milano
Italy
eMail: phpDev (A T) esurfers (dot) com
To have my real eMail just replace (A T) with @ and (dot) with .