请教下php中namespace和use的用法及异同?

发布于 2022-09-11 21:19:18 字数 1103 浏览 13 评论 0

目前的理解和疑惑如下:

  1. namespace的作用: 命名空间为了解决重名问题, 比如同事A.php里有class A, 而同事B事先不知道A会使用什么类名, 可能会重复. 那么命名空间可以解决这问题. namespace nsa里有class A, class A只能在当前命名空间下生效.
  2. use的作用就是在当前命名空间下使用其它命名空间下的类, 比如在(index.php里的类Index)app\admin\controller命名空间里使用 另一个(Db.php里有Db类)命名空间use think\Db

    • 只知道这么用, 但有些东西讲不清楚.
    • use think\Db = Db类的命名空间think + 类名Db ? 框架里是这样用的, (这里的命名空间think经过tp的修改和简化)
    • 再推而广之, 如果想在A.php, namespace nsa, class A 调用 B.php, namespace nsb, class B, 就是use nsb/B? 需要先在A.php用include或require引入B.php吗?
  3. 在网上找了很多人写的博客, 但是我发现, 因为这涉及到file_name, namespace_name, class_name, 甚至path_name和directory_name. 一些人在写文章时, 这几个名字都取得稀巴烂像a, b, aa, bb, ab,导致描述也混乱, 很容易产生歧义. 所以先事先约定以下名称

    • A.php
    • namespace nsa (要用多层级就namespace n/s/a)
    • class A
    • B.php,
    • namespace nsb (要用多层级就namespace m/t/b)
    • class B
  4. 现在简单的框架功能练习没什么问题, 但是看源代码和练习复杂功能的代码时, 面向对象和命名空间认识太浅, 导致理解有些困难. 还请大家帮忙分享下自己的经验.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

Smile简单爱 2022-09-18 21:19:18

autoload(5.1加入) 和 namespace(5.3加入),可见这俩并非 PHP 语言不可或缺,而是为了针对特定的问题所引入的一种解决方案。

0.先说 symbol table,这是根本。PHP 解释器在执行的时候,内部维护着的一个表,类似于:

|--------+----------+----------------|
| symbol | type     | memory address |
|--------+----------+----------------|
| Name1  | Class    |     0x00DFF1A8 |
| Name2  | Class    |     0x00DFF1B8 |
| Name1  | Function |     0x00DFF1C8 |
| Name1  | Variable |     0x00DFF1D8 |
| ...    | ...      |            ... |

类名、函数名、变量名这些都是 symbol
PHP 解释器在执行(载入)每一个 .php 文件时,遇到一个 类定义、函数定义、变量定义 就往 symbol table 添入一行(这也是为什么 PHP 解释器能够发现重复定义)。在接下来的执行中,PHP 解释器遇到 "实例化一个类" 的代码,就查一下 symbol tabletype Class 下有没有这个 类名,如果没有,则报错"类未定义"。

1.有了上面的铺垫,按照加入PHP的先后顺序,先说 autoload。上面 "实例化一个类" 的这个流程,其实是有改进余地的,在其查 symbol table 没有找到 类名 之后,可以插入一个步骤,这个步骤负责从文件系统找到 类定义所在的.php文件 并当即载入,这个步骤,就叫 autoload
autoload 内的匹配规则是需要你动手来写的,最常见的做法是 类名类定义所在.php文件名 两者取同名:

spl_autoload_register(function ($class_name) {
    include $class_name . '.php';
});

2.在 PHP 中加入 namespace 后,其 symbol table 类似于:

|-----------+--------+----------+----------------|
| namespace | symbol | type     | memory address |
|-----------+--------+----------+----------------|
| \         | Name1  | Class    |     0x00DFF1A8 |
| \         | Name2  | Class    |     0x00DFF1B8 |
| \         | Name1  | Function |     0x00DFF1C8 |
| \         | Name1  | Variable |     0x00DFF1D8 |
| ...       | ...    | ...      |            ... |

PHP 解释器在查 symbol table 时加入了对 namespace 的判断
假设你给自己所有的 .php 的首行放

namespace SF\jinz;

PHP 解释器在执行你的代码后,其 symbol table 类似于:

|-----------+--------+----------+----------------|
| namespace | symbol | type     | memory address |
|-----------+--------+----------+----------------|
| \         | Name1  | Class    |     0x00DFF1A8 |
| \         | Name2  | Class    |     0x00DFF1B8 |
| \         | Name1  | Function |     0x00DFF1C8 |
| \         | Name1  | Variable |     0x00DFF1D8 |
| ...       | ...    | ...      |            ... |
| SF\jinz   | Name1  | Class    |     0x00DFF2A8 |
| SF\jinz   | Name2  | Class    |     0x00DFF2B8 |
| SF\jinz   | Name1  | Function |     0x00DFF2C8 |
| SF\jinz   | Name1  | Variable |     0x00DFF2D8 |
| ...       | ...    | ...      |            ... |

别人在实例化 你的代码中的类 的时候,须这么写:

$obj = new SF\jinz\Name1();

看看上面起分隔作用的这个 \,眼不眼熟?有没有让你联想到 文件路径 中起分隔作用的 /?那么 autoload 中的匹配规则你有想法了吗?
想细究的话可以看 Composer 的实现,ThinkPHP5 的话你可以看 ProjectPath/thinkphp/library/Loader.php。

3.use Some\NS; 不是必须的,你可以先试着不用 use Some\NS;,等你敲累了后再自行决定用不用 :)。

梦魇绽荼蘼 2022-09-18 21:19:18
  1. php 命名空间之间应该用反斜线,而不是斜线

如果想在A.php, namespace nsa, class A 调用 B.php, namespace nsb, class B, 就是use nsb/B? 需要先在A.php用include或require引入B.php吗?

使用了命名空间,一般会使用自动加载,当然自动加载的本质是不需要你写 require/include,只是自动加载的方法会帮你 require.
如果没有使用自动加载,你当然是需要 require 的。

其它,没看懂你还有什么问题,推荐:https://www.php.net/manual/zh... 官方手册,阅读后有什么问题,但针对手册中的描述来提问。

两人的回忆 2022-09-18 21:19:18
  1. 命名空间不只是为了解决重名问题,主要是可以将代码归类,便于维护和扩展
  2. 按照PSR规范定义的命名空间,使用composer时可以自动加载(不用手动require类文件)
  3. namespace定义命名空间,user导入类
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文