Drupal是否解析(和/或运行)与当前用户加载的内容无关的挂钩?
例如,假设我安装了一个模块foo
并使用以下挂钩激活:
<?php
// .. stuff ...
function foo_menu() {
$items = array();
$items['foo/show'] = array(
'title' => t('Foo!'),
'page callback' => 'foo_display_all',
'description' => 'All our foo are belong to you',
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
function foo_display_all() {
// About 100 lines of code
}
// ... stuff ...
Drupal会为foo_menu
中未列出的页面解析(从而影响加载时间)吗?换句话说,foo_display_all
的长度和复杂性会影响www.example.com/bar的加载吗?
在这里有两个不同的问题的风险,我会说我会感谢Drupal如何以及为什么解析,而不是是/否答案的解释(或链接到解释)。< / p>
答案 0 :(得分:6)
hook_menu用于告诉drupal在特定URL上做什么,因此缓存结果。
Drupal只会执行钩子本身的内容而不是它们所在文件的整个内容。所以当在上面的例子中调用钩子菜单时,将运行foo_menu()函数。 您可以查看Hooks API
上的介绍文字编辑: 为了让PHP执行该功能,它需要包含它所在的文件。所以当Drupal想要执行一个钩子时,PHP需要解析该文件中的代码。这就是PHP的设计方式,因此与Drupal没什么关系。
这也是许多模块生成大量inc文件的原因,以限制在触发钩子时需要解析的代码量。
答案 1 :(得分:4)
是。正如其他人所指出的那样,将内容拆分为有条件加载的包含文件是减少这种情况的唯一方法。从Drupal 6开始,可以将theme_whatever()函数以及hook_menu()页面回调移动到单独的包含文件中。 Drupal会在需要的时候自动加载它们,而不需要你做任何明确的require_once()杂耍。
有关详细信息,请参阅hook_menu()和hook_theme()文档。
同样重要的是要注意,如果你正在运行像APC这样的操作码缓存,将事物拆分成一堆条件包含实际上是更糟 - APC可以完成所有的解析和编译PHP源代码一次性在请求之间保持不变。有条件地拆分东西只是给它多个独立的“代码库”来编译,这取决于正在做什么。
在当前正在开发的Drupal 7中,添加了一个通用Code registry,允许将任何钩子实现拆分为单独的包含文件。但是,管理函数和.inc位置的内部缓存以及动态加载它们的开销会降低较小的解析代码库的性能。唯一真正的回报是减少12-16兆内存限制的共享主机上的内存使用量;目前尚不清楚这种变化是否能够存活到Drupal 7的最终版本,并给出了权衡。
Drupal 6中的答案 2 :(得分:3)
Drupal包含每个请求的每个模块的所有MODULE.module文件(以及它们包含的任何内容)。
Drupal核心知道模块是否有任何需要调用的钩子的唯一方法是加载文件。这需要时间和记忆。
答案 3 :(得分:3)
首先,我不是一个经验丰富的Drupal开发人员,第二,它不是一个很好的实现,第三,我没有尝试过,但应该工作
function foo_display_all() {
include("foo_display_all_body.php");
}
这样每次都会解析钩子,+一个带有函数体的附加php文件。
第四,它是微观优化。如果不是绝对必要的话,可能最好避免使用它,因为从长远来看,额外的复杂性(和+1文件读取)对你来说可能比在解析时节省的成本更高。如果你想更快地解析php代码,你应该使用操作码缓存
答案 4 :(得分:0)
APC现在似乎缓存.inc文件以及php,这确实提升了性能。