编译模块

建立一个功能类 CompileClass,这里的「编译」指的是进行相关的文本替换输出新的脚本文件,而非生成二进制文件。

基本功能

  1. 显示普通变量
  2. 支持普通变量的默认值
  3. 导入其他文件

简单实现

显示语法替换
  • 将文本中的 {$xx} 替换为 <?php $this->printValueWithKey("xx"); ?>
  • 将文本中的 {$xx!123} 替换为 <?php $this->printValueWithKey("xx", "123"); ?>
  • printValueWithKey 方法中,当 xx 变量不存在时,会显示默认值 123
1
2
3
4
5
6
7
$valid_var_reg = sprintf('[.a-zA-z_%c-%c][.a-zA-z0-9_%c-%c]*', 0x7f, 0xff, 0x7f, 0xff);

$this->T_P[] = sprintf('#\{\$(%s)\}#', $valid_var_reg);
$this->T_R[] = '<?php $this->printValueWithKey("\1"); ?>';

$this->T_P[] = sprintf('#\{\$(%s)!\'([^\']*)\'\}#', $valid_var_reg);
$this->T_R[] = '<?php $this->printValueWithKey("\1", "\2"); ?>';
import 处理

这里定义的 import 功能与 PHP 原生的 include 相似,导入的文件为 PHP 模板文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public function referLinkForChild()
{
$referLink = $this->referLink;
array_push($referLink, $this->templateFile);
return $referLink;
}

/**
* 预处理,递归处理 import 标签
*/
public function preCompile()
{
// 避免循环引用文件
foreach($this->referLink as $refer)
{
if($refer == $this->templateFile)
{
return '';
}
}

$reg = '#\{import\s+\'([^\']+)\'\}#';
$config = $this->config;
$referLink = $this->referLinkForChild();
$this->content = preg_replace_callback($reg, function ($matches) use ($config, $referLink) {
$templateFile = sprintf('%s/template/%s', __DIR__, $matches[1]);
$compileTool = new CompileClass($templateFile, $config, $referLink);
$content = $compileTool->preCompile();
return $content;
}, $this->content);

return $this->content;
}
输出文件

处理过后的文本为一个可执行的 PHP 脚本文件,输出到本地。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public function compile()
{
$content = $this->preCompile();
$this->content = preg_replace($this->T_P, $this->T_R, $content);
return $this->content;
}

public function saveToDisk($compileFile)
{
$dir = dirname($compileFile);
if(!is_dir($dir))
{
mkdir($dir, 0755, TRUE);
}

file_put_contents($compileFile, $this->content);
}