如何缩小"先验"输出javascript的php文件?

时间:2017-08-13 00:00:52

标签: javascript php minify

我们有一些输出JavaScript代码的PHP文件。我知道事情可能会有所不同,但这是在项目开始时做出的决定。

我们有几个生成Javascript文件的PHP文件,如:

<?php Header("content-type: application/x-javascript");
if(strlen($_GET['country']) != 2){ exit;} //avoids code injection 
include_once($_SERVER['DOCUMENT_ROOT'].'/countries/'.$_GET['country'].'.php');?>

/*Define GLOBAL Javascript variables*/
var COUNTRY = "<?php echo $GLOBALS["country"]; ?>";
/*Language code according to ISO_639-1 codes*/
var LANGUAGE = "<?php echo $lang_CT[$GLOBALS["country"]]; ?>";
...

缩小代码先验的最佳方法是什么,即不是在调用或回显文件时,而是在服务器上使用Javascript缩小规则?

编辑:我一直在思考,事情可能很复杂,我想这个无效的JS代码案例:

var str = <?php echo "'a string';"; ?>

输出有效的JS代码

var str = 'a string';

但基本上我想知道是否有任何基本的缩小选项,删除双空格,注释和分隔线,这样就不会影响生成的JS代码。

2 个答案:

答案 0 :(得分:2)

AFAIK没有支持将此作为PHP的集成功能实现,因为您显然希望缩小PHP实际忽略的代码,因为不会驻留在流程指令<?php?>中。因此,您需要使用其他工具处理PHP代码。如果要用PHP编写,我可能会尝试使用以下代码片段:

$sequence = preg_split( '/(<\?php|<\?=|\?>)/', $phpFileCode, null, PREG_SPLIT_DELIM_CAPTURE );

$isPHP = false;
foreach ( $sequence as &$segment ) {
  switch ( $segment ) {
    case '<?php' :
    case '<?=' :
      $isPHP = true;
      break;
    case '?>' :
      $isPHP = false;
      break;
    default :
      if ( !$isPHP ) {
        $segment = preg_replace( array(
          '#\s*/\*.*?\*/\s*#', // matching multi-line comments
          '#\s*//.*$#m',       // matching single-line comments
          '#\s+#',             // matching arbitrary sequences of whitespace incl. multiple blank lines
        ), array( 
          ' ',
          ' ',
          ' ',
        ) );
      }
  }
}

$phpCodeMinified = implode( '', $sequence );

注意:这段代码只是一个涂鸦...我还没有测试过,但我认为它指的是一些非常简单的方法。

更精细的方法可能

  1. 使用此代码将所有PHP进程指令序列替换为Javascript中的一些特殊全局变量名,而不是检测不属于PHP的段。例如。使用像window.__PHPreplacedXXXX这样的名称,其中XXXX是数组的数字索引,整个替换的PHP段已被推送到下面的步骤3中进行恢复。通过使用全局名称,它们不会在下一步中被破坏。

  2. 使用一些JS minifier(例如uglify或minify之前引用的min minifier)来修改生成的代码。

  3. 处理生成的缩小的JS文件,并恢复以前使用全局名称替换PHP序列。

  4. 这可能会使用更积极的缩小,但是当minifier优化并重新组织代码时,可能会导致JS代码损坏。当坚持使用“简单”的缩放器时,风险并不高。

答案 1 :(得分:0)

这就是我要做的事;使用Heredoc将所有Javascript放在变量中,例如:

$js = <<<EOD
console.log('Valar Morgulis');

console.log('Valar Dohaeris');
EOD;

然后使用Github上可以找到的minify_js()函数here或类似的东西。这是功能:

function minify_js($input) {
if(trim($input) === "") return $input;
return preg_replace(
    array(
        // Remove comment(s)
        '#\s*("(?:[^"\\\]++|\\\.)*+"|\'(?:[^\'\\\\]++|\\\.)*+\')\s*|\s*\/\*(?!\!|@cc_on)(?>[\s\S]*?\*\/)\s*|\s*(?<![\:\=])\/\/.*(?=[\n\r]|$)|^\s*|\s*$#',
        // Remove white-space(s) outside the string and regex
        '#("(?:[^"\\\]++|\\\.)*+"|\'(?:[^\'\\\\]++|\\\.)*+\'|\/\*(?>.*?\*\/)|\/(?!\/)[^\n\r]*?\/(?=[\s.,;]|[gimuy]|$))|\s*([!%&*\(\)\-=+\[\]\{\}|;:,.<>?\/])\s*#s',
        // Remove the last semicolon
        '#;+\}#',
        // Minify object attribute(s) except JSON attribute(s). From `{'foo':'bar'}` to `{foo:'bar'}`
        '#([\{,])([\'])(\d+|[a-z_][a-z0-9_]*)\2(?=\:)#i',
        // --ibid. From `foo['bar']` to `foo.bar`
        '#([a-z0-9_\)\]])\[([\'"])([a-z_][a-z0-9_]*)\2\]#i'
    ),
    array(
        '$1',
        '$1$2',
        '}',
        '$1$3',
        '$1.$3'
    ),
$input);
}

minify_js($js);会让你获得缩小的JS。您可以在Heredoc中使用变量,更多信息here