mirror of
https://github.com/vrana/adminer.git
synced 2025-08-06 14:46:36 +02:00
Compile: Use external PhpShrink
This commit is contained in:
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -4,3 +4,6 @@
|
||||
[submodule "JsShrink"]
|
||||
path = externals/JsShrink
|
||||
url = https://github.com/vrana/JsShrink
|
||||
[submodule "PhpShrink"]
|
||||
path = externals/PhpShrink
|
||||
url = https://github.com/vrana/PhpShrink
|
||||
|
@@ -2,8 +2,8 @@
|
||||
<?php
|
||||
include __DIR__ . "/adminer/include/version.inc.php";
|
||||
include __DIR__ . "/adminer/include/errors.inc.php";
|
||||
include __DIR__ . "/php_shrink.inc.php";
|
||||
include __DIR__ . "/externals/JsShrink/jsShrink.php";
|
||||
include __DIR__ . "/externals/PhpShrink/phpShrink.php";
|
||||
|
||||
function add_apo_slashes($s) {
|
||||
return addcslashes($s, "\\'");
|
||||
@@ -354,7 +354,9 @@ $file = preg_replace('~\.\./adminer/static/(default\.css)~', '<?php echo h(' . $
|
||||
$file = preg_replace('~"\.\./adminer/static/(functions\.js)"~', $replace, $file);
|
||||
$file = preg_replace('~\.\./adminer/static/([^\'"]*)~', '" . h(' . $replace . ') . "', $file);
|
||||
$file = preg_replace('~"\.\./externals/jush/modules/(jush\.js)"~', $replace, $file);
|
||||
$file = php_shrink($file);
|
||||
if (function_exists('phpShrink')) {
|
||||
$file = phpShrink($file);
|
||||
}
|
||||
|
||||
$filename = $project . (preg_match('~-dev$~', $VERSION) ? "" : "-$VERSION") . ($driver ? "-$driver" : "") . ($_SESSION["lang"] ? "-$_SESSION[lang]" : "") . ".php";
|
||||
file_put_contents($filename, $file);
|
||||
|
1
externals/PhpShrink
vendored
Submodule
1
externals/PhpShrink
vendored
Submodule
Submodule externals/PhpShrink added at 4e3587239b
@@ -1,142 +0,0 @@
|
||||
<?php
|
||||
|
||||
/** Minify PHP code with these operations:
|
||||
* remove extra {}
|
||||
* minify variables
|
||||
* strip comments, preserve only the first doc-comment
|
||||
* join consecutive echo
|
||||
* change ?>HTML<?php to echo 'HTML' if it saves space
|
||||
* strip public visibility or change it to var
|
||||
*
|
||||
* @param string PHP code including <?php
|
||||
* @return string
|
||||
*/
|
||||
function php_shrink($input) {
|
||||
// based on http://latrine.dgx.cz/jak-zredukovat-php-skripty
|
||||
$input = preg_replace("~<\\?php\\s*\\?>\n?|\\?>\n?<\\?php~", '', $input);
|
||||
$special_variables = array_flip(array('$this', '$GLOBALS', '$_GET', '$_POST', '$_FILES', '$_COOKIE', '$_SESSION', '$_SERVER', '$http_response_header', '$php_errormsg'));
|
||||
$short_variables = array();
|
||||
$shortening = true;
|
||||
$tokens = token_get_all($input);
|
||||
|
||||
// remove unnecessary { }
|
||||
//! change also `while () { if () {;} }` to `while () if () ;` but be careful about `if () { if () { } } else { }
|
||||
$shorten = 0;
|
||||
$opening = -1;
|
||||
foreach ($tokens as $i => $token) {
|
||||
if (in_array($token[0], array(T_IF, T_ELSE, T_ELSEIF, T_WHILE, T_DO, T_FOR, T_FOREACH), true)) {
|
||||
$shorten = ($token[0] == T_FOR ? 4 : 2);
|
||||
$opening = -1;
|
||||
} elseif (in_array($token[0], array(T_SWITCH, T_FUNCTION, T_CLASS, T_CLOSE_TAG), true)) {
|
||||
$shorten = 0;
|
||||
} elseif ($token === ';') {
|
||||
$shorten--;
|
||||
} elseif ($token === '{') {
|
||||
if ($opening < 0) {
|
||||
$opening = $i;
|
||||
} elseif ($shorten > 1) {
|
||||
$shorten = 0;
|
||||
}
|
||||
} elseif ($token === '}' && $opening >= 0 && $shorten == 1) {
|
||||
unset($tokens[$opening]);
|
||||
unset($tokens[$i]);
|
||||
$shorten = 0;
|
||||
$opening = -1;
|
||||
}
|
||||
}
|
||||
$tokens = array_values($tokens);
|
||||
|
||||
foreach ($tokens as $i => $token) {
|
||||
if ($token[0] === T_VARIABLE && !isset($special_variables[$token[1]])) {
|
||||
$short_variables[$token[1]]++;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($tokens as $i => $token) {
|
||||
if (
|
||||
$tokens[$i+2][0] === T_CLOSE_TAG && $tokens[$i+3][0] === T_INLINE_HTML && $tokens[$i+4][0] === T_OPEN_TAG
|
||||
&& strlen(addcslashes($tokens[$i+3][1], "\\'")) < strlen($tokens[$i+3][1]) + 3
|
||||
) {
|
||||
$tokens[$i+2] = array(T_ECHO, 'echo');
|
||||
$tokens[$i+3] = array(T_CONSTANT_ENCAPSED_STRING, "'" . addcslashes($tokens[$i+3][1], "\\'") . "'");
|
||||
$tokens[$i+4] = array(0, ';');
|
||||
}
|
||||
}
|
||||
|
||||
arsort($short_variables);
|
||||
$chars = implode(range('a', 'z')) . '_' . implode(range('A', 'Z'));
|
||||
//! preserve variable names between versions if possible
|
||||
$short_variables2 = array_splice($short_variables, strlen($chars));
|
||||
ksort($short_variables);
|
||||
ksort($short_variables2);
|
||||
$short_variables += $short_variables2;
|
||||
foreach (array_keys($short_variables) as $number => $key) {
|
||||
$short_variables[$key] = short_identifier($number, $chars); // could use also numbers and \x7f-\xff
|
||||
}
|
||||
|
||||
$set = array_flip(preg_split('//', '!"#$%&\'()*+,-./:;<=>?@[]^`{|}'));
|
||||
$space = '';
|
||||
$output = '';
|
||||
$in_echo = false;
|
||||
$doc_comment = false; // include only first /**
|
||||
$next_pos = 0;
|
||||
foreach ($tokens as $i => $token) {
|
||||
if ($i < $next_pos) {
|
||||
continue;
|
||||
}
|
||||
if (!is_array($token)) {
|
||||
$token = array(0, $token);
|
||||
}
|
||||
if ($token[0] == T_COMMENT || $token[0] == T_WHITESPACE || ($token[0] == T_DOC_COMMENT && $doc_comment)) {
|
||||
$space = "\n";
|
||||
} else {
|
||||
if ($token[0] == T_DOC_COMMENT) {
|
||||
$doc_comment = true;
|
||||
}
|
||||
if ($token[0] == T_VAR || $token[0] == T_PUBLIC || $token[0] == T_PROTECTED || $token[0] == T_PRIVATE) {
|
||||
if ($token[0] == T_PUBLIC) {
|
||||
$token[1] = ($tokens[$i+2][1][0] == '$' ? 'var' : '');
|
||||
}
|
||||
$shortening = false;
|
||||
} elseif (!$shortening) {
|
||||
if ($token[1] == ';' || $token[0] == T_FUNCTION) {
|
||||
$shortening = true;
|
||||
}
|
||||
} elseif ($token[0] == T_ECHO) {
|
||||
$in_echo = true;
|
||||
} elseif ($token[1] == ';' && $in_echo) {
|
||||
$next_echo = next_token($tokens, $i, T_ECHO, array(T_WHITESPACE, T_COMMENT));
|
||||
if ($next_echo) {
|
||||
// join two consecutive echos
|
||||
$next_pos = $next_echo + 1;
|
||||
$token[1] = ','; // '.' would conflict with "a".1+2 and would use more memory //! remove ',' and "," but not $var","
|
||||
} else {
|
||||
$in_echo = false;
|
||||
}
|
||||
} elseif ($token[0] === T_VARIABLE && !isset($special_variables[$token[1]])) {
|
||||
$token[1] = '$' . $short_variables[$token[1]];
|
||||
}
|
||||
if (isset($set[substr($output, -1)]) || isset($set[$token[1][0]])) {
|
||||
$space = '';
|
||||
}
|
||||
$output .= $space . $token[1];
|
||||
$space = '';
|
||||
}
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
function next_token($tokens, $i, $search, $allowed = array()) {
|
||||
for ($i += 1; in_array($tokens[$i][0], $allowed); $i++) {
|
||||
}
|
||||
return ($tokens[$i][0] === $search ? $i : 0);
|
||||
}
|
||||
|
||||
function short_identifier($number, $chars) {
|
||||
$return = '';
|
||||
while ($number >= 0) {
|
||||
$return .= $chars[$number % strlen($chars)];
|
||||
$number = floor($number / strlen($chars)) - 1;
|
||||
}
|
||||
return $return;
|
||||
}
|
@@ -1,43 +0,0 @@
|
||||
<?php
|
||||
include __DIR__ . "/../adminer/include/errors.inc.php";
|
||||
include __DIR__ . "/../php_shrink.inc.php";
|
||||
|
||||
function check($code, $expected) {
|
||||
$shrinked = str_replace("\n", " ", php_shrink("<?php\n$code"));
|
||||
if ("<?php $expected" != $shrinked) {
|
||||
$backtrace = reset(debug_backtrace());
|
||||
echo "$backtrace[file]:$backtrace[line]:" . substr($shrinked, 6) . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
//! bugs:
|
||||
check('{if (true) {} echo 1;}', '{if(true);echo 1;}');
|
||||
|
||||
//! inefficiencies
|
||||
check('echo "a"."b",\'c\'."d$a"."e";', 'echo "abcd$a"."e"');
|
||||
|
||||
check('$ab = 1; echo $ab;', '$a=1;echo$a;');
|
||||
check('$ab = 1; $cd = 2;', '$a=1;$b=2;');
|
||||
check('define("AB", 1);', 'define("AB",1);');
|
||||
check('function f($ab, $cd = 1) { return $ab; }', 'function f($a,$b=1){return$a;}');
|
||||
check('class C { var $ab = 1; }', 'class C{var$ab=1;}');
|
||||
check('class C { public $ab = 1; }', 'class C{var$ab=1;}');
|
||||
check('class C { protected $ab = 1; }', 'class C{protected$ab=1;}');
|
||||
check('class C { private $ab = 1; }', 'class C{private$ab=1;}');
|
||||
check('class C { private $ab = 1; }', 'class C{private$ab=1;}');
|
||||
check('class C { private function f($ab) { return $ab; }}', 'class C{private function f($a){return$a;}}');
|
||||
check('class C { public function f($ab) { return $ab; }}', 'class C{function f($a){return$a;}}');
|
||||
check('class C { private static $ab; }', 'class C{private static$ab;}');
|
||||
check('class C { const AB = 1; }', 'class C{const AB=1;}');
|
||||
check('class C { private const AB = 1; }', 'class C{private const AB=1;}');
|
||||
check('class C { public $ab; function f($cd) { return $cd . $this->ab; }}', 'class C{var$ab;function f($b){return$b.$this->ab;}}');
|
||||
check('namespace NS { class C { public $ab = 1; } } new NS\C; $ab = 2;', 'namespace NS{class C{var$ab=1;}}new NS\C;$a=2;');
|
||||
check('new \stdClass;', 'new \stdClass;');
|
||||
check('if (true) { echo "a"; } else { echo "b"; }', 'if(true)echo"a";else echo"b";');
|
||||
check('echo $_GET["a"];', 'echo$_GET["a"];');
|
||||
check('$ab = 1; echo "$ab";', '$a=1;echo"$a";');
|
||||
check('echo 1; echo 3;', 'echo 1,3;');
|
||||
check('echo 1; /**/ echo 2;', 'echo 1,2;');
|
||||
check('echo 1; ?>2<?php echo 3;', "echo 1,'2',3;");
|
||||
check('/** preserve */ $a; /** ignore */ /* also ignore */ // ignore too', '/** preserve */$a;');
|
||||
check('$a = 1; ?><?php ?><?php $a = 2;', '$a=1;$a=2;');
|
Reference in New Issue
Block a user