Объединение func_get_args, call_user_func_array и Pass By Reference

Сегодня я делаю что-то немного сложное в PHP 5.3.29. Я нахожусь в сценарии, где я должен цепи 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_* называется рамкой. Я по сути использую гость как временный «Code Hub», где различные функции в моем коде обрабатываются отдельно.

И нет, я не могу разделить этот проект на несколько проектов. Это ограничение наложено на меня. Обычно, я бы выбрал этот маршрут.

module* функции — это в основном внутренние функции, которые я хочу иметь возможность легко включать и выключать. Это намеренно отдельные файлы, так как сами модули не имеют кроссовера, за исключением того, что они иногда используют одни и те же хуки.

Все конфигурации для самих крючков обрабатываются в $hooks переменная (Это упрощенная версия. Обычно есть также атрибуты функций для каждого модуля, атрибуты модуля и т. Д., Но это не требуется для этой конкретной проблемы.).

Я стараюсь максимально обобщить это. Я знаю, что я мог бы засунуть все в соответствующие caller_hook_* функций, но по мере роста этого проекта эти хуки станут громоздкими для обслуживания, если независимые функции будут объединены.

Некоторые из крючков используют Pass-By-Reference на некоторых из их аргументов, поэтому я должен иметь возможность указать, какие из них. Все, что я сделал до сих пор, работает для всех Pass-By-Value только функции.

Я тоже не хочу использовать время вызова по ссылке.

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 переменная.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]