namespace和use用法的疑惑

时间:2021-10-08 20:56:02
我看PHP文档里说使用use是为了解决命名空间过长的问题
比如命名空间为\a\b\c,可以用use \a\b\c 或者 use \a\b\c as myns

但是如果已经用namespace \a\b\c 引入过命名空间
那下面的代码可以直接使用该命名空间下的类

a.php:
namespace \a\b\c
class myclass(){
   public function say(){echo "hello";}
}

在b.php引用
namespace \a\b\c
require_once("a.php");
$x = new myclass();
$x->say();
这样就可以了啊,何必加一行use \a\b\c as myns

然后:
$x = new \myns\myclass();
$x->say();
这样不是多次一举了吗?
我到底是哪里理解错了呢?

3 个解决方案

#1


如果你去掉 在b.php中的 namespace \a\b\c; 将会是什么结果呢?
你怎么就一定知道 a.php 就一定声明有namespace a\b\c; 呢?

#2


命名空间的功能是给你当前文件下声明的类加一个名称前缀
比如在你的a.php文件中 myclass的名称前缀就是 \a\b\c
如果你在a.php文件中还声明了更多的类 那么他们的名称前缀就都是\a\b\c
因此 命名空间的声明是放在php文件的开头部分的 在namespace之前不能有其他的语句(但印象中好像还支持在文件中部声明命名空间的情况 记不清了)

再看你的b.php文件
它也声明了命名空间\a\b\c
因此在这个文件中声明的类也具有\a\b\c的名称前缀

当你在b文件中require了a.php文件后
程序的全局作用域下 就会定义了\a\b\c\myclass (注意: myclass类是不存在的 只有\a\b\c\myclass类声明过)
按理说 你如果想实例化\a\b\c\myclass
你的写法应该是这样:
  $x = new \a\b\c\myclass();

但为何在你的b.php文件中下面的写法也不报错呢?
  $x = new myclass();

原因是这样的
首先b.php文件的命名空间 刚好跟a.php文件是相同的  是\a\b\c
在b文件中  当这行代码
  $x = new myclass();
运行时 实际上找的是在当前命名空间(即b.php文件的命名空间)\a\b\c下的myclass
凑巧  \a\b\c\myclass这个类存在
所以在b.php文件中 并没有报错

如果!
两个文件的命名空间不同
比如a.php文件的命名空间是\a\b\c\d
那么在b.php文件中实例化的代码 将要报错

为了不报错有两种方法
第一种:
  $x = new \a\b\c\d\myclass();//使用全名

第二种
在b.php文件的开头
  use \a\b\c\d\myclass as myclass;
然后在调用处:
  $x = new myclass();


那么use的作用是什么??
use的作用就是在当前命名空间下 如果需要使用其他不同命名空间下的类时 为其他命名空间下的某个类 起一个别名
从而省略一些冗长的命名空间的输入
这个别名只在当前文件内有效


最后
命名空间有什么用??

利用命名空间 你可以在不同命名空间(即不同文件)下声明"同名"的类(注意是加引号的同名 意思是只有类的子名称相同 而命名空间不同)
消除一些别扭的命名冲突
此外 规范的命名空间定义 也非常有利于现在很多流行框架的类自动加载(这一点如果不了解 不必太过担心 慢慢就会了解)



#3


引用 2 楼 robinjackson 的回复:
命名空间的功能是给你当前文件下声明的类加一个名称前缀
比如在你的a.php文件中 myclass的名称前缀就是 \a\b\c
如果你在a.php文件中还声明了更多的类 那么他们的名称前缀就都是\a\b\c
因此 命名空间的声明是放在php文件的开头部分的 在namespace之前不能有其他的语句(但印象中好像还支持在文件中部声明命名空间的情况 记不清了)

再看你的b.php文件
它也声明了命名空间\a\b\c
因此在这个文件中声明的类也具有\a\b\c的名称前缀

当你在b文件中require了a.php文件后
程序的全局作用域下 就会定义了\a\b\c\myclass (注意: myclass类是不存在的 只有\a\b\c\myclass类声明过)
按理说 你如果想实例化\a\b\c\myclass
你的写法应该是这样:
  $x = new \a\b\c\myclass();

但为何在你的b.php文件中下面的写法也不报错呢?
  $x = new myclass();

原因是这样的
首先b.php文件的命名空间 刚好跟a.php文件是相同的  是\a\b\c
在b文件中  当这行代码
  $x = new myclass();
运行时 实际上找的是在当前命名空间(即b.php文件的命名空间)\a\b\c下的myclass
凑巧  \a\b\c\myclass这个类存在
所以在b.php文件中 并没有报错

如果!
两个文件的命名空间不同
比如a.php文件的命名空间是\a\b\c\d
那么在b.php文件中实例化的代码 将要报错

为了不报错有两种方法
第一种:
  $x = new \a\b\c\d\myclass();//使用全名

第二种
在b.php文件的开头
  use \a\b\c\d\myclass as myclass;
然后在调用处:
  $x = new myclass();


那么use的作用是什么??
use的作用就是在当前命名空间下 如果需要使用其他不同命名空间下的类时 为其他命名空间下的某个类 起一个别名
从而省略一些冗长的命名空间的输入
这个别名只在当前文件内有效


最后
命名空间有什么用??

利用命名空间 你可以在不同命名空间(即不同文件)下声明"同名"的类(注意是加引号的同名 意思是只有类的子名称相同 而命名空间不同)
消除一些别扭的命名冲突
此外 规范的命名空间定义 也非常有利于现在很多流行框架的类自动加载(这一点如果不了解 不必太过担心 慢慢就会了解)


感谢!

#1


如果你去掉 在b.php中的 namespace \a\b\c; 将会是什么结果呢?
你怎么就一定知道 a.php 就一定声明有namespace a\b\c; 呢?

#2


命名空间的功能是给你当前文件下声明的类加一个名称前缀
比如在你的a.php文件中 myclass的名称前缀就是 \a\b\c
如果你在a.php文件中还声明了更多的类 那么他们的名称前缀就都是\a\b\c
因此 命名空间的声明是放在php文件的开头部分的 在namespace之前不能有其他的语句(但印象中好像还支持在文件中部声明命名空间的情况 记不清了)

再看你的b.php文件
它也声明了命名空间\a\b\c
因此在这个文件中声明的类也具有\a\b\c的名称前缀

当你在b文件中require了a.php文件后
程序的全局作用域下 就会定义了\a\b\c\myclass (注意: myclass类是不存在的 只有\a\b\c\myclass类声明过)
按理说 你如果想实例化\a\b\c\myclass
你的写法应该是这样:
  $x = new \a\b\c\myclass();

但为何在你的b.php文件中下面的写法也不报错呢?
  $x = new myclass();

原因是这样的
首先b.php文件的命名空间 刚好跟a.php文件是相同的  是\a\b\c
在b文件中  当这行代码
  $x = new myclass();
运行时 实际上找的是在当前命名空间(即b.php文件的命名空间)\a\b\c下的myclass
凑巧  \a\b\c\myclass这个类存在
所以在b.php文件中 并没有报错

如果!
两个文件的命名空间不同
比如a.php文件的命名空间是\a\b\c\d
那么在b.php文件中实例化的代码 将要报错

为了不报错有两种方法
第一种:
  $x = new \a\b\c\d\myclass();//使用全名

第二种
在b.php文件的开头
  use \a\b\c\d\myclass as myclass;
然后在调用处:
  $x = new myclass();


那么use的作用是什么??
use的作用就是在当前命名空间下 如果需要使用其他不同命名空间下的类时 为其他命名空间下的某个类 起一个别名
从而省略一些冗长的命名空间的输入
这个别名只在当前文件内有效


最后
命名空间有什么用??

利用命名空间 你可以在不同命名空间(即不同文件)下声明"同名"的类(注意是加引号的同名 意思是只有类的子名称相同 而命名空间不同)
消除一些别扭的命名冲突
此外 规范的命名空间定义 也非常有利于现在很多流行框架的类自动加载(这一点如果不了解 不必太过担心 慢慢就会了解)



#3


引用 2 楼 robinjackson 的回复:
命名空间的功能是给你当前文件下声明的类加一个名称前缀
比如在你的a.php文件中 myclass的名称前缀就是 \a\b\c
如果你在a.php文件中还声明了更多的类 那么他们的名称前缀就都是\a\b\c
因此 命名空间的声明是放在php文件的开头部分的 在namespace之前不能有其他的语句(但印象中好像还支持在文件中部声明命名空间的情况 记不清了)

再看你的b.php文件
它也声明了命名空间\a\b\c
因此在这个文件中声明的类也具有\a\b\c的名称前缀

当你在b文件中require了a.php文件后
程序的全局作用域下 就会定义了\a\b\c\myclass (注意: myclass类是不存在的 只有\a\b\c\myclass类声明过)
按理说 你如果想实例化\a\b\c\myclass
你的写法应该是这样:
  $x = new \a\b\c\myclass();

但为何在你的b.php文件中下面的写法也不报错呢?
  $x = new myclass();

原因是这样的
首先b.php文件的命名空间 刚好跟a.php文件是相同的  是\a\b\c
在b文件中  当这行代码
  $x = new myclass();
运行时 实际上找的是在当前命名空间(即b.php文件的命名空间)\a\b\c下的myclass
凑巧  \a\b\c\myclass这个类存在
所以在b.php文件中 并没有报错

如果!
两个文件的命名空间不同
比如a.php文件的命名空间是\a\b\c\d
那么在b.php文件中实例化的代码 将要报错

为了不报错有两种方法
第一种:
  $x = new \a\b\c\d\myclass();//使用全名

第二种
在b.php文件的开头
  use \a\b\c\d\myclass as myclass;
然后在调用处:
  $x = new myclass();


那么use的作用是什么??
use的作用就是在当前命名空间下 如果需要使用其他不同命名空间下的类时 为其他命名空间下的某个类 起一个别名
从而省略一些冗长的命名空间的输入
这个别名只在当前文件内有效


最后
命名空间有什么用??

利用命名空间 你可以在不同命名空间(即不同文件)下声明"同名"的类(注意是加引号的同名 意思是只有类的子名称相同 而命名空间不同)
消除一些别扭的命名冲突
此外 规范的命名空间定义 也非常有利于现在很多流行框架的类自动加载(这一点如果不了解 不必太过担心 慢慢就会了解)


感谢!