我想知道在调用函数时是否可以确定当前命名空间是什么。我有这个函数声明:
<?php
namespace Site\Action;
function add ($hook, $function) {
/**
* determine the namespace this was called from because
* __NAMESPACE__ is "site\action" :(
*/
if (is_callable($function))
call_user_func($function);
}
?>
在另一个档案中:
<?php
namespace Foo;
function bar () {
}
?>
让我们说我将此作为我的程序代码:
<?php
namespace Foo;
Site\Action\add('hookname', 'bar');
?>
假设在这种情况下Bar
旨在解析为Foo\bar
,因为那是从它调用的命名空间,这是有意义的。
这又是一个很长的解释,是否可以确定调用Site\Action\add()
的活动命名空间?
提前致谢。
答案 0 :(得分:4)
如果你想知道你来自哪里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();
包含此文件的结果将在stdout上显示以下内容:
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!
答案 1 :(得分:1)
如果您使用闭包而不是静态函数,您可以随时询问反射API
namespace A;
$closure = function($word = 'hello')
{
return $word;
};
...
$r = new ReflectionFunction($closure);
print $r->getNamespaceName();
答案 2 :(得分:0)
我不知道我是否遗漏了一些东西,但有了这个:
http://php.net/manual/en/reflectionclass.getnamespacename.php,我认为您可以获得正在使用的对象的命名空间。