I found myself in in the situation that I had to use PHPExcel to generate some graphs. Sounds easy enough, and it kind of is, but... after I develop locally on my machine running php 5.3 I face myself with the challenge that I have to install the code on a machine running php 5.1.2 (not suported by PHPExcel). I soon found out that the main problem is the fact that php 5.1 dose not have ZipArchive or PHPExcel_Shared_ZipArchive, you can install them but with a lot of headache and a lot of trying (more than 1 solutions available for more than 1 case) and to be honest, that solution was not the proper way to do it as this was a production server with a lot of stuff on it (you don't want to mess it up).
Maybe a guru server admin could find a proper solution, but I am not that, I am a dev, so... I started researching to find a way to change to another lib that works on 5.1. And so I found... nothing!!! (at least after 2-3h of research and reading a lot of useless forum posts).
As my search was not fruitful and time consuming and annoying I moved my atention to something I love but not like doing: hacking the code ( hacking the code of a maintained lib is not encouraged as this may lead to rough upgrades with lots of diffs etc. ).
After a little more research and documentation I found pclzip as a php standalone lib here and I found that PHPExcel has a very simple way of changing the ziping class in the settings.
So this is what I have done:
- imported the pclzip lib
- created a wrapper class for compatibility reasons (pclzip dose not have the function names implemented in the other to libs)
- added my wrapper class as a ziping method in settings.php
- forced PHPExcel to use my class for ziping
NOTICE: This was tested only for writing, so I have no ideea what will happen when reading, but that is the subject of another post.
Here is a short description of the code I created:
################################################
// pclzip.extended.php
################################################
include('pclzip.lib.php'); // PhpConcept Library - Zip Module 2.8.2 - http://www.phpconcept.net
class PCLZipExtended{
// just a place holder
function PCLZipExtended(){
}
private $zip;
private $temp_dir;
// implementation of function open
// this function needs to create the zip file
// pclzip dose not create the file untill any action is taken (create/append)
function open($pFilename,$zipCreate){
$this->zip = new PclZip($pFilename);
$this->zip->create(array());
return file_exists($pFilename);
}
// implementation of addFromString function
// needs to save the string to a local file and then append it to the archive
// keeping the paths is a ***ch
function addFromString($_location,$data){
$location=$this->tempdir().$_location;
if(!file_exists(dirname($location)))
mkdir(dirname($location), 0777, true);
file_put_contents($location,$data);
$loc_to_add = explode('/',$location);
array_shift ($loc_to_add);
array_pop ($loc_to_add);
$loc_to_add = implode('/',$loc_to_add);
$this->zip->add($location,$loc_to_add,dirname($location));
}
// we are done and we can clean up after our selfs
function close(){
// do cleanup
$this->rrmdir($this->tempdir());
}
// generate a temp dir to store the files needed for the zip
// or if we already done this return it
// and yes php 5.1 dose not have sys_get_temp_dir
private function tempdir($dir='') {
if(isset($temp_dir)) return $temp_dir;
$tempfile=tempnam($dir,'');
if (file_exists($tempfile)) { unlink($tempfile); }
mkdir($tempfile);
if (is_dir($tempfile)) { return $temp_dir=$tempfile.'/'; }
return false;
}
// recursive delete for php
private function rrmdir($dir='') {
if (is_dir($dir)) {
$objects = scandir($dir);
foreach ($objects as $object) {
if ($object != "." && $object != "..") {
if (filetype($dir."/".$object) == "dir") rmdir($dir."/".$object); else unlink($dir."/".$object);
}
}
reset($objects);
rmdir($dir);
}
}
}
################################################
// PHPExcel: PHPExcel/PHPExcel/Settings.php
################################################
################
const PCLZIP = 'PHPExcel_Shared_ZipArchive';
// line: 42 added just this
const PCLZIP_SOURCE = 'PCLZipExtended';
// line: 42 added just this
const ZIPARCHIVE = 'ZipArchive';
################
if (($zipClass === self::PCLZIP) ||
// line: 120 added just this
($zipClass === self::PCLZIP_SOURCE) ||
// line: 120 added just this
($zipClass === self::ZIPARCHIVE)) {
################
################################################
// Main php file that dose all the work
################################################
include('modules/ER_Reports/pclzip.extended.php');
include('modules/ER_Reports/PHPExcel/PHPExcel.php');
PHPExcel_Settings::setZipClass(PHPExcel_Settings::PCLZIP_SOURCE);
$er = new ER_Reports();
And that's all folks!!!!