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
经验文章,请点击下面的链接查看:
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。