Php 将大型函数重构为多个文件

Php 将大型函数重构为多个文件,php,xml,refactoring,include,Php,Xml,Refactoring,Include,我一直在尝试重构我以前开发的一些代码。基本上,这个项目是我对不知道如何有效使用XSLT的回应,所以我用PHP开发了一个XML转换系统。程序读取XML文件的标记,并按照以下方式将其转换为HTML: private function getTemplate(...) { switch ($nodeName) { case "a" : // code here to generate a link tag break;

我一直在尝试重构我以前开发的一些代码。基本上,这个项目是我对不知道如何有效使用XSLT的回应,所以我用PHP开发了一个XML转换系统。程序读取XML文件的标记,并按照以下方式将其转换为HTML:

private function getTemplate(...) {
    switch ($nodeName) {
        case "a" :
            // code here to generate a link tag
            break;
        case "box" :
            // code here to generate the divs and whatnot to create a box
            break;
        case "ref" :
            // look up an external reference file and include a bibliography
            break;
        default :
            // do the default thing
    }
}
这一切都很好,除了我的交换机有26个分支,而且曾经的交换机块有1000多行代码。不用说,这使得维护稍微困难一些

我现在所做的是将每个分支的代码拉到它自己的名为a.php、box.php、ref.php的文件中。。。并且每次都包括该文件:

if (file_exists("templates/$nodeName.php")) {
    include "templates/$nodeName.php";
} else {
    // do the default thing
}
同样,这是可行的,但基准测试表明它将处理时间降低了50%。我假设这是因为现在有多达4000个包含正在进行

我考虑的是将每个模板的代码放入一个函数中,如果函数尚未声明,则包含该文件,然后运行该函数-唯一的问题是,现有代码已在原始函数的范围内编写,使用$this,等等


考虑到这段代码不是实时运行的,例如:它只是将XML处理成静态HTML文件并存储起来——这不是即时完成的,您有什么建议吗?

警告:我不懂PHP,但我可以而且我更喜欢函数指针而不是巨大的开关语句,所以如果您不能只使用XSLT

…一种选择是为包含html节点标记名的“worker”函数采用命名约定,例如_converter,包括所有函数,并用以下内容替换switch语句:

private function getTemplate(...) 
{
    $func = $nodeName + "_converter";
    if (function_exists($func))    //see if function is defined, somehow...
    {
        $func();    //call conversion function (pass whatever is needed)
    }
}

警告:我不懂PHP,但我可以而且我更喜欢函数指针,而不是大型开关语句,所以如果您不能只使用XSLT

…一种选择是为包含html节点标记名的“worker”函数采用命名约定,例如_converter,包括所有函数,并用以下内容替换switch语句:

private function getTemplate(...) 
{
    $func = $nodeName + "_converter";
    if (function_exists($func))    //see if function is defined, somehow...
    {
        $func();    //call conversion function (pass whatever is needed)
    }
}

试着这样做:

//utils.php function handle_box($node) { //... } function handle_link($node) { //.... } ?\> 然后:


基本上,这会将每个节点的所有功能重构为自己的功能。从这里你可以得到一个更普遍的解决方案。它与您最初使用的非常相似,但是switch/case语句在没有大量代码的情况下将更易于管理。然后,如果您觉得有必要,可以考虑潜在地实施。

尝试以下方法:

//utils.php function handle_box($node) { //... } function handle_link($node) { //.... } ?\> 然后:


基本上,这会将每个节点的所有功能重构为自己的功能。从这里你可以得到一个更普遍的解决方案。它与您最初使用的非常相似,但是switch/case语句在没有大量代码的情况下将更易于管理。然后,如果您觉得有必要,您可以考虑潜在地实现。

而不必深入XSLT本身并关注重构问题:您已经考虑了大量不同的策略。我将提供一个优化技巧,介绍您已经尝试过的一种方法,以及另一种可能适合您的方法

当您说依赖多个文件时,性能会下降50%。我认为您没有启用PHP操作代码缓存。你这么做了,那50%的损失应该消失了

在另一种方法中,我建议创建一个基类NodeProcessor左右。然后为每个节点创建一个新类ANodeProcessor、RefNodeProcessor等等

或者,您只能创建一个类NodeProcessor,其中包含:processTag形式的方法。然后:

您可以调用$this->processNode$tag; 该方法中的一个参数:$name='process'$标签 然后:返回$this->nodeProcessor->{$name}; NodeProcessor应该有一个_调用方法来为没有定义processTag方法的标记执行默认操作。
同样,不要忘了添加操作码缓存。

不必深入XSLT本身并关注重构问题:您已经考虑了大量不同的策略。我将提供一个优化技巧,介绍您已经尝试过的一种方法,以及另一种可能适合您的方法

当您说依赖多个文件时,性能会下降50%。我认为您没有启用PHP操作代码缓存。你这么做了,那50%的损失应该消失了

在另一种方法中,我建议创建一个基类NodeProcessor左右。然后为每个节点创建一个新类ANodeProcessor、RefNodeProcessor等等

或者,您只能创建一个类NodeProcessor,其中包含:processTag形式的方法。然后:

您可以调用$this->processNode$tag; 该方法中的一个参数:$name='process'$标签 然后:返回$this->nodeProcessor->{$name}; 节点处理器应该有一个_调用方法来执行de 未定义processTag方法的标记的错误。
同样,不要忘了添加操作码缓存。

我认为这就是他的原始代码,或者更糟的话。对你来说幸运的是,我还差9分投了反对票;不,我实际上只是将我的原始代码剪切粘贴到外部文件中——根本没有对其进行任何更改。例如:将每个代码包装成一个函数如果这是他的原始代码,将26个case语句转换成1000行将是非常惊人的……我想这就是他的原始代码,或者更糟的话。对你来说幸运的是,我还差9分投了反对票;不,我实际上只是将我的原始代码剪切粘贴到外部文件中-根本没有对其进行任何更改例如:将每个代码包装成一个函数如果这是他的原始代码,将26个case语句转换为1000行将是非常惊人的。。。