This is a PHP script that creates the equivalent of a self-extracting ZIP file--but instead of being an .exe, the self-extracting file is a .php.
I tested it with about 1-10 megs of files, and it takes about 1 second per meg to extract. Also, since there is some base64 encoding, the file size is on average about 1.5x the size of an equivalent ZIP file.
I had envisioned this being useful to create foolproof PHP script installations. I was just wondering what anyone thought. Feel free to use it in your own projects, however, I'd like to know where, just out of curiousity.
The script relies on some config variables below the copyright/GPL notice. Set these and give it a whirl!
PHP Code:
<?
/*
Copyright 2003 Kyle Maxwell
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
//Change these values
$path_to_pack = "relative/path/to/folder"; // No trailing slash
$redirect_page = "index.php"; // URL to go to after unpacking
$self_destruct = true; // Delete archive after unpacked?
$output_file = "packed.php" // Name of archive;
$text_file_types = array(
"txt",
"html",
"php",
"htm"
); // File extensions to treat as ascii (not binary)
$recurse_subdirectories = true; //Get files in subfolders
//No need to edit below this
@ob_implicit_flush(true);
function is_binary($filename){
global $text_file_types;
$temp = explode(".", $filename);
$extension = array_pop($temp);
$temp = array_flip($text_file_types);
return !array_key_exists($extension, $temp);
}
function recurse_dir($dir){
global $recurse_subdirectories, $path_to_pack;
if (is_dir($dir)) {
if ($dh = opendir($dir)) {
while (($file = readdir($dh)) !== false) {
if ($file == "." || $file == ".." ) {
//Do nothing
} elseif (is_dir($dir."/".$file)) {
if($recurse_subdirectories)
$a = array_merge($a, recurse_dir($dir."/".$file));
} else{
$filename = substr($dir ."/". $file, strlen($path_to_pack)+1);
if(is_binary($filename)){
$b = "rb";
}else{
$b = "r";
}
echo("Packing $filename ... <br>" );
$fh = fopen($dir ."/". $file, $b)
or die("Unable to open ".$dir ."/". $file);
$a[$filename] = fread($fh, filesize ($dir ."/". $file))
or die("Unable to read $b ".$dir ."/". $file);
fclose($fh);
}
}
closedir($dh);
} else {
die("Unable to open directory" );
}
} else {
die("Not a directory" );
}
return $a;
}
$br = '
';
$file_array = recurse_dir($path_to_pack);
$file_array["!ascii"] = $file_text_types;
$file_array["!redirect"] = $redirect_page;
$file_array["!selfdestruct"] = $self_destruct;
$fh = fopen($output_file, "w" );
$out = base64_encode(serialize($file_array));
$b = '<?php'.$br;
$b.= '$s = \'';
$b.= $out;
$b.= '\';'."$br";
$this_file = implode("", file($HTTP_SERVER_VARS["PHP_SELF"]));
$temp = explode("/* The code inside of the packed file", $this_file);
$b.= $temp[2];
$b.= "?" . ">";
fwrite($fh, $b, strlen($b));
fclose($fh);
/*
The commented section below is actually most of the code inserted in the
unpacking file for the unpacking algorithm. It's easier to put it here
in comments than to do a bunch of fwrites or create a buffer or something.
*/
/* The code inside of the packed file
@ob_implicit_flush(true);
$br = '
';
function is_binary($filename){
global $text_file_types;
$temp = explode(".", $filename);
$extension = array_pop($temp);
$temp = array_flip($text_file_types);
return !array_key_exists($extension, $temp);
}
$file_array = unserialize(base64_decode($s));
$text_file_types = $file_array["!ascii"];
foreach(array_keys($file_array) as $key){
if(substr($key, 0, 1) != "!" ){
$temp = explode("/", $key);
array_pop($temp);
$tempnew = array();
while($temp != array()){
$tempnew[] = array_shift($temp);
if(!is_dir(implode("/", $tempnew))) mkdir(implode("/", $tempnew));
}
echo("Unpacking $key ... <br>" );
if(!is_binary($key)){
$temp = $file_array[$key];
$temp = str_replace("\r\n", "\n", $temp);
$temp = str_replace("\r", "\n", $temp);
$file_array[$key] = str_replace("\n", $br, $temp);
$fh = fopen($key, "w" );
fwrite($fh, $file_array[$key]);
fclose($fh);
} else {
$fh = fopen($key, "wb" );
fwrite($fh, $file_array[$key]);
fclose($fh);
}
}
}
if($file_array["!selfdestruct"]) unlink($HTTP_SERVER_VARS["SCRIPT_NAME"]);
if($file_array["!redirect"] == "" ){
die("Unpacking complete" );
} else {
echo("<meta http-equiv=refresh content="1; url=".$file_array["!redirect"].">" );
die("<script>location.replace('".$file_array["!redirect"]."');</script>" );
}
/* The code inside of the packed file */
?>
Packing complete.
Bookmarks