Skip to content

Instantly share code, notes, and snippets.

@davidrenne
Created May 4, 2012 13:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davidrenne/2594907 to your computer and use it in GitHub Desktop.
Save davidrenne/2594907 to your computer and use it in GitHub Desktop.
AutoLoadMinifier
<?php
//It turns out, that it takes more memory and same amount of time to have all your includes in one file. I thought that all the file I/O would be less with one huge compiled include file. This class will combine all your includes into one file.
//it could be useful to try to see all your includes top down. But over all is not meant for production
//Ended up using spl_autoload_register which took all my production includes from 40MB to 10MB and increased speed by 1 to 3 seconds
/*
implementation
include('autoload_minify.php');
$minify = new AutoLoadMinifier('test','$phpVariableThatHasYourBasePath',str_replace(array('//','/'),array('/','\\'),$phpVariableThatHasYourBasePath));
if (!$minify->isProduction)
{
//your normal includes
}
else
{
require($minify->autoLoadFileInclude);
}
$minify->EndListener();
*/
class AutoLoadMinifier
{
private $includesMain;
private $includesOriginal;
public $isProduction;
public $isWindows;
private $thisFile;
private $cwd;
private $folder;
private $autoLoadFilePathName='autoload_main';
public $autoLoadFileInclude;
private $autoLoadFileVersion;
private $autoLoadVersionContents;
private $instanceName;
private $basePath;
private $baseReplace;
private $logs;
/**
* Pass $instanceName for the section in your application
* Pass $basePath which should be a php variable in scope to concatenate your chdir()'s so relative includes will work
* Pass $baseReplace which should be string to be able to replace each path in get_included_files so that the output is a relative path
*
* @param mixed $instanceName
* @param mixed $basePath
* @return AutoLoadMinifier
*/
function __construct($instanceName='',$basePath='',$baseReplace='')
{
$this->logs = array();
$this->instanceName = $instanceName;
$this->basePath = $basePath;
$this->baseReplace = $baseReplace;
$this->isWindows = (stristr(PHP_OS, 'WIN'));
$this->folder = ($this->isWindows) ? "\\" : "/";
$this->isProduction = (!$this->isWindows);
$this->cwd = dirname(__FILE__).$this->folder;
$this->thisFile = basename(__FILE__);
$this->autoLoadFileInclude = $this->cwd.$this->autoLoadFilePathName.".php";
$this->autoLoadFileVersion = $this->cwd.$this->autoLoadFilePathName."_version.php";
if (file_exists($this->autoLoadFileVersion))
{
$this->autoLoadVersionContents = file_get_contents($this->autoLoadFileVersion);
}
$this->StartListener();
}
public function StartListener()
{
$this->includesOriginal = get_included_files();
}
public function EndListener()
{
$this->includesMain = get_included_files();
foreach ($this->includesOriginal as $k=>$v)
{
unset($this->includesMain[$k]);
}
foreach ($this->includesMain as $k=>$v)
{
if (stristr($v,$this->thisFile))
{
unset($this->includesMain[$k]);
}
}
$this->includesMain = array_values($this->includesMain);
if (!$this->isProduction)
{
$fileContents = array();
foreach($this->includesMain as $k=>$php)
{
$i++;
$fileContents[$k] = trim( file_get_contents($php) );
$relativePath = str_replace(array($this->baseReplace,basename($php),'\\'),array('','','/'),$php);
$functionArray = array();
preg_match_all( '/function[\s\n]+(\S+)[\s\n]*\(/' , $fileContents[$k] , $functionArray );
$classArray = array();
preg_match_all( '/class[\s\n]+([a-zA-Z0-9_]+)[\s\na-zA-Z0-9_]+\{/' , $fileContents[$k] , $classArray );
if( count( $classArray )>1 && !empty($classArray[1]) )
{
$funcStart = "\n\nif (!class_exists('".$class."'))\n{\n\n";
$funcEnd = "<?php\n\n}//class_exists '".$class."'\n\n?>";
}
elseif( count( $functionArray ) > 1 && !empty($functionArray[1]) )
{
if (!is_array($functionArray[1]))
{
$func = $functionArray[1];
}
else
{
$func = $functionArray[1][0];
}
$funcStart = "\n\nif (!function_exists('".$func."'))\n{\n\n";
$funcEnd = "<?php\n\n}//func exists '".$func."'\n\n?>";
}
else
{
$funcStart = '';
$funcEnd = '';
}
$relativePaths[] = $relativePath.basename($php)." (".count(explode("\n",$fileContents[$k]))." lines)";
$fileContents[$k] = "<?php\n\n//Minified Include #$i -".basename($php)."\n//\n\nchdir( ".$this->basePath.". '/".$relativePath."');\n\n{$funcStart}?>".$fileContents[$k];
if( substr($fileContents[$k],-2) != '?>')
{
$fileContents[$k] .= "\n\n?>";
$this->logs[] = __CLASS__." - file $php - doesnt have end ?>. Add it.";
}
$fileContents[$k] .= $funcEnd;
$hash .= basename($php)."_".md5($fileContents[$k])."\n";
}
if ($this->autoLoadVersionContents != $hash)
{
file_put_contents($this->autoLoadFileVersion,$hash);
file_put_contents($this->autoLoadFileInclude,"<?php\n\n/*\n\n//Main included files in minify\n\n".implode("\n\n",$relativePaths)."\n\n*/\n\n?>");
file_put_contents($this->autoLoadFileInclude,implode("",$fileContents),FILE_APPEND);
}
}
}
private function DumpLogs()
{
if (!empty($this->logs))
{
error_log(implode('',$this->logs));
}
}
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment