php命名空间和use我并不是很熟悉,经过实际例子测试,得出以下结论:在phalapi中,只有顶级命名空间下只有放置在Api、Domain以及Model目录下的类使用相应的命名空间才能被use后实例化,如果不在这三个目录下,则需要在composer.json中添加自动加载文件。当然,也可以在config/di.php中注册di依赖注入服务,需要使用时实例化\PhalApi\DI()->name
即可。以下为测试过程记录。
测试不在Api、Domain以及Model目录下的类使用
在phalapi/src/app目录下新建一个Test.php,定义命名空间为App\Test;
//phalapi/src/app/Test.php
namespace App\Test;
class Test{
public function say() {
return 'hello';
}
}
接着在phalapi/src/app/Api下的Hello.php中定义Test接口用于本次测试
//phalapi/src/app/Api/Hello.php
namespace App\Api;
use PhalApi\Api;
use App\Test\Test;
/**
* 测试模块接口
*/
class Hello extends Api {
/**
* 测试命名空间接口
* @desc 测试命名空间自动加载
* @return string rs 结果
*/
public function test(){
$a = new Test();
return $a->say();
}
}
此时访问接口?s=App.Hello.Test
会提示uncaught错误,即 App\Test\Test类找不到。可见该文件没有被自动加载,才产生了这种结果。
接下来为进一步证明,我们将该文件的命名空间修改为App\Domain进行测试。会发现同样报错Uncaught Error: Class 'App\\Domain\\Test' not found
,接下来我们测试将该文件放置到Domain目录下。
测试在Api、Domain以及Model目录下的类使用
我们先将该文件放置到Domain目录下,将命名空间修改为App\Test。再次在Test接口中访问,会发现还是提示Uncaught Error: Class ‘App\Test\Test’ not found。这是不是说明命名空间还必须与文件路径相一致呢?我们将命名空间修改为App\Domain再次尝试一下,接口成功返回数据,这一点在官网文档上已有提示。
测试composer.json中声明自动加载
接下来我们将Test.php移回app目录下,命名空间修改为App\Test,然后在项目根目录下的composer.json中的添加一条路径。
"autoload": {
"files": [
"src/app/functions.php",
"src/app/Test.php"//添加的自动加载文件
],
最后仍在Test接口中实例化该类,访问可正常返回结果。
综上可见命名空间的自动加载是框架已经定义好的,只有满足以下两个条件:
- 类文件放置在Api、Domain以及Model目录下
- 命名空间需与文件路径保持一致
除此之外,只能通过di注入或者在composer.json中声明自动加载才可使用。
2019/2/22更新
@dogstar
大佬亲自在phalapi社区回复,感谢大佬答疑解惑!
最上面的例子,把命名空间从原来的【namespace App\Test;】改为【namespace App;】,最后【use App\Test;】就可以了。
要么,把文件路径调整为【phalapi/src/app/Test/Test.php】。