编程技术分享平台

网站首页 > 技术教程 正文

namespace命名空间学习(namespace命名规则)

xnh888 2024-10-21 13:11:45 技术教程 19 ℃ 0 评论

1. namespace是什么?

命名空间是namespace是翻译,作用是防止类名或函数名重复,命名重复会导致报错。以前没有命名空间的时候只能人为去防止重复,但项目上了一定规模难以避免这个问题,因此,在php5.3版本推出了namespace。

2. namespace的简单使用

使用比较简单,下面举个例子
1. 先是不用namespace的方式
Foo.php

<?php
class Test {
    public static function index(){
        echo 'hello world 1';
    }
}

Fee.php

<?php
class Test{
    public static function index(){
        echo 'hello world 2';
    }
}

然后在index.php分别require这两个文件

<?php
require './Foo.php';
require './Fee.php';
Test::index();
Test::index();

由于foo.php和fee.php里的类名和方法名都一样,所以在index.php里系统就无法区分到底是调用的那个类,这时运行就会报错

PHP Fatal error:  Cannot declare class Test, because the name is already in use in C:\Users\53101\Desktop\study\php\namespace_study\Foo.php on line 3

2. 下面是加入namespace后的样子
Foo.php

<?php
namespace Foo;
class Test {
    public static function index(){
        echo 'hello world 1';
    }
}

Fee.php

<?php
namespace Fee;
class Test{
    public static function index(){
        echo 'hello world 2';
    }
}

然后在index.php分别require这两个文件

<?php
require './Foo.php';
require './Fee.php';
Foo\Test::index();
Fee\Test::index();

运行获得了想要结果

hello word 1hello word 2

总结:事实上命名空间就是用来区分调用的类或方法来自哪里,类似于java或python里的包的概念,但是功能上还是比较弱,无法帮你自动加载调用的文件,要配合自动加载autoload才能实现更强的功能。

3. 详细使用

1. namespace的定义

  1. 通过namespace关键字来定义
<?php
namespace App;
class Test{//...dosomething}
  1. 使用花括号定义,没有名字的命名空间相当于全局命名空间,相当于不带命名空间,不使用命名空间默认就是放在全局命名空间下的,但是这种不使用命名空间的代码和带命名空间代码要放在一个文件就必须放在没有名字的命名空间下,必须使用花括号定义
<?php
namespace App{
    class Test{//...dosomething}
}
namespace {
    class Test{//...dosomething}
}
  1. namespace前面只允许declare 语句,不能有其它任何代码或空格
<?php
$a = '';//报错
namespace App;

有一个容易忽略的点就是<?php前面也不能有空格,必须顶格写,不然也会报错

 <?php//前面有空格,报错
namespace App;

2. 书写规范

  1. 虽然定义namespace可以随意定义,但是根据PSR-0的要求,必须有一个上级Vendor Name,一般是使用文件夹名,文件夹路径就是namespace的路径,这样方便定位文件。
  2. 命名规范跟PHP变量基本一样,什么首字母不能是数字啊。只能有数字,字母,下划线_组成,也不能是系统保留关键字等。但是’\’是可以使用的,因为namespace是用’\’来分割目录的。

3. namespace的访问

  1. 使用全路径访问Vendor\namespce\class这样
    Foo.php
<?php
namespace App;
class Foo {
    public static function index()
    {
        echo 'hello word 1';
    }
}

Fee.php

<?php
namespace App;
class Fee {
    public static function index()
    {
        echo 'hello word 2';
    }
}

index.php

<?php
require './Fee.php';
require './Foo.php';
App\Foo::index();//静态方法直接调用
$fee = new App\Fee();//非静态方法要先new再调用
$fee->index();
  1. 非限定名称,或不包含前缀的类名称。使用use关键字引入,遇到引入class重复的可以使用as 关键字定义别名。
<?php
require './Fee.php';
require './Foo.php';
use App\Fee;
use App\Foo as Alias;
Alias::index();//静态方法直接调用
$fee = new Fee();//非静态方法要先new再调用
$fee->index();
  1. 使用完全限定名称,就是使用全路径同时最前面加\,这样就只会在对应路径找对应class或方法
<?php
require './Fee.php';
require './Foo.php';
\App\Foo::index();//静态方法直接调用
$fee = new \App\Fee();//非静态方法要先new再调用
$fee->index();
echo \strlen('abc');//前面加\的方式可以用于任何内置方法,不加\默认是在当前命名空间下找对应class或方法

总结:访问有三种方式,要么用use关键字引入,遇到重复的名称用as定义别名,要么用Vendor\namespce\class这种方式,会到对应路径寻找,但路径指定不全的话优先在当前命名空间下寻找。要么在最前面加上\,就只会到指定路径寻找。

4. namespace关键字和NAMESPACE常量

  1. namespace 可用来显式访问当前命名空间或子命名空间中的元素。它等价于类中的 self 操作符。
<?php
namespace App;
class Foo {
    public static function index()
    {
        echo 'hello word 1';
    }
}
namespace\Foo::index();
//输出 hello word 1;
  1. NAMESPACE常量
<?php
namespace App;
class Foo {
    public static function index()
    {
        echo __NAMESPACE__;//可用于动态创建类
    }
}
namespace\Foo::index();
//输出 App;

总结:

namespace主要解决了两个问题

  1. 用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突。
  2. 为很长的标识符名称(通常是为了缓解第一类问题而定义的)创建一个别名(或简短)的名称,提高源代码的可读性。

定义方式有两种

  1. namespace关键字在文件首行,前面不能有任何代码,只能有declare。
  2. namespace花括号定义,可以使用匿名定义,等同于全局命名空间

访问方式有三种

  1. use关键字引入然后使用引入的名称调用,遇到引入名称一样使用as定义别名
  2. 使用限定名称,例如App\Foo::index(),会在当前命名空间下找这个路径的class,这里的App不一定是根命名空间
  3. 使用完全限定名称,例如\App\Foo::index(),这样只会在给定的路径下寻找class,这里的App一定是根命名空间

一些特性

  1. namespace可用于访问当前命名空间和子命名空间中的元素,等价于self
  2. __NAMESPACE__常量指向当前命名空间名称,是字符串,可以用于动态创建class

参考资料:
https://www.runoob.com/php/php-namespace.html
https://www.zybuluo.com/phper/note/65479

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表