Если вы хотите знать, откуда вы пришли debug_backtrace () ваш друг.
Следующее должно решить вашу загадку:
function backtrace_namespace()
{
$trace = array();
$functions = array_map(
function ($v) {
return $v['function'];
},
debug_backtrace()
);
foreach ($functions as $func) {
$f = new ReflectionFunction($func);
$trace[] = array(
'function' => $func,
'namespace' => $f->getNamespaceName()
);
}
return $trace;
}
Просто позвоните из любой точки мира, чтобы увидеть след.
Я изменил ваш файл процедурного кода следующим образом:
namespace Foo;
function bar ()
{
var_export(backtrace_namespace());
}
/** The unasked question: We need to use the fully qualified name currently. */
function go()
{
\Site\Action\add('hookname', 'Foo\\bar');
}
go();
Результат от включения этого файла будет следующим на стандартный вывод:
array (
0 =>
array (
'function' => 'backtrace_namespace',
'namespace' => '',
),
1 =>
array (
'function' => 'Foo\\bar',
'namespace' => 'Foo',
),
2 =>
array (
'function' => 'call_user_func',
'namespace' => '',
),
3 =>
array (
'function' => 'Site\\Action\\add',
'namespace' => 'Site\\Action',
),
4 =>
array (
'function' => 'Foo\\go',
'namespace' => 'Foo',
),
)
Теперь за бонусные баллы ответ на скрытый вопрос:
Как разрешить вызывающее пространство имен, чтобы избежать использования полного имени функции в качестве аргумента?
Следующее позволит вам вызвать функцию, как вы и предполагали:
Site\Action\add('hookname', 'bar');
Без страха:
Предупреждение: call_user_func () ожидает, что параметр 1 будет допустимым обратным вызовом, функция 'bar' не найдена или недопустимое имя функции
Так что перед тем, как сделать редизайн, попробуйте это для размера:
namespace Site\Action;
function add($hook, $function)
{
$trace = backtrace_namespace();
$prev = (object) end($trace);
$function = "$prev->namespace\\$function";
if (is_callable($function))
call_user_func($function);
}
Я не вижу причин, по которым debug_backtrace
не следует использовать, вот для чего он нужен.
NJoy!