1. 命名空间的两种写法
<?php
// 命名空间:方式一
// namespace ns1;
// namespace ns2;
// namespace ns3;
// namespace ; 会报错
// 此种声明方式,不能在同脚本中声明匿名空间(全局空间)
namespace ns1;
interface iDemo
{
public function show();
}
class Demo implements iDemo
{
public $name = '果冻';
public function show ()
{
return $this->name;
}
}
$obj = new Demo();
echo $obj->show(),'<hr>';
// 普通写法
// function ff ($obj)
// 如果要声明函数中参数的类型,如下:
// 1. 使用类名 Demo
// function ff (Demo $obj)
// 2. 使用接口名 iDemo,在有接口的的情况下,最好这样使用
function ff (iDemo $obj)
{
echo $obj->show(),'<hr>';
}
ff($obj);
// 在命名空间中访问其他命名空间中的成员
namespace ns2;
// \ : 表示全局空间
$obj1 = new \ns1\Demo();
echo $obj1->show(),'<hr>';
\ns1\ff($obj1);
<?php
// 命名空间:方式二
/*
namespace ns1
{
//...
}
namespace ns2
{
//...
}
namespace
{
//...
}
*/
// 这样的方式就可以在同脚本中声明全局空间(匿名空间)
namespace ns1
{
class Demo
{
public static function show ()
{
return __METHOD__;
}
}
}
namespace ns2
{
// 1. 访问ns1中的show()方法
echo \ns1\Demo::show(),'<hr>';
// 2. 查看当前类全名
echo \ns1\Demo::class,'<hr>';
}
// 全局空间中访问时,可以省略第一个 \
namespace
{
// 1. 访问ns1中的show()方法
echo ns1\Demo::show(),'<hr>';
// 2. 查看当前类全名
echo ns1\Demo::class,'<hr>';
// 因为有了全局空间, 那么全局成员的声明就不应该放在全局,而应该放在空间中
// 因此,全局空间应该主要写对全局对象的调用
}
2. 命名空间类名的引用
<?php
// 命名空间类名的引用
namespace ns1;
class Demo{}
namespace ns2;
class Demo{}
namespace ns3;
// 1. 限定名称:不从根开始但有路径(省略和当前空间名称相当的部分)
echo \ns3\sub\Demo::class,'<hr>';
echo sub\Demo::class,'<hr>';
namespace ns3\sub;
class Demo{}
// 2. 完全限定名称:从根开始且有路径
echo \ns1\Demo::class,'<hr>';
// 3. 非限定名称:没有根也没有路径(当前空间)
echo Demo::class;
3. 命名空间的别名
<?php
// 命名空间的别名
namespace ns1;
class Demo{}
class Test{}
namespace ns2;
class Demo{}
// 1. 空间级别名
echo \ns1\Demo::class,'<hr>';
use \ns1 as n;
echo n\Demo::class,'<hr>';
// 2. 类级别名
use \ns1\Demo as d;
echo d::class,'<hr>';
// 3. 简写:前提是当前空间中不能有同名的类
// use \ns1\Test as Test;
use \ns1\Test;
echo Test::class,'<hr>';
// class Test{} 若有同名的类会报错
// 4. 若在当前空间,可一省略 \
use ns2\Demo as dd;
echo dd::class;
4. 访问类和内置函数的区别
<?php
// 示例一:
namespace ns1
{
function print_r ($arr)
{
return '我在打印 : '.implode(',',$arr);
}
// 1. 访问类时,都要加 \
echo \Arr::NAME,'<hr>';
// 2. 访问函数时
// 2.1 若不加 \ ,访问到当前空间的自定义函数
echo print_r(\Arr::$arr);
echo '<hr>';
// 2.2 若加 \ ,此时到了全局空间中查找,调用了PHP内置函数
\print_r(\Arr::$arr);
echo '<hr>';
}
namespace
{
class Arr{
const NAME = '果冻';
public static $arr = ['aa','bb','cc'];
}
}
// 示例二:
namespace ns2
{
function var_dump($name)
{
echo '我的名字叫 : ' . $name;
}
var_dump(\Arr::NAME);
echo '<hr>';
\var_dump(\Arr::NAME);
}
5. 类的自动加载
<?php
// 类的自动加载
try{
spl_autoload_register(function($class){
$path = str_replace('\\',DIRECTORY_SEPARATOR,$class);
$file = __DIR__.DIRECTORY_SEPARATOR.$path.'.php';
if (!(is_file($file) && file_exists($file)))
throw new \Exception('不是文件名文件不存在');
require $file;
});
}catch(Exception $e){
die($e->getMessage());
}
echo inc\lib\test1::NAME,'<hr>';
echo inc\lib\test1::show(),'<hr>';
echo inc\lib\test2::class,'<hr>';
echo inc\lib\test3::class,'<hr>';
<?php
// 1. 当前类的命名空间与当前类的文件路径对应起来
namespace inc\lib;
// 2. 类名必须与当前类文件名称相同
class test1 {
const NAME = '果冻';
public static function show ()
{
return __METHOD__;
}
}
6. 总结