在函数内使用php命名空间

39

在我的函数内部尝试使用命名空间时,我遇到了解析错误。

require('/var/load.php');

function go(){

  use test\Class;

    $go = 'ok';
    return $go;
}

    echo go();

1
PHP解析错误:在/var/www/test.php的第8行中出现语法错误,意外的T_USE。 - westnblue
2
你为什么想要这样做呢?use只是建立一个文件范围内的别名,没有更多或更少。在函数中这样做有什么意义呢? - deceze
3个回答

61

根据导入的作用域规则,use关键字必须在文件的最外层范围(全局范围)或命名空间声明内部声明。这是因为导入是在编译时而不是运行时完成的,所以它不能是块级作用域。

所以你应该像这样使用,在全局级别指定use

require('/var/load.php');
use test\Class;

function go(){
    $go = 'ok';
    return $go;
}
echo go();

请查看以下手册中的示例 5 请参考其手册:http://php.net/manual/en/language.namespaces.importing.php


命名空间与作用域无关,因此我会避免在这里使用模糊的术语... - deceze
@deceze 请指定一些链接,以便清晰地了解 PHP 中的命名空间和作用域。 - Nishant
...?你已经链接到了一个:手册。变量作用域命名空间只是两个完全不同的概念。 - deceze
根据我的理解,命名空间与Unix中的“别名”命令相同,但为什么它只有全局作用域?为什么不能在函数中定义它,并将其作用域限制在该函数内部?请帮助我理解这个问题。 - Nishant
我认为这是因为使用它的情况非常有限,而且会引起混淆。在一个函数中,你使用了use Foo\Bar as MyClass,但在同一文件中的另一个函数中,你又使用了use Foo\Baz as MyClass。这很容易在阅读源代码时引入非常令人困惑的小错误。因此,use指令一次只适用于整个文件/命名空间。无论如何,我还没有遇到过不足以解决的情况。 - deceze

6

来自手册

use关键字必须在文件的最外层作用域(全局作用域)中声明,或者在命名空间声明内部。


2
@westnblue 这意味着 use 语句只能出现在文件打开时立即运行的代码部分。如果将其放在类或函数内部,则会在调用类或函数时执行。这与 PHP 命名空间和解析代码的系统不兼容,因此必须将 use 语句放在文件的最外层范围内。 - lonesomeday
请帮我解决一个命名空间的问题,我在一个函数中使用了“use”,这让我很头疼。谢谢。 - Michael Nguyen

0
据我所知,许多人在包含单独的函数文件并尝试在该函数中使用静态方法时会遇到这个问题。例如,在 index.php 中。
namespace foo/bar
require('func.php')
f();

并且在 func.php

function f() {
    StaticClass::static_method();
}

你只需要在 func.php 中声明命名空间 foo/bar (就像在 index.php 中声明的一样),所以代码应该如下:

namespace foo\bar
function f() {
    StaticClass::static_method();
}

为避免以下错误:

Fatal error: Uncaught Error: Class 'StaticClass' not found in func.php

必须注意以下事项:现在显而易见,但是之前我曾困惑过,即func.php文件中的命名空间声明不会被包含(require)func.php文件的文件继承。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接