php如何通过use关键字导入命名空间里的函数变量以及类?
发布于 作者:苏南大叔 来源:程序如此灵动~
本文将要总结一下php中命名空间的使用方法,文章属于总结性质的,高手请飘过。命令空间可以更好地区分代码的归属,对代码进行分门别类的放置。并且不同命名空间里面,也可以有同名的变量或者类及其它。

苏南大叔的“程序如此灵动”博客,记录苏南大叔的编程感想和感悟。本文测试环境:win10,nginx@1.15.11,php@8.2.10-nts。
定义"namespace"
定义一个命名空间其实很简单。最常见的使用姿势是:
namespace SN;
class sunan{
}本文中为了便于问题描述,这里增加了其它的元素。本文的测试代码如下:
namespace SN;
// namespace SN\demo;
class sunan
{
function test()
{
echo 'SN命名空间下的sunan类的test()方法', PHP_EOL;
}
}
// 下面的都是附带的测试数据,一般来说,是就定义个class就行
$author = "苏南大叔";
const AUTHOR = "Uncle Sunan";
function test()
{
echo 'SN命名空间下的test()函数', PHP_EOL;
}
trait sunan_trait
{
public function test()
{
echo "SN命名空间下的trait里的test方法", PHP_EOL;
}
}命名空间是用于表示代码归属的。所以,合理的命名规划还是非常必要的。对于这个类文件,建议文件名是sunan.php,路径是<其它路径>/SN/sunan.php。当然,不这么命名也是可以运行的,这里仅仅是个最佳实践的建议。

加载类库文件
对于本文的代码来说,直接include或者require是更好的选择。关于include和require的区别,可以参考:
可以直接这样加载类库:
include 'namespace/SN/sunan.php';如何是定义当前文件和被引用文件使用统一个namespace,那么就是这么写的:
namespace SN;
// namespace SN\demo;
include 'namespace/SN/sunan.php';如果命名空间里面仅仅是个单纯的class的话,可以使用spl_autoload_register()来做类加载。但是,如果并不是单纯的类的话,使用spl_autoload_register()会有不少问题,这个以后再写文章讨论。
use关键字导入
实际上还是涉及到use关键字,可以使用use导入类库中的相关定义。这里又有下面的几个分支:
- 导入类:
use。 - 导入函数:
use function。 - 导入变量:
use const。 - 导入
trait:use <trait的命名空间路径+trait名称>。 - 其它
使用的时候,有两个小技巧:
- 如果不先
use导入的话,也可以直接使用带路径的命名空间。 - 如果调用的文件和被导入数据所在文件,是在同一个命名空间里面的话,也可以省略或者简写命名空间的路径信息的。
- 还可以使用
as关键字对导入的数据进行改名操作。
导入类
// namespace SN;
include 'namespace/SN/sunan.php';
// $sn = new sunan(); ////注意本文件的namespace,否则会报错 Class "sunan" not found
// $sn->test(); // SN命名空间下的sunan类的test()方法
$sn = new \SN\sunan();
$sn->test(); // SN命名空间下的sunan类的test()方法
use SN\sunan;
$sn = new sunan();
$sn->test(); // SN命名空间下的sunan类的test()方法
use SN\sunan as ssuu;
$sn = new ssuu();
$sn->test(); // SN命名空间下的sunan类的test()方法带上同样的namespace,就可以直接简写了。
namespace SN;
include 'namespace/SN/sunan.php';
$sn = new sunan(); // 注意本文件的namespace
$sn->test(); // SN命名空间下的sunan类的test()方法导入函数
// namespace SN;
include 'namespace/SN/sunan.php';
// test(); //注意本文件的namespace,否则会报错 Call to undefined function test()
\SN\test(); // SN命名空间下的test()函数
use function SN\test;
test(); // SN命名空间下的test()函数
use function SN\test as test2;
test2(); // SN命名空间下的test()函数导入常量
// namespace SN;
include 'namespace/SN/sunan.php';
// echo AUTHOR; //注意本文件的namespace,否则会报错 Undefined constant "AUTHOR"
echo \SN\AUTHOR;
use const SN\AUTHOR;
echo AUTHOR;
use const SN\AUTHOR as aaa;
echo aaa; // 注意这里 as 的是个常量,没有 $ 符号导入变量
"导入变量"的说法是个伪命题,与常量AUTHOR所不同的是,变量$author没有在任何的命名空间里面,include()后直接就可以使用,无视命名空间。
// namespace SN; // 注意没有命名空间
include 'namespace/SN/sunan.php';
// use const SN\author; // 注意没有use
echo $author;导入trait
导入trait是比较特殊的,因为导入其它数据都是需要在先use一下,才能使用。trait因为本身的使用方式就是使用use关键字。所以,trait的导入和使用,就合并成一句话了。
// namespace SN;
include 'namespace/SN/sunan.php';
// class s {
// use sunan_trait; ////注意本文件的namespace,否则会报错 Trait "sunan_trait" not found
// }
// $s = new s();
// $s->test(); // SN命名空间下的trait里的test方法
class n {
use \SN\sunan_trait;
}
$n = new n();
$n->test(); // SN命名空间下的trait里的test方法合并导入
这里为了演示方便,复制sunan.php为sunan2.php。同时,修改命名空间为:namespace SN/demo;。文件内各种元素都做了适当的改名操作。

如果从同一个命名空间里面,导入多个同样类型的代码,还可以合并导入。
例如,低版本的代码可以这样写:
require 'namespace/SN/demo/sunan.php';
require'namespace/SN/demo/sunan2.php';
use SN\demo\sunan;
use SN\demo\sunan2 as s2;
use function SN\demo\test;
use function SN\demo\test2 as t2;
use const SN\demo\AUTHOR;
use const SN\demo\AUTHOR2 as a2;对比(php@7以后,高版本可以这么写):
require 'namespace/SN/demo/sunan.php';
require 'namespace/SN/demo/sunan2.php';
use SN\demo\{sunan, sunan2 as s2};
use function SN\demo\{test, test2 as t2};
use const SN\demo\{AUTHOR, AUTHOR2 as a2};值得注意的是:在use导入阶段,导入了错误的命名空间路径的话,并不会报错。相关文章
结束语
一个重要的结论就是:常量有命名空间,变量没有命名空间。其它的结论就是命名空间语法层面上的了。苏南大叔的更多php经验文章,请点击下面的链接查看: