我一直计划与一组开发人员一起编写一个小型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
代替只包括完整的文件(包括课程)。
除此之外可能会出现什么问题::
更新
请不要以各种形式提出上述两个理由。我们意识到这种方法是无意义和缓慢的。
此外,我们还希望了解直接include()
vs eval()
参数。除了以上两个原因以及易于使用和更容易的项目/系统管理的原因之外,为什么要使用include()
而不是eval()?
答案 0 :(得分:4)
&#34;问题&#34;你试图解决通常被认为是一件好事:如果代码必须存在于某处的文件中,那么你需要一个这样的文件的命名约定来组织项目;并且由于您还需要命名空间和类的命名约定,因此将两个实际的保存工作对齐,因为您不需要跟踪这两种约定。
PHP还包含一个功能,以autoloading的形式为此提供更强大的优势。这允许你编写一个函数,当你提到一个尚未定义的类时,它将被调用该类名;通过将文件名与类名对齐,它可以找到并加载该类。随着项目的增长,这非常有用,因为这意味着您永远不需要将require
或include
添加到文件中,或者计算出代码的特定区域所需的确切依赖关系树。主要框架已经在标准化的目录布局上进行了合作,以利用这一点,称为PSR-4。
虽然创建大量目录和单独文件可能很烦人,并且很容易将许多小类放入一个文件中,但这并不能很好地扩展,如果其中一个小类后来增长,那么你和#39;很遗憾没有自己的文件,有自己的版本历史等等。
如果您在文件所包含的课程后没有为文件命名,则需要手动管理一组复杂的require
/ include
行,跟踪正确的顺序以定义所有内容,或者具有自动加载器功能,其中包含将类名称映射到文件名的长列表。要么听起来像很多工作对我没有好处。
如果您的文件将在课程之后命名,那么自动加载器仍然有效,但您唯一获得的是您不需要在文件顶部。另一方面,您需要创建一个相当不寻常的函数来包含这些文件,涉及class Cart
的使用效率相当低。像OpCache和HHVM这样的事情会发现缓存和优化以这种方式加载的代码要困难得多,并且任何执行静态分析的工具都将完全失败,因为文件中的代码无效(例如PHPCodeSniffer报告编码标准,PHPDocumentor,或任何提供函数列表和语法分析功能的编辑器或IDE。)
最后,通常会注意到代码读取比写更频繁。对于绝大多数类而言,您正在保存的步骤只发生一次 - 首次创建类时。重命名或复制类通常是非常罕见的,如果您重命名大量文件,制作脚本以自动执行任务相当容易。另一方面,您正在介绍一些使您阅读代码变得更难的事情。除了混淆静态分析(以及自动化文档)之外,您还必须向从事该项目的新开发人员解释这种特殊方案,从而有效地提高您的培训成本。还有一个问题是,一旦扩展到单个目录之外,您将不得不查看文件的完整目录路径以查看它实际定义的类;我经常最终打开几个同名的文件(例如eval()
),而且我(和我的编辑)可以查看文件顶部的完整类声明,这对于跟踪哪个文件是必不可少的。是哪个。