Does Drupal parse (and/or run) hooks that are unrelated to the content being loaded by the current user?
Drupal是否解析(和/或运行)与当前用户加载的内容无关的钩子?
For example, say I had a module foo
installed and active with the following hooks:
例如,假设我安装了一个模块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 ...
Would Drupal parse (and thus effect the load time) for pages that aren't listed in foo_menu
? Put another way, would the length and complexity of foo_display_all
effect how www.example.com/bar loads?
Drupal会为未在foo_menu中列出的页面解析(从而影响加载时间)吗?换句话说,foo_display_all的长度和复杂性是否会影响www.example.com/bar的加载方式?
At risk of having two different questions here, I'll say I would be grateful for an explanation (or link to an explanation) of how and why Drupal does or does not parse, rather than a yes/no answer.
有可能在这里遇到两个不同的问题,我会说我很感激Drupal如何以及为什么解析的解释(或链接到解释),而不是是/否答案。
5 个解决方案
#1
hook_menu is used to tell drupal about what to do at specific urls, so the result of that is cached.
hook_menu用于告诉drupal在特定URL上做什么,因此缓存结果。
Drupal will only execute the content of the hooks themselves not the entire content of the file they are located in. So when hook menu is invoked in the above example, on the foo_menu() function will be run. You can take a look at the intro text at the Hooks API
Drupal只会执行钩子本身的内容而不是它们所在文件的整个内容。所以当在上面的例子中调用钩子菜单时,将运行foo_menu()函数。您可以在Hooks API上查看介绍文本
Edit: In order for PHP to execute the function, it needs to include the file where it is located. So when Drupal wants to execute a hook, PHP would need to parse the code in that file. That is just how PHP is designed, so haven't got much to do with Drupal.
编辑:为了让PHP执行该功能,它需要包含它所在的文件。所以当Drupal想要执行一个钩子时,PHP需要解析该文件中的代码。这就是PHP的设计方式,因此与Drupal没什么关系。
This is also the reason why a lot of modules make a lot of inc files, to limit the amount of code needed to be parsed when hooks are fired.
这也是许多模块生成大量inc文件的原因,以限制在触发钩子时需要解析的代码量。
#2
Yes. As others have noted, splitting things out into include files that are loaded conditionally is the only way to cut that down. Starting in Drupal 6, it became possible to move theme_whatever() functions, as well as hook_menu() page callbacks, into separate include files. Drupal will automatically load them when they're needed without you doing any explicit require_once() juggling.
是。正如其他人所指出的那样,将内容拆分为有条件加载的包含文件是减少这种情况的唯一方法。从Drupal 6开始,可以将theme_whatever()函数以及hook_menu()页面回调移动到单独的包含文件中。 Drupal会在需要时自动加载它们,而不用任何明确的require_once()杂乱。
See the hook_menu() and hook_theme() documentation for details.
有关详细信息,请参阅hook_menu()和hook_theme()文档。
It's also important to note that if you're running an opcode cache like APC, splitting things into a bunch of conditional includes is actually worse -- APC can do all of the parsing and compiling of the PHP source in one go and persist it between requests. Splitting things out conditionally just gives it multiple discrete 'codebases' to compile depending on what's being done.
同样重要的是要注意,如果你正在运行像APC这样的操作码缓存,那么将事物拆分成一堆条件包含实际上更糟糕 - APC可以一次完成PHP源的所有解析和编译,并在两者之间持续存在要求。有条件地拆分东西只是给它多个独立的“代码库”来编译,这取决于正在做什么。
In the currently-under-development Drupal 7, a general Code registry has been added that allows any hook implementation to be split out into a separate include file. However, the overhead of managing that internal cache of functions and .inc locations, and loading them on the fly, eats up the performance gains of the smaller-to-parse codebase. The only real payoff is reduced memory usage for those on shared hosts with tight 12-16 meg memory limits; it's unclear whether the change will survive through to the final release of Drupal 7 given the tradeoffs.
在当前正在开发的Drupal 7中,添加了一个通用代码注册表,允许将任何钩子实现拆分为单独的包含文件。但是,管理函数和.inc位置的内部缓存以及动态加载它们的开销会降低较小的解析代码库的性能。唯一真正的回报是减少12-16兆内存限制的共享主机上的内存使用量;目前尚不清楚这种变化是否能够存活到Drupal 7的最终版本,并给出了权衡。
The upshot: in Drupal 6, split out the menu callbacks that build custom pages into a separate .inc file, and it will only be loaded when those pages are built. Do the same with any theme functions. And if you're using an opcode cache like APC, remember that your separate .inc files are only good for organizational purposes -- they won't give you any performance boost.
结果:在Drupal 6中,将自定义页面构建的菜单回调拆分为单独的.inc文件,只有在构建这些页面时才会加载。对任何主题功能都一样。如果您使用像APC这样的操作码缓存,请记住您的单独.inc文件仅适用于组织目的 - 它们不会为您带来任何性能提升。
#3
Drupal includes all of the MODULE.module files (and anything they include) for every module for every request.
Drupal包含每个请求的每个模块的所有MODULE.module文件(以及它们包含的任何内容)。
The only way for Drupal core to know if the module has any hooks it needs to call is to load the file. This will take time and memory.
Drupal核心知道模块是否有任何需要调用的钩子的唯一方法是加载文件。这需要时间和记忆。
#4
Firs of all, I'm not an experienced Drupal developer, second, it is not a nice implementation and third, I have not tried this, but should work
首先,我不是一个经验丰富的Drupal开发人员,第二,它不是一个很好的实现,第三,我没有尝试过,但应该工作
function foo_display_all() {
include("foo_display_all_body.php");
}
This way the hooks are parsed every time, + one additional php file with the function body.
这样每次都会解析钩子,+一个带有函数体的额外php文件。
Fourth, it's micro optimization. Might be better to avoid it if not absolutely necessary, as the additional complexity (and the +1 file read) can cost more for you in the long run than it saves on parsing.
第四,它是微观优化。如果不是绝对必要的话,可能最好避免使用它,因为从长远来看,额外的复杂性(和+1文件读取)对你来说可能比在解析时节省更多。
If you want to make the php code parsing faster, you should use an opcode cache
如果你想更快地解析php代码,你应该使用操作码缓存
#5
APC now seems to cache .inc files as well as php, which does give a great performance boost.
APC现在似乎缓存.inc文件以及php,这确实提供了很好的性能提升。
#1
hook_menu is used to tell drupal about what to do at specific urls, so the result of that is cached.
hook_menu用于告诉drupal在特定URL上做什么,因此缓存结果。
Drupal will only execute the content of the hooks themselves not the entire content of the file they are located in. So when hook menu is invoked in the above example, on the foo_menu() function will be run. You can take a look at the intro text at the Hooks API
Drupal只会执行钩子本身的内容而不是它们所在文件的整个内容。所以当在上面的例子中调用钩子菜单时,将运行foo_menu()函数。您可以在Hooks API上查看介绍文本
Edit: In order for PHP to execute the function, it needs to include the file where it is located. So when Drupal wants to execute a hook, PHP would need to parse the code in that file. That is just how PHP is designed, so haven't got much to do with Drupal.
编辑:为了让PHP执行该功能,它需要包含它所在的文件。所以当Drupal想要执行一个钩子时,PHP需要解析该文件中的代码。这就是PHP的设计方式,因此与Drupal没什么关系。
This is also the reason why a lot of modules make a lot of inc files, to limit the amount of code needed to be parsed when hooks are fired.
这也是许多模块生成大量inc文件的原因,以限制在触发钩子时需要解析的代码量。
#2
Yes. As others have noted, splitting things out into include files that are loaded conditionally is the only way to cut that down. Starting in Drupal 6, it became possible to move theme_whatever() functions, as well as hook_menu() page callbacks, into separate include files. Drupal will automatically load them when they're needed without you doing any explicit require_once() juggling.
是。正如其他人所指出的那样,将内容拆分为有条件加载的包含文件是减少这种情况的唯一方法。从Drupal 6开始,可以将theme_whatever()函数以及hook_menu()页面回调移动到单独的包含文件中。 Drupal会在需要时自动加载它们,而不用任何明确的require_once()杂乱。
See the hook_menu() and hook_theme() documentation for details.
有关详细信息,请参阅hook_menu()和hook_theme()文档。
It's also important to note that if you're running an opcode cache like APC, splitting things into a bunch of conditional includes is actually worse -- APC can do all of the parsing and compiling of the PHP source in one go and persist it between requests. Splitting things out conditionally just gives it multiple discrete 'codebases' to compile depending on what's being done.
同样重要的是要注意,如果你正在运行像APC这样的操作码缓存,那么将事物拆分成一堆条件包含实际上更糟糕 - APC可以一次完成PHP源的所有解析和编译,并在两者之间持续存在要求。有条件地拆分东西只是给它多个独立的“代码库”来编译,这取决于正在做什么。
In the currently-under-development Drupal 7, a general Code registry has been added that allows any hook implementation to be split out into a separate include file. However, the overhead of managing that internal cache of functions and .inc locations, and loading them on the fly, eats up the performance gains of the smaller-to-parse codebase. The only real payoff is reduced memory usage for those on shared hosts with tight 12-16 meg memory limits; it's unclear whether the change will survive through to the final release of Drupal 7 given the tradeoffs.
在当前正在开发的Drupal 7中,添加了一个通用代码注册表,允许将任何钩子实现拆分为单独的包含文件。但是,管理函数和.inc位置的内部缓存以及动态加载它们的开销会降低较小的解析代码库的性能。唯一真正的回报是减少12-16兆内存限制的共享主机上的内存使用量;目前尚不清楚这种变化是否能够存活到Drupal 7的最终版本,并给出了权衡。
The upshot: in Drupal 6, split out the menu callbacks that build custom pages into a separate .inc file, and it will only be loaded when those pages are built. Do the same with any theme functions. And if you're using an opcode cache like APC, remember that your separate .inc files are only good for organizational purposes -- they won't give you any performance boost.
结果:在Drupal 6中,将自定义页面构建的菜单回调拆分为单独的.inc文件,只有在构建这些页面时才会加载。对任何主题功能都一样。如果您使用像APC这样的操作码缓存,请记住您的单独.inc文件仅适用于组织目的 - 它们不会为您带来任何性能提升。
#3
Drupal includes all of the MODULE.module files (and anything they include) for every module for every request.
Drupal包含每个请求的每个模块的所有MODULE.module文件(以及它们包含的任何内容)。
The only way for Drupal core to know if the module has any hooks it needs to call is to load the file. This will take time and memory.
Drupal核心知道模块是否有任何需要调用的钩子的唯一方法是加载文件。这需要时间和记忆。
#4
Firs of all, I'm not an experienced Drupal developer, second, it is not a nice implementation and third, I have not tried this, but should work
首先,我不是一个经验丰富的Drupal开发人员,第二,它不是一个很好的实现,第三,我没有尝试过,但应该工作
function foo_display_all() {
include("foo_display_all_body.php");
}
This way the hooks are parsed every time, + one additional php file with the function body.
这样每次都会解析钩子,+一个带有函数体的额外php文件。
Fourth, it's micro optimization. Might be better to avoid it if not absolutely necessary, as the additional complexity (and the +1 file read) can cost more for you in the long run than it saves on parsing.
第四,它是微观优化。如果不是绝对必要的话,可能最好避免使用它,因为从长远来看,额外的复杂性(和+1文件读取)对你来说可能比在解析时节省更多。
If you want to make the php code parsing faster, you should use an opcode cache
如果你想更快地解析php代码,你应该使用操作码缓存
#5
APC now seems to cache .inc files as well as php, which does give a great performance boost.
APC现在似乎缓存.inc文件以及php,这确实提供了很好的性能提升。