PHP Packer

PHP Packer é uma classe em PHP5 desenvolvida para minimizar códigos PHP, removendo comentários e espaços. Essa classe é o início de um sistema free para proteção de códigos PHP.

Download
PHP Packer v0.1.

Código normal

<?php
/**
 * Classe para minimizar códigos PHP
 *
 * @version 0.1
 * @author Tarcísio Xavier Gruppi <tarcisio@txgruppi.com>
 * @link http://blog.txgruppi.com/php-packer
 */
class Packer {
	/**
	 * Guarda o caminho para o arquivo alvo
	 *
	 * @var string
	 */
	protected $file;

	/**
	 * Guarda o código fonte do arquivo alvo
	 *
	 * @var string
	 */
	protected $source;

	/**
	 * Guarda os tokens to arquivo alvo
	 *
	 * @var array
	 */
	protected $tokens;

	/**
	 * Guarda os tokens após a limpesa
	 *
	 * @var string
	 */
	protected $parsedTokens = array();

	/**
	 * Método construtor, recebe como parâmetro o caminho para o arquivo alvo
	 *
	 * @param string $file
	 */
	public function __construct($file) {
		$this->file = $file;
		$this->loadContent();
		$this->getTokens();
		$this->parseTokens();
	}

	/**
	 * Retorna o código fonte minimizado
	 *
	 * @return string
	 */
	public function getSource() {
		if (empty($this->parsedTokens)) return false;

		$out = "";
		foreach ($this->parsedTokens as $t) {
			if (is_array($t)) {
				$out .= $t[1];
			} else {
				$out .= $t;
			}
		}
		return trim($out);
	}

	/**
	 * Limpa o código fonte
	 *
	 */
	protected function parseTokens() {
		$newTokens = array();
		foreach ($this->tokens as $k=>$t) {
			if (is_array($t)) {
				$token = $t[0];
			} else {
				$token = ';';
			}

			if ($token == T_WHITESPACE) {
				if (isset($this->tokens[$k-1])) {
					if (is_array($this->tokens[$k-1])) {
						if ($this->tokens[$k-1][0] == T_IF) continue;
						if ($this->tokens[$k-1][0] == T_FOREACH) continue;
						if ($this->tokens[$k-1][0] == T_CONCAT_EQUAL) continue;
						if ($this->tokens[$k-1][0] == T_IS_EQUAL) continue;
						if ($this->tokens[$k-1][0] == T_BOOLEAN_AND) continue;
						if ($this->tokens[$k-1][0] == T_BOOLEAN_OR) continue;
					} else {
						if ($this->tokens[$k-1] == ';') continue;
						if ($this->tokens[$k-1] == '{') continue;
						if ($this->tokens[$k-1] == '}') continue;
						if ($this->tokens[$k-1] == '(') continue;
						if ($this->tokens[$k-1] == ')') continue;
						if ($this->tokens[$k-1] == '=') continue;
						if ($this->tokens[$k-1] == ',') continue;
					}
				}
				if (isset($this->tokens[$k+1])) {
					if (is_array($this->tokens[$k+1])) {
						if ($this->tokens[$k+1][0] == T_CONCAT_EQUAL) continue;
						if ($this->tokens[$k+1][0] == T_IS_EQUAL) continue;
						if ($this->tokens[$k+1][0] == T_BOOLEAN_AND) continue;
						if ($this->tokens[$k+1][0] == T_BOOLEAN_OR) continue;
					} else {
						if ($this->tokens[$k+1] == '=') continue;
						if ($this->tokens[$k+1] == '{') continue;
						if ($this->tokens[$k+1] == '(') continue;
						if ($this->tokens[$k+1] == ',') continue;
					}
				}
				if (isset($this->tokens[$k-3])) {
					if (is_array($this->tokens[$k-3])) {
						if ($this->tokens[$k-3][0] == T_CLASS) continue;
					}
				}
			}
			if (!isset($this->tokens[$k+1])) {
				if (is_array($t) && $t[0] == T_CLOSE_TAG) continue;
			}
			$newTokens[] = $t;
		}
		$this->parsedTokens = $newTokens;
	}

	/**
	 * Separa os tokens do código fonte
	 *
	 */
	protected function getTokens() {
		$this->tokens = token_get_all($this->source);
	}

	/**
	 * Carrega o conteúdo do arquivo alvo e já remove os comentários
	 *
	 */
	protected function loadContent() {
		if (empty($this->file)) return;
		if (!file_exists($this->file)) return;
		if (!is_readable($this->file)) return;

		$this->source = php_strip_whitespace($this->file);
		$this->source = preg_replace("'^([^\s]+)\s+'","$1 ",$this->source);
		$this->source = trim($this->source);
	}
}

header("Content-Type: text/plain");
$packer = new Packer(__FILE__);
echo $packer->getSource();

Código minimizado

<?php class Packer{protected $file;protected $source;protected $tokens;protected $parsedTokens=array();public function __construct($file){$this->file=$file;$this->loadContent();$this->getTokens();$this->parseTokens();}public function getSource(){if(empty($this->parsedTokens))return false;$out="";foreach($this->parsedTokens as $t){if(is_array($t)){$out.=$t[1];}else{$out.=$t;}}return trim($out);}protected function parseTokens(){$newTokens=array();foreach($this->tokens as $k=>$t){if(is_array($t)){$token=$t[0];}else{$token=';';}if($token==T_WHITESPACE){if(isset($this->tokens[$k-1])){if(is_array($this->tokens[$k-1])){if($this->tokens[$k-1][0]==T_IF)continue;if($this->tokens[$k-1][0]==T_FOREACH)continue;if($this->tokens[$k-1][0]==T_CONCAT_EQUAL)continue;if($this->tokens[$k-1][0]==T_IS_EQUAL)continue;if($this->tokens[$k-1][0]==T_BOOLEAN_AND)continue;if($this->tokens[$k-1][0]==T_BOOLEAN_OR)continue;}else{if($this->tokens[$k-1]==';')continue;if($this->tokens[$k-1]=='{')continue;if($this->tokens[$k-1]=='}')continue;if($this->tokens[$k-1]=='(')continue;if($this->tokens[$k-1]==')')continue;if($this->tokens[$k-1]=='=')continue;if($this->tokens[$k-1]==',')continue;}}if(isset($this->tokens[$k+1])){if(is_array($this->tokens[$k+1])){if($this->tokens[$k+1][0]==T_CONCAT_EQUAL)continue;if($this->tokens[$k+1][0]==T_IS_EQUAL)continue;if($this->tokens[$k+1][0]==T_BOOLEAN_AND)continue;if($this->tokens[$k+1][0]==T_BOOLEAN_OR)continue;}else{if($this->tokens[$k+1]=='=')continue;if($this->tokens[$k+1]=='{')continue;if($this->tokens[$k+1]=='(')continue;if($this->tokens[$k+1]==',')continue;}}if(isset($this->tokens[$k-3])){if(is_array($this->tokens[$k-3])){if($this->tokens[$k-3][0]==T_CLASS)continue;}}}if(!isset($this->tokens[$k+1])){if(is_array($t)&&$t[0]==T_CLOSE_TAG)continue;}$newTokens[]=$t;}$this->parsedTokens=$newTokens;}protected function getTokens(){$this->tokens=token_get_all($this->source);}protected function loadContent(){if(empty($this->file))return;if(!file_exists($this->file))return;if(!is_readable($this->file))return;$this->source=php_strip_whitespace($this->file);$this->source=preg_replace("'^([^\s]+)\s+'","$1 ",$this->source);$this->source=trim($this->source);}}header("Content-Type: text/plain");$packer=new Packer(__FILE__);echo $packer->getSource();