2015-04-06 31 views
0

今天我29年3月5日在做PHP的东西有点棘手。我在一个场景中,我必须连锁func_get_args,call_user_func_array,并通过一些通过引用的参数。结合func_get_args,call_user_func_array,并引用传递

在简化方案的尝试看起来是这样的:

caller.php

//* Caller Setup *// 
// Define which Modules call which Hooks 
global $hooks = array(
    'hookA' => array('moduleA', 'moduleB'), 
    'hookB' => array('moduleA') 
); 

// Generically calls any Hook for all Modules 
function caller_call_hook($hook, $by_reference = array()) 
{ 
    // Use Hooks Array 
    global $hooks; 

    // Initialize Return Array 
    $values = array(); 

    // Determine the Arguments for the Function Call 
    $args = func_get_args(); 

    // Remove $hook and $by_reference from the Arguments 
    unset($args[0], $args[1]); 
    $args = array_values($args); // Collapse Array 

    // Map specified Arguments by Reference 
    foreach($by_reference as $index) 
     $args[$index] =& $args[$index]; 

    // Call each Embedded Hook 
    foreach($hooks[$hook] as $module) 
     $values[$module] = call_user_func_array($module . '_' . $hook, $args); 

    // Return all Values 
    return $values; 
} 

//* Caller Triggers *// 
function caller_hook_A($paramA, $paramB) 
{ 
    caller_call_hook('hook_A', array(), $paramA, $paramB); 
} 

function caller_hook_B(&$paramA) 
{ 
    caller_call_hook('hook_B', array(0), $paramA); 
} 

moduleA.php

function moduleA_hook_A($paramA, $paramB) { ... } 
function moduleA_hook_B(&$paramA) { ... } 

moduleB.php

function moduleB_hook_A($paramA, $paramB) { ... } 

做这一切引发了警告:

Warning: Parameter 1 to moduleA_hook_B() expected to be a reference, value given in caller_call_hook() 

我怎样才能使这项工作按照预期?


只是提供一些背景,以什么实际发生在这里:

我在一个框架,caller_hook_*由框架调用工作。我基本上使用调用者作为转换“代码中心”,其中我的代码中的各种功能是分开处理的。

不,我不能把这个项目分成多个项目。这是对我的限制。通常情况下,这将是我会采取的路线。

module*功能,我想能够轻松打开和关闭基本上内部特征。由于模块本身没有交叉,所以它们故意将文件分开,除了它们有时使用相同的钩子。

钩子本身的所有配置都在$hooks变量中处理(这是一个简化版本,通常也有每个模块的功能属性,模块属性等,但这不是特别需要解决的问题。)

我试图尽可能地保持这种一般化。我知道我可以在各自的功能中推动一切,但随着此项目的发展,如果独立功能聚集在一起,这些挂钩将变得非常麻烦。

一些钩子使用传递引用对他们的一些参数,因此我需要能够指定哪些。我迄今为止所做的一切都适用于所有传递值唯一的功能。

我也不想使用通话时间通过引用

+0

什么是$ args [$ index] =&$ args [$ index]'应该这样做?怎样才能成为对自身的参照? – Barmar

+0

应该是'$ args [$ index] =&$ by_reference [$ index];'? – Barmar

+0

我来自C++背景,所以我可能在这里使用引用不正确。你会推荐什么? – Boom

回答

0

我最终得到这个工作,虽然是一个奇怪的解决方案。

我走在正确的轨道上,略微偏离。

我改变这样的:

// Map specified Arguments by Reference 
foreach($by_reference as $index) 
    $args[$index] =& $args[$index]; 

这样:

// Map specified Arguments by Reference 
$refs = array(); 

foreach($args as $key => &$value) 
    $refs[$key] =& $value; 

这:

// Call each Embedded Hook 
foreach($hooks[$hook] as $module) 
    $values[$module] = call_user_func_array($module . '_' . $hook, $args); 

这样:

// Call each Embedded Hook 
foreach($hooks[$hook] as $module) 
    $values[$module] = call_user_func_array($module . '_' . $hook, $refs); 

这是一个奇怪的修复程序,但它可以完成这项工作。事实证明,我不需要$by_reference变量。