Dav*_*ess 29 php namespaces function
在命名空间中定义函数时,
namespace foo {
function bar() { echo "foo!\n"; }
class MyClass { }
}
Run Code Online (Sandbox Code Playgroud)
从另一个(或全局)命名空间调用时,必须指定命名空间:
bar(); // call to undefined function \bar()
foo\bar(); // ok
Run Code Online (Sandbox Code Playgroud)
对于类,您可以使用"use"语句将类有效地导入当前命名空间[编辑:我认为您可以"使用foo"来获取类,但显然不是.]
use foo\MyClass as MyClass;
new MyClass(); // ok, instantiates foo\MyClass
Run Code Online (Sandbox Code Playgroud)
但这不适用于函数[并且考虑到有多少函数会很笨拙]:
use foo\bar as bar;
bar(); // call to undefined function \bar()
Run Code Online (Sandbox Code Playgroud)
您可以对命名空间进行别名以使前缀更短以进行输入,
use foo as f; // more useful if "foo" were much longer or nested
f\bar(); // ok
Run Code Online (Sandbox Code Playgroud)
但有没有办法完全删除前缀?
背景:我正在研究Hamcrest匹配库,它定义了许多工厂函数,其中许多都是为嵌套而设计的.拥有名称空间前缀确实会破坏表达式的可读性.相比
assertThat($names,
is(anArray(
equalTo('Alice'),
startsWith('Bob'),
anything(),
hasLength(atLeast(12))
)));
Run Code Online (Sandbox Code Playgroud)
至
use Hamcrest as h;
h\assertThat($names,
h\is(h\anArray(
h\equalTo('Alice'),
h\startsWith('Bob'),
h\anything(),
h\hasLength(h\atLeast(12))
)));
Run Code Online (Sandbox Code Playgroud)
Mat*_*oli 35
PHP 5.6将允许使用use
关键字导入函数:
namespace foo\bar {
function baz() {
echo 'foo.bar.baz';
}
}
namespace {
use function foo\bar\baz;
baz();
}
Run Code Online (Sandbox Code Playgroud)
有关更多信息,请参阅RFC:https://wiki.php.net/rfc/use_function
通过添加下面提到的帮助程序,您可以通过调用以下命令将所有内容从Hamcrest命名空间导入到当前命名空间:
import_namespace('Hamcrest', __NAMESPACE__);
Run Code Online (Sandbox Code Playgroud)
以下是hacks,function_alias的工作方式如http://www.php.net/manual/en/function.class-alias.php,除非是在函数上工作:
function function_alias ($original, $alias) {
$args = func_get_args();
assert('count($args) == 2', 'function_alias(): requires exactly two arguments');
assert('is_string($original) && is_string($alias)', 'function_alias(): requires string arguments');
// valid function name - http://php.net/manual/en/functions.user-defined.php
assert('preg_match(\'/^[a-zA-Z_\x7f-\xff][\\\\\\\\a-zA-Z0-9_\x7f-\xff]*$/\', $original) > 0',
"function_alias(): '$original' is not a valid function name");
assert('preg_match(\'/^[a-zA-Z_\x7f-\xff][\\\\\\\\a-zA-Z0-9_\x7f-\xff]*$/\', $alias) > 0',
"function_alias(): '$alias' is not a valid function name");
$aliasNamespace = substr($alias, 0, strrpos($alias, '\\') !== false ? strrpos($alias, '\\') : 0);
$aliasName = substr($alias, strrpos($alias, '\\') !== false ? strrpos($alias, '\\') + 1 : 0);
$serializedOriginal = var_export($original, true);
eval("
namespace $aliasNamespace {
function $aliasName () {
return call_user_func_array($serializedOriginal, func_get_args());
}
}
");
}
Run Code Online (Sandbox Code Playgroud)
与名称空间导入器结合使用:
function import_namespace ($source, $destination) {
$args = func_get_args();
assert('count($args) == 2', 'import_namespace(): requires exactly two arguments');
assert('is_string($source) && is_string($destination)', 'import_namespace(): requires string arguments');
// valid function name - http://php.net/manual/en/functions.user-defined.php
assert('preg_match(\'/^([a-zA-Z_\x7f-\xff][\\\\\\\\a-zA-Z0-9_\x7f-\xff]*)?$/\', $source) > 0',
"import_namespace(): '$destination' is not a valid namespace name");
assert('preg_match(\'/^([a-zA-Z_\x7f-\xff][\\\\\\\\a-zA-Z0-9_\x7f-\xff]*)?$/\', $destination) > 0',
"import_namespace(): '$source' is not a valid namespace name");
foreach(get_declared_classes() as $class)
if (strpos($class, $source . '\\') === 0)
class_alias($class, $destination . ($destination ? '\\' : '') . substr($class, strlen($source . '\\')));
$functions = get_defined_functions();
foreach(array_merge($functions['internal'], $functions['user']) as $function)
if (strpos($function, $source . '\\') === 0)
function_alias($function, $destination . ($destination ? '\\' : '') . substr($function, strlen($source . '\\')));
}
Run Code Online (Sandbox Code Playgroud)