青风百里

PHP 命名空间
一.什么是命名空间命名空间是一种封装事物的方法,例如函数,类,方法也是封装事物的方法命名空间的作用:用来解决类名或...
扫描右侧二维码阅读全文
28
2018/09

PHP 命名空间

一.什么是命名空间

  • 命名空间是一种封装事物的方法,例如函数,类,方法也是封装事物的方法
  • 命名空间的作用:用来解决类名或者应用程序名冲突问题

二.定义命名空间的要求

  • 使用namespace关键字来声明一个命名空间,不区分大小写
  • 命名方式使用"大驼峰"
  • 所有代码都可以存在于命名空间中,但是,只有三种代码受到空间影响:类,常量(const),函数,即除了类,常量(const),函数之外的代码,都是全局代码
  • 全局代码所在的空间称为"根空间"
  • define定义的常量不受空间影响
  • 声明命名空间的语句,必须是PHP脚本的第一行代码
  • 在项目中,要求命名空间要与真是的文件件目录一致
  • 看一段代码
<?php
// libs目录下的Student.php
//声明一个命名空间(文件夹)
namespace Libs;
//定义一个类
class Student{
    public function showInfo(){
        echo "我是一个学生";
    }
}
//定义一个函数
function test(){
    echo "测试函数";
}
//定义一个常量
const TITLE = "标题";
//定义一个变量
$a = 100;
<?php
//包含文件
require "./libs/Student.php";
$stuObj = new Libs\Student();
$stuObj->showInfo();
echo "<br>";
Libs\test();
echo "<br>";
echo Libs\TITLE;
echo "<br>";
echo $a;

三.子命名空间

  • 看代码
<?php
// libs目录下的Student.php
//声明一个子命名空间,但是是虚拟的
namespace Libs\Home;
//定义一个类
class Student{
    public function showInfo(){
        echo "我是一个学生";
    }
}
//定义一个函数
function test(){
    echo "测试函数";
}
//定义一个常量
const TITLE = "标题";
//定义一个变量
$a = 100;
<?php
//包含文件
require "./libs/Student.php";
$stuObj = new Libs\Home\Student();
$stuObj->showInfo();
echo "<br>";
Libs\Home\test();
echo "<br>";
echo Libs\Home\TITLE;
echo "<br>";
echo $a;

四.声明多个命名空间

  • 不建议在同一个脚本中声明多个命名空间
<?php
// libs目录下的Student.php
//声明一个命名空间
namespace Libs\Home;
//定义一个类
class Student{
    public function showInfo(){
        echo "我是孙悟空";
    }
}
namespace Libs\Admin;
class Student{
    public function showInfo(){
        echo "我是沙僧";
    }
}
<?php
//包含文件
require "./libs/Student.php";
$stuObj1 = new Libs\Home\Student();
$stuObj1->showInfo();
echo "<br>";
$stuObj2 = new Libs\Admin\Student();
$stuObj2->showInfo();

  • 上面的代码也可以使用大括号写法,如下
<?php
// libs目录下的Student.php
//声明一个命名空间
namespace Libs\Home {
//定义一个类
    class Student
    {
        public function showInfo()
        {
            echo "我是孙悟空";
        }
    }
}
namespace Libs\Admin {
    class Student
    {
        public function showInfo()
        {
            echo "我是沙僧";
        }
    }
}

五.匿名命名空间

  • 在使用了大括号写法,声明了多个命名空间的时候,如果要写全局代码,就需要声明一个匿名空间
  • 匿名空间就相当于是根空间
  • 看代码
<?php
// libs目录下的Student.php
//声明一个命名空间
namespace Libs\Home {
//定义一个类
    class Student{
        public function showInfo(){
            echo "我是孙悟空";
        }
    }
}
namespace Libs\Admin {
    class Student{
        public function showInfo(){
            echo "我是沙僧";
        }
    }
}
namespace {
    class Teacher{
        public function showInfo(){
            echo "我是老师";
        }
    }
}
<?php
//包含文件
require "./libs/Student.php";
$stuObj1 = new Libs\Home\Student();
$stuObj1->showInfo();
echo "<br>";
$stuObj2 = new Libs\Admin\Student();
$stuObj2->showInfo();
echo "<br>";
$teaObj = new Teacher();
$teaObj->showInfo();

六.三种限定

<?php
namespace app\admin;
const SITE_NAME = '青风百里的博客';

//1.非限定名称:即省略空间名称,使用默认或者当前的空间名称(相当于访问当前文件夹下的东西)
echo SITE_NAME.'<br><hr>';

//2.限定名称:前面必须添加命名空间才可以访问,通常用于子空间(相当于访问当前文件夹下的子文件夹里的东西)
namespace app\admin\user;
const SITE_NAME = '青风百里的博客-PHP';

namespace app\admin;
//要使用限定名称来访问,须跳出当前空间,切换到父空间,才能看到效果
echo user\SITE_NAME.'<br><hr>';

//3.完全限定名称:从全局空间的开始(相当于绝对路径)
//访问app\admin中的常量
echo \app\admin\SITE_NAME.'<br><hr>';
//上面这句也可以写成echo namespace\SITE_NAME.'<br><hr>';此处的namespace指代\app\admin,相当于self

//访问app\admin中的常量
echo \app\admin\user\SITE_NAME.'<br><hr>';

七.__NAMESPACE__ 魔术常量

<?php
namespace app\admin;
class Student{
    public function __construct(){
        echo "我是一个学生";
    }
}

$className = __NAMESPACE__."\Student";
$stuObj = new $className;

八.导入与别名

  • 导入的目的是为了方便书写
  • 函数和常量不能导入,只能导入类,但是php5.6以后也支持导入常量和函数
  • 可以使用use导入空间中的类
  • 可以使用use导入空间
  • 当导入了两个不同空间中同名的类的时候,可以使用as关键字取个别名
  • 当然也可以给空间取个别名
  • 以下介绍四种情况

只导入空间名

<?php
// libs目录下的Student.php
//声明一个命名空间
namespace Libs\Home\Controller {
//定义一个类
    class Student{
        public function __construct(){
            echo "我是孙悟空";
        }
    }
}
<?php
require "./libs/Student.php";

use Libs\Home\Controller;//此处也可以写绝对路径(即完全限定名称)use \Libs\Home\Controller;但是本例中App.php默认就在根空间下,所以这里的完全限定名称(use \Libs\Home\Controller;)与限定名称(use Libs\Home\Controller;)效果是一样的,下同
$stuObj = new Controller\Student();//此时在使用Student类的时候,默认的空间名就是Controller

导入空间名并取别名

  • 其他代码不变,只是App.php代码改变了,如下,结果不变
<?php
require "./libs/Student.php";

use Libs\Home\Controller as Abc;
$stuObj = new Abc\Student();

导入类

  • 默认的类名就是Student
  • 其他代码不变,只改变App.php中的代码,结果不变
<?php
require "./libs/Student.php";

use \Libs\Home\Controller\Student;
$stuObj = new Student();

导入类并取别名

  • 在有两个同名的类的时候使用,例如:App.php中已经有Student类了,再导入一个Student类就会发生冲突
  • 其他代码不变,只改变App.php中的代码,结果不变
<?php
require "./libs/Student.php";

use \Libs\Home\Controller\Student as Abc;
$stuObj = new Abc();

九.在项目中使用命名空间

<?php
// 真实文件路径./frame/libs/Db.class.php
//声明一个命名空间,与真实文件路径一致
namespace Frame\Libs;
//最终的Db类
final class Db{
    public function __construct(){
        echo "Db类";
    }
}
<?php
//真实文件路径./app.php
spl_autoload_register(function($className){
    //类名是Frame\Libs\Db
    //真实的文件路径是./frame/libs/Db.class.php
    //构建真实文件路径
    $filename = "./".str_replace('\\', '/', $className).".class.php";
    if (file_exists($filename)) require("$filename");
});

$db = new Frame\Libs\Db();//此处需要结合命名空间的规则知识点

Last modification:September 29th, 2018 at 02:41 pm

Leave a Comment