我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

本文将要总结一下php中命名空间的使用方法,文章属于总结性质的,高手请飘过。命令空间可以更好地区分代码的归属,对代码进行分门别类的放置。并且不同命名空间里面,也可以有同名的变量或者类及其它。

苏南大叔:php如何通过use关键字导入命名空间里的函数变量以及类? - php命名空间
php如何通过use关键字导入命名空间里的函数变量以及类?(图3-1)

苏南大叔的“程序如此灵动”博客,记录苏南大叔的编程感想和感悟。本文测试环境:win10nginx@1.15.11php@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。当然,不这么命名也是可以运行的,这里仅仅是个最佳实践的建议。

苏南大叔:php如何通过use关键字导入命名空间里的函数变量以及类? - 命名空间定义
php如何通过use关键字导入命名空间里的函数变量以及类?(图3-2)

加载类库文件

对于本文的代码来说,直接include或者require是更好的选择。关于includerequire的区别,可以参考:

可以直接这样加载类库:

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.phpsunan2.php。同时,修改命名空间为:namespace SN/demo;。文件内各种元素都做了适当的改名操作。

苏南大叔:php如何通过use关键字导入命名空间里的函数变量以及类? - 命名空间的使用
php如何通过use关键字导入命名空间里的函数变量以及类?(图3-3)

如果从同一个命名空间里面,导入多个同样类型的代码,还可以合并导入。

例如,低版本的代码可以这样写:

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经验文章,请点击下面的链接查看:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   php