包含vs eval for php framework

时间:2014-10-11 20:53:47

标签: php

我一直计划与一组开发人员一起编写一个小型PHP框架供内部使用,其中一个开发人员遇到了一些问题,我们正试图在我们的几个现有框架中解决这些问题。

在某些框架中,类名(控制器或模型)必须与文件名匹配。开发人员认为这是额外的开发开销,我们一直在想办法解决这个问题。

另一方面,如果我们没有文件名及其包含的类名的规则,那么人们可以包含a.php等包含UserController类的文件,其他开发人员必须打开每个文件以确定哪个类包含在哪个文件中。

这个特定的开发人员建议我们使用语义文件名创建文件(比如cart.php,这将包含没有类包装器的代码。

例如(取自PHP.net),而不是

<?php
class Cart {
    var $items;  // Items in our shopping cart

    // Add $num articles of $artnr to the cart

    function add_item($artnr, $num) {
        $this->items[$artnr] += $num;
    }

    // Take $num articles of $artnr out of the cart

    function remove_item($artnr, $num) {
        if ($this->items[$artnr] > $num) {
            $this->items[$artnr] -= $num;
            return true;
        } elseif ($this->items[$artnr] == $num) {
            unset($this->items[$artnr]);
            return true;
        } else {
            return false;
        }
    }
}
?>
我们写

    var $items;  // Items in our shopping cart

    // Add $num articles of $artnr to the cart

    function add_item($artnr, $num) {
        $this->items[$artnr] += $num;
    }

    // Take $num articles of $artnr out of the cart

    function remove_item($artnr, $num) {
        if ($this->items[$artnr] > $num) {
            $this->items[$artnr] -= $num;
            return true;
        } elseif ($this->items[$artnr] == $num) {
            unset($this->items[$artnr]);
            return true;
        } else {
            return false;
        }
    }

然后我们读取该文件,比如使用file_get_contents,添加并附加所需的代码以使其成为正确的类(与文件名同名),然后eval代替只包括完整的文件(包括课程)。

除此之外可能会出现什么问题

  1. 整个方法都是无意义的。
  2. 代码执行速度较慢。
  3. 更新

    请不要以各种形式提出上述两个理由。我们意识到这种方法是无意义和缓慢的。

    此外,我们还希望了解直接include() vs eval()参数。除了以上两个原因以及易于使用和更容易的项目/系统管理的原因之外,为什么要使用include()而不是eval()?

1 个答案:

答案 0 :(得分:4)

&#34;问题&#34;你试图解决通常被认为是一件好事:如果代码必须存在于某处的文件中,那么你需要一个这样的文件的命名约定来组织项目;并且由于您还需要命名空间和类的命名约定,因此将两个实际的保存工作对齐,因为您不需要跟踪这两种约定。

PHP还包含一个功能,以autoloading的形式为此提供更强大的优势。这允许你编写一个函数,当你提到一个尚未定义的类时,它将被调用该类名;通过将文件名与类名对齐,它可以找到并加载该类。随着项目的增长,这非常有用,因为这意味着您永远不需要将requireinclude添加到文件中,或者计算出代码的特定区域所需的确切依赖关系树。主要框架已经在标准化的目录布局上进行了合作,以利用这一点,称为PSR-4

虽然创建大量目录和单独文件可能很烦人,并且很容易将许多小类放入一个文件中,但这并不能很好地扩展,如果其中一个小类后来增长,那么你和#39;很遗憾没有自己的文件,有自己的版本历史等等。

如果您在文件所包含的课程后没有为文件命名,则需要手动管理一组复杂的require / include行,跟踪正确的顺序以定义所有内容,或者具有自动加载器功能,其中包含将类名称映射到文件名的长列表。要么听起来像很多工作对我没有好处。

如果您的文件将在课程之后命名,那么自动加载器仍然有效,但您唯一获得的是您不需要在文件顶部。另一方面,您需要创建一个相当不寻常的函数来包含这些文件,涉及class Cart的使用效率相当低。像OpCache和HHVM这样的事情会发现缓存和优化以这种方式加载的代码要困难得多,并且任何执行静态分析的工具都将完全失败,因为文件中的代码无效(例如PHPCodeSniffer报告编码标准,PHPDocumentor,或任何提供函数列表和语法分析功能的编辑器或IDE。)

最后,通常会注意到代码读取更频繁。对于绝大多数类而言,您正在保存的步骤只发生一次 - 首次创建类时。重命名或复制类通常是非常罕见的,如果您重命名大量文件,制作脚本以自动执行任务相当容易。另一方面,您正在介绍一些使您阅读代码变得更难的事情。除了混淆静态分析(以及自动化文档)之外,您还必须向从事该项目的新开发人员解释这种特殊方案,从而有效地提高您的培训成本。还有一个问题是,一旦扩展到单个目录之外,您将不得不查看文件的完整目录路径以查看它实际定义的类;我经常最终打开几个同名的文件(例如eval()),而且我(和我的编辑)可以查看文件顶部的完整类声明,这对于跟踪哪个文件是必不可少的。是哪个。