我们可以编写一个合并/捆绑脚本,它获取给定文件的内容并匹配 的任何实例include|require
,然后获取任何引用文件的内容,并用实际代码替换 include/require 调用。
以下是一个基本实现(基于对具有嵌套引用的文件进行的非常有限的测试),它适用于包含/需要其他文件的任意数量的文件。
<?php
// Main file that references further files:
$start = 'test/test.php';
function bundle_files(string $filepath)
{
// Fetch current code
$code = file_get_contents($filepath);
// Set directory for referred files
$dirname = pathinfo($filepath, PATHINFO_DIRNAME);
// Match and substitute include/require(_once) with code:
$rx = '~((include|require)(_once)?)\s+[\'"](?<path>[^\'"]+)[\'"];~';
$code = preg_replace_callback($rx, function($m) use ($dirname) {
// Ensure a valid filepath or abort:
if($path = realpath($dirname . '/' . $m['path'])) {
return bundle_files($path);
} else {
die("Filepath Read Fail: {$dirname}/{$m['path']}");
}
}, $code);
// Remove opening PHP tags, note source filepath
$code = preg_replace('~^\s*<\?php\s*~i', "\n// ==== Source: {$filepath} ====\n\n", $code);
// Remove closing PHP tags, if any
$code = preg_replace('~\?>\s*$~', '', $code);
return $code;
}
$bundle = '<?php ' . "\n" . bundle_files($start);
file_put_contents('bundle.php', $bundle);
echo $bundle;
在这里,我们使用preg_replace_callback()
按出现顺序匹配和替换,回调在每个匹配的文件路径上调用捆绑函数,并用实际代码替换 include/require 引用。该函数还包括一个注释行,指示包含文件的来源,如果/当您调试编译的捆绑文件时,它可能会派上用场。
笔记/作业:
- 您可能需要改进基本目录引用例程。(预计依赖于 PHP include_path 的“不完整”文件路径会出现问题。)
- 没有控制
_once
,代码将被重新包含。(通过记录包含的文件路径和跳过重复来轻松补救。)
- 匹配仅在 上进行
"path/file.php"
,即。单/双引号内的完整字符串。连接的字符串不匹配。
- 不理解包括变量或常量的路径。必须在没有副作用的情况下评估文件!才能做到这一点。
- 如果您使用
declare(strict_types=1);
,请将其放在顶部并消除以下实例。
- 捆绑文件可能还有其他副作用,此处未提及。
- 正则表达式不会向后/查看您的 include/require 是否被注释掉!
- 如果你的代码跳进跳出 PHP 模式并脱口而出 HTML,所有的赌注都没有了
- 管理包含自动加载的类超出了此代码段。
请报告任何故障和边缘情况。随意开发和(自由)分享。