如何使用 spl_autoload 在所有名称空间中自动使用根 类?
How to use roots classes in all namespaces automatically with spl_autoload?
Class 可以在 spl_autoload_register
内(自动)访问吗?
例如,我在index.php中使用spl_autoload_register
:
<?php
class Utils {
public function example() {
echo 'Hello word!';
}
}
spl_autoload_register(function($class)
{
$relative_class = strtolower(str_replace('\', '/', $class));
$file = './src/' . $relative_class . '.php';
if (is_file($file)) {
require_once $file;
}
});
$user = new \Controllers\Foo\User;
这个 new \Controllers\Foo\User;
自动加载这个文件 ./src/controllers/foo/user.php
user.php:
<?php
namespace Controllers/Foo;
class User
{
public function foo() {
//Something...
}
}
如果我需要使用 Utils class 我必须在文件 [=49= 中添加 new \Controllers\Foo\User
] 像这样:
public function foo() {
\Utils::example();
}
或
<?php
namespace Controllers/Foo;
use \Utils as Utils;
class User
{
public function foo() {
Utils::example();
}
}
是否可以在 spl_autoload_register
内(自动)访问 Utils class?我会在没有 use \Utils as Utils;
且没有反斜杠 (\Utils::
) 的情况下使用。
你不能。这就是使用命名空间的全部意义所在。您可以引用 class whitout 反斜杠或 use
语句 only 如果它在您正在使用的同一名称空间中。您无法破解自动加载器以自动将目标 class 导入当前命名空间并即时更改其命名空间。
如果您的 class 不属于 named 命名空间,那么它在 global 命名空间中,而您仍然必须与 \
或 use
一起使用。 python、java、go、.net、c/c++等中的import
或use
关键字也是如此
除了使用 use ... as ...
或 "backslash" (\
) 之外,没有任何标准可以做到这一点,但是我们可以 "cheat the PHP" 在 spl_autoload_register()
中使用 eval()
来扩展 namespace
.
中的 Utils class
Only use this if really necessary, prefer to use "backslash" (\
) or use \Utils as Utils
示例(阅读代码中的注释):
<?php
class Utils {
public static function example() {
echo 'Hello World!';
}
}
spl_autoload_register(function($class)
{
$relative_class = strtolower(str_replace('\', '/', $class));
$file = './src/' . $relative_class . '.php';
if (is_file($file)) {
$np = explode('\', $class); //Dividi string
//Check if class exists in namespace (prevent conflicts)
if (class_exists(implode('::', $np)) === false) {
//Remove "class name", use only "namespace"
array_pop($np);
//evaluate a namespace in eval (extends the Utils class)
eval(
'namespace ' . implode('\', $np) . ' {' . PHP_EOL .
'class Utils extends \Utils {}' . PHP_EOL .
'}'
);
}
require_once $file;
}
});
$user = new \Controllers\Foo\User;
$user->foo(); //Show "Hello word!"
我承认这是一个丑陋的黑客,也许我不会使用,但它仍然是一个提示是的。
Note: use \Utils as Utils
not work in eval
Class 可以在 spl_autoload_register
内(自动)访问吗?
例如,我在index.php中使用spl_autoload_register
:
<?php
class Utils {
public function example() {
echo 'Hello word!';
}
}
spl_autoload_register(function($class)
{
$relative_class = strtolower(str_replace('\', '/', $class));
$file = './src/' . $relative_class . '.php';
if (is_file($file)) {
require_once $file;
}
});
$user = new \Controllers\Foo\User;
这个 new \Controllers\Foo\User;
自动加载这个文件 ./src/controllers/foo/user.php
user.php:
<?php
namespace Controllers/Foo;
class User
{
public function foo() {
//Something...
}
}
如果我需要使用 Utils class 我必须在文件 [=49= 中添加 new \Controllers\Foo\User
] 像这样:
public function foo() {
\Utils::example();
}
或
<?php
namespace Controllers/Foo;
use \Utils as Utils;
class User
{
public function foo() {
Utils::example();
}
}
是否可以在 spl_autoload_register
内(自动)访问 Utils class?我会在没有 use \Utils as Utils;
且没有反斜杠 (\Utils::
) 的情况下使用。
你不能。这就是使用命名空间的全部意义所在。您可以引用 class whitout 反斜杠或 use
语句 only 如果它在您正在使用的同一名称空间中。您无法破解自动加载器以自动将目标 class 导入当前命名空间并即时更改其命名空间。
如果您的 class 不属于 named 命名空间,那么它在 global 命名空间中,而您仍然必须与 \
或 use
一起使用。 python、java、go、.net、c/c++等中的import
或use
关键字也是如此
除了使用 use ... as ...
或 "backslash" (\
) 之外,没有任何标准可以做到这一点,但是我们可以 "cheat the PHP" 在 spl_autoload_register()
中使用 eval()
来扩展 namespace
.
Only use this if really necessary, prefer to use "backslash" (
\
) oruse \Utils as Utils
示例(阅读代码中的注释):
<?php
class Utils {
public static function example() {
echo 'Hello World!';
}
}
spl_autoload_register(function($class)
{
$relative_class = strtolower(str_replace('\', '/', $class));
$file = './src/' . $relative_class . '.php';
if (is_file($file)) {
$np = explode('\', $class); //Dividi string
//Check if class exists in namespace (prevent conflicts)
if (class_exists(implode('::', $np)) === false) {
//Remove "class name", use only "namespace"
array_pop($np);
//evaluate a namespace in eval (extends the Utils class)
eval(
'namespace ' . implode('\', $np) . ' {' . PHP_EOL .
'class Utils extends \Utils {}' . PHP_EOL .
'}'
);
}
require_once $file;
}
});
$user = new \Controllers\Foo\User;
$user->foo(); //Show "Hello word!"
我承认这是一个丑陋的黑客,也许我不会使用,但它仍然是一个提示是的。
Note:
use \Utils as Utils
not work ineval