You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用token_get_all移除PHP中所有以_example结尾的函数

如何用token_get_all移除所有以_example结尾的PHP函数

既然你已经搞定了注释移除和起始标签处理,接下来我们只需要在token遍历过程中加入函数识别、名称判断和完整函数体跳过的逻辑就行。核心思路是跟踪几个状态:是否正在收集函数定义、是否要移除当前函数,以及函数体内大括号的嵌套深度(避免提前结束移除)。

完整实现代码

<?php
// 假设你已经预处理好代码(移除注释、处理起始标签)
$code = file_get_contents('your_source_code.php');
$tokens = token_get_all($code);

$output = '';
$in_remove_function = false;   // 是否处于要移除的函数中
$brace_depth = 0;              // 函数体内大括号的嵌套深度
$collecting_function_ctx = []; // 暂存T_FUNCTION到函数名之间的内容
$waiting_for_function_name = false; // 是否正在等待获取函数名

foreach ($tokens as $token) {
    // 第一步:如果当前正在移除函数,处理大括号深度,直到函数体结束
    if ($in_remove_function) {
        if (!is_array($token)) {
            if ($token === '{') {
                $brace_depth++;
            } elseif ($token === '}') {
                $brace_depth--;
                // 当大括号深度回到0,说明整个函数体结束
                if ($brace_depth === 0) {
                    $in_remove_function = false;
                }
            }
        }
        // 跳过所有属于要移除函数的token
        continue;
    }

    // 第二步:如果正在等待函数名,收集上下文直到找到函数名
    if ($waiting_for_function_name) {
        if (is_array($token)) {
            list($token_id, $content) = $token;
            if ($token_id === T_STRING) {
                // 判断函数名是否以_example结尾
                if (str_ends_with($content, '_example')) {
                    // 标记要移除整个函数,清空缓冲区
                    $in_remove_function = true;
                    $collecting_function_ctx = [];
                } else {
                    // 保留函数,把缓冲区和函数名追加到输出
                    $output .= implode('', $collecting_function_ctx) . $content;
                }
                $waiting_for_function_name = false;
                $collecting_function_ctx = [];
            } else {
                // 收集函数修饰符(比如public、static)、空格等内容
                $collecting_function_ctx[] = $content;
            }
        } else {
            // 收集非数组类型的token(比如空格、&符号等)
            $collecting_function_ctx[] = $token;
        }
        continue;
    }

    // 第三步:正常遍历token,寻找函数定义的起始标记
    if (is_array($token)) {
        list($token_id, $content) = $token;
        if ($token_id === T_FUNCTION) {
            // 遇到函数定义,开始收集上下文,准备判断函数名
            $waiting_for_function_name = true;
            $collecting_function_ctx[] = $content;
        } else {
            // 非函数定义的token,直接追加到输出
            $output .= $content;
        }
    } else {
        // 单个字符的token(比如;、{等),直接追加到输出
        $output .= $token;
    }
}

// 保存处理后的代码
file_put_contents('processed_code.php', $output);
?>

关键逻辑解释

  1. 状态跟踪:
    • $waiting_for_function_name:标记我们刚遇到T_FUNCTION,正在收集函数修饰符、空格等内容,直到找到函数名(T_STRING)。
    • $in_remove_function:一旦确认函数名符合_example结尾的条件,就标记进入移除状态,跳过所有后续token直到函数体结束。
  2. 大括号深度处理:
    函数体内可能有嵌套的大括号(比如if语句、循环),所以用$brace_depth跟踪嵌套层级,只有当深度回到0时,才说明整个函数体完全结束,退出移除状态。
  3. 兼容性处理:
    支持带修饰符的函数(public static function demo_example())、带引用的函数(function &test_example()),因为我们会先收集这些修饰符内容,再判断函数名。

注意事项

  • 如果你用的是PHP 7.x及以下版本,str_ends_with()不可用,替换成substr($content, -8) === '_example'(_example刚好是8个字符)。
  • 确保你已经正确移除了所有注释,否则注释中的内容可能干扰token识别(比如函数名旁边的注释可能被误判为函数名的一部分)。
  • 建议先拿一小段测试代码验证逻辑,比如包含目标函数、普通函数、嵌套大括号的函数,确保移除逻辑准确。

内容的提问来源于stack exchange,提问作者Adam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:34:49