从几个 .php 文件中解包/合并 PHP 代码
Unwrap / amalgamate PHP code from several .php files
出于调试目的,在处理包含许多文件/许多 include
的 PHP 项目时(例如:Wordpress 代码),有时我会对查看“展开的”代码感兴趣,并且合并/展平(“展平”是类似 Photoshop 的工具中使用的术语,当您将多个图层合并为一个图层时)所有文件合并到一个大 PHP 文件中。
如何合并多个PHP文件?
示例:
$ php index.php --amalgamation
将这些文件作为输入:
vars.php
<?php
$color = 'green';
$fruit = 'apple';
?>
index.php
<?php
include 'vars.php';
echo "A $color $fruit";
?>
并生成此合并输出:
<?php
$color = 'green';
$fruit = 'apple';
echo "A $color $fruit";
?>
(它应该也适用于许多文件,例如,如果 index.php
包含 vars.php
,而 vars.php
本身包含 abc.php
)。
我们可以编写一个 amalgamation/bundling 脚本来获取给定文件的内容并匹配 include|require
的任何实例,然后获取任何引用文件的内容,并替换 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 引用替换为实际代码。该函数还包括一个注释行,指示包含文件的源,这可能会派上用场if/when你正在调试编译的捆绑文件。
Notes/Homework:
- 您可能需要完善基目录引用例程。 (预计依赖 PHP include_path 的“不完整”文件路径会遇到麻烦。)
- 没有控制
_once
,代码会重新收录。 (通过记录包含的文件路径和跳过重复项很容易补救。)
- 仅在
"path/file.php"
上进行匹配,即。 single/double 引号内的完整字符串。连接的字符串不匹配。
- 不理解包含变量或常量的路径。必须对文件进行评估,没有副作用!,才能做到这一点。
- 如果您使用
declare(strict_types=1);
,请将其置于顶部并消除以下实例。
- 此处未提及的文件捆绑可能会产生其他副作用。
- 正则表达式没有 lookbehind/around 来查看您的 include/require 是否被注释掉了!
- 如果您的代码跳进跳出 PHP 模式并脱口而出 HTML,所有赌注都将取消
- 管理自动加载的内容 类 超出了此代码段的范围。
请报告任何故障和边缘情况。随意开发和(自由)分享。
出于调试目的,在处理包含许多文件/许多 include
的 PHP 项目时(例如:Wordpress 代码),有时我会对查看“展开的”代码感兴趣,并且合并/展平(“展平”是类似 Photoshop 的工具中使用的术语,当您将多个图层合并为一个图层时)所有文件合并到一个大 PHP 文件中。
如何合并多个PHP文件?
示例:
$ php index.php --amalgamation
将这些文件作为输入:
vars.php
<?php $color = 'green'; $fruit = 'apple'; ?>
index.php
<?php include 'vars.php'; echo "A $color $fruit"; ?>
并生成此合并输出:
<?php
$color = 'green';
$fruit = 'apple';
echo "A $color $fruit";
?>
(它应该也适用于许多文件,例如,如果 index.php
包含 vars.php
,而 vars.php
本身包含 abc.php
)。
我们可以编写一个 amalgamation/bundling 脚本来获取给定文件的内容并匹配 include|require
的任何实例,然后获取任何引用文件的内容,并替换 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 引用替换为实际代码。该函数还包括一个注释行,指示包含文件的源,这可能会派上用场if/when你正在调试编译的捆绑文件。
Notes/Homework:
- 您可能需要完善基目录引用例程。 (预计依赖 PHP include_path 的“不完整”文件路径会遇到麻烦。)
- 没有控制
_once
,代码会重新收录。 (通过记录包含的文件路径和跳过重复项很容易补救。) - 仅在
"path/file.php"
上进行匹配,即。 single/double 引号内的完整字符串。连接的字符串不匹配。 - 不理解包含变量或常量的路径。必须对文件进行评估,没有副作用!,才能做到这一点。
- 如果您使用
declare(strict_types=1);
,请将其置于顶部并消除以下实例。 - 此处未提及的文件捆绑可能会产生其他副作用。
- 正则表达式没有 lookbehind/around 来查看您的 include/require 是否被注释掉了!
- 如果您的代码跳进跳出 PHP 模式并脱口而出 HTML,所有赌注都将取消
- 管理自动加载的内容 类 超出了此代码段的范围。
请报告任何故障和边缘情况。随意开发和(自由)分享。