Sử dụng module_invoke_all('some_hook')
là dễ dàng, nhưng điều này là tốt hơn cho hiệu suất?
foreach (module_implements('some_hook') as $module) {
$data = module_invoke($module, 'some_hook');
}
Sử dụng module_invoke_all('some_hook')
là dễ dàng, nhưng điều này là tốt hơn cho hiệu suất?
foreach (module_implements('some_hook') as $module) {
$data = module_invoke($module, 'some_hook');
}
Câu trả lời:
Có rất ít sự khác biệt; module_invoke_all()
chạy đoạn mã sau:
function module_invoke_all() {
$args = func_get_args();
$hook = $args[0];
unset($args[0]);
$return = array();
foreach (module_implements($hook) as $module) {
$function = $module . '_' . $hook;
if (function_exists($function)) {
$result = call_user_func_array($function, $args);
if (isset($result) && is_array($result)) {
$return = array_merge_recursive($return, $result);
}
elseif (isset($result)) {
$return[] = $result;
}
}
}
return $return;
}
Sự khác biệt duy nhất là với module_invoke_all()
, ví dụ, func_get_args()
chỉ được gọi một lần, trong khi khi sử dụng module_invoke()
func_get_args()
được gọi mỗi lần module_invoke()
được gọi; đó là một sự khác biệt cận biên, mặc dù.
Có một vài trường hợp module_implementing()
và module_invoke()
được sử dụng, thông thường khi một mô-đun cần biết mô-đun nào được gọi, chẳng hạn như trong trường hợp search_get_info()
đó xây dựng một mảng thông tin về các mô-đun thực hiện các chức năng tìm kiếm.
function search_get_info($all = FALSE) {
$search_hooks = &drupal_static(__FUNCTION__);
if (!isset($search_hooks)) {
foreach (module_implements('search_info') as $module) {
$search_hooks[$module] = call_user_func($module . '_search_info');
// Use module name as the default value.
$search_hooks[$module] += array(
'title' => $module,
'path' => $module,
);
// Include the module name itself in the array.
$search_hooks[$module]['module'] = $module;
}
}
if ($all) {
return $search_hooks;
}
$active = variable_get('search_active_modules', array('node', 'user'));
return array_intersect_key($search_hooks, array_flip($active));
}
Một ví dụ khác là image_styles () , lấy danh sách tất cả các kiểu hình ảnh được thực hiện bởi các mô-đun và sử dụng mã sau:
foreach (module_implements('image_default_styles') as $module) {
$module_styles = module_invoke($module, 'image_default_styles');
foreach ($module_styles as $style_name => $style) {
$style['name'] = $style_name;
$style['module'] = $module;
$style['storage'] = IMAGE_STORAGE_DEFAULT;
foreach ($style['effects'] as $key => $effect) {
$definition = image_effect_definition_load($effect['name']);
$effect = array_merge($definition, $effect);
$style['effects'][$key] = $effect;
}
$styles[$style_name] = $style;
}
}
Trong cả hai trường hợp, thông tin được truy xuất được đặt trong một mảng trong đó chỉ mục là tên viết tắt của mô-đun.
Khi bạn xem mã, module_invoke_all thực hiện điều đó, cộng với một vài kiểm tra độ tỉnh táo. Và nó rất dễ dàng. :-)
Có lẽ tốt hơn là không sử dụng, và thay vào đó sử dụng drupal_alter () .
Như đã nêu trong tài liệu module_invoke_all () ,
Tất cả các đối số được thông qua bởi giá trị. Sử dụng drupal_alter () nếu bạn cần truyền tham số bằng tham chiếu.