php 中namespace、use 、require 和自动加载

image.png

namespace 防止重名

首先,namespace就是为了解决项目中类的重名问题。 了解了目的后,就可以知道namespace的影响就 仅仅是限制在和类名相关的操作上。

  • namespace后命名的定义不区分大小写。这就是要求我们在定义命名空间的时候要注意别定义了相同命名空间。以下就是等效的命名空间
namespace one;
namespace One;
namespace ONE;
  • 和Linux文件目录不同的事命名空间采用的事反斜杠 ""。
  • 没有定义命名空间,就默认理解为使用顶级命名空间。在命名空间中的定义中,针对没有命名空间的php文件,会默认虚拟一个顶层命名空间 \ 。
  • 如果一个类在定义的时候指定了命名空间,new类时,一定要带上指定的命名空间。 这个意思是如果这个类指定了命名空间,那么相当于在整个项目中这个类必须以命名空间的方式被声明和使用。 不能单独只依靠类名来调用了。 可以理解成名称替换,这个替换就是命名空间设计的初衷,防止类名重复。
//1.php   
namespace one;
class Person{
    function __construct(){
            echo 'I am one!';
        }
}
//name.php
require_once './1.php';
new \one\Person(); //输出 I am one!;使用person需要这样来声明,在项目中person的名字被固定成这个样子。
  • 在使用命名命名空间的时候,如果直接new 一个类,PHP解释器会默认尝试在当前命名空间中寻找这个类,如果能找到就new成功,如果失败就抛出错误
//1.php   
namespace one;
class Person{
   function __construct(){
           echo 'I am one!';
       }
}
//name.php
namespace test;
require_once './1.php';
new \one\Person(); //成功,输出 I am one!;
new \Person(); //代码报错:Fatal error: Class 'Person' not found
new Person(); //代码报错:Fatal error:  Class 'test\Person' not found

注意后另个错误,第一个错误解释器会去顶层命名空间寻找,显然不能找到抛出错误;第二个会从默认的test命名空间中寻找。

对于同一上面的name。php ,如果去掉了namespace test;这段会怎么样呢。结果如下,可以看到此时没有显示声明命名空间,那么久开始选用默认顶层命名空间,所以后面连个的结果是一样的。

//name.php
namespace test;
require_once './1.php';
new \one\Person(); //成功,输出 I am one!;
new \Person(); //代码报错:Fatal error: Class 'Person' not found
new Person(); //代码报错:Fatal error:  Class 'Person' not found
  • 一个php文件中可以存在多个命名空间,第一个命名空间前不能有任何代码。(这个不常用,不建议这样编码)

总结一下:对于namespace 的掌握就是记住以下几点:

一个目的: 解决重名问题
两个默认: 默认顶层虚拟;默认当前空间寻找;
一个符号:  "\"

use 简写类名

use 关键字是用来导入命名空间的,或者说就是偷懒简写类名的功能,他并不能加载文件,加载还要靠其他机制。 从上面的namespace的介绍中,我们已经可以避免重名这个现象了。但是人们总是偷懒的,每次声明一个类的时候还需要写那么长的命名空间是不能忍受的,隐藏use 和as 就登场了

use one;
require_once './1.php';
new Person();

psr-2的相关规定 :

命名空间(namespace)的声明后面必须有一行空行。
所有的导入(use)声明必须放在命名空间(namespace)声明的下面。
一句声明中,必须只有一个导入(use)关键字。
在导入(use)声明代码块后面必须有一行空行。

require 导入文件

通过上面的介绍,我们了解到了类的名称在使用时候的方法。但是无论namespace 还是use 都不能真的找到这个php文件把代码引入,可以看上面的每段代码都有require 的使用。下面看一个例子

1.php

<?php
    $b = require('ext.php');
    echo "---------\r\n";

    echo $_SERVER['SCRIPT_FILENAME'];

ext.php

<?php

echo $_SERVER['SCRIPT_FILENAME'];
            echo 'I am ext!';

输出

./1.php
I am ext!
---------
./1.php
  • 从这里可以看到require导入后,代码识别的脚本是导入后的。从这个角度也可以部分理解require是对导入文件直接替换。
  • 但是当有命名空间就不一样了。并不是简单替换,而是引入保存了命名空间的属性。

手动引入会使得开发者崩溃的,这时候命名空间和导入就可以结合起来。

psr-4

在说啥是PSR-[0-4]规范的之前,我觉得我们有必要说下它的发明者和规范者:PHP-FIG,它的网站是:www.php-fig.org。就是这个联盟组织发明和创造了PSR-[0-4]规范,膜拜吧,屌丝们!

FIG 是 Framework Interoperability Group(框架可互用性小组)的缩写,由几位开源框架的开发者成立于 2009 年,从那开始也选取了很多其他成员进来,虽然不是 “官方” 组织,但也代表了社区中不小的一块。组织的目的在于:以最低程度的限制,来统一各个项目的编码规范,避免各家自行发展的风格阻碍了程序设计师开发的困扰,于是大伙发明和总结了PSR,PSR是Proposing a Standards Recommendation(提出标准建议)的缩写,截止到目前为止,总共有5套PSR规范,分别是:

PSR-0 (Autoloading Standard) 自动加载标准 
PSR-1 (Basic Coding Standard) 基础编码标准 
PSR-2 (Coding Style Guide) 编码风格向导 
PSR-3 (Logger Interface) 日志接口 
PSR-4 (Improved Autoloading) 自动加载的增强版,可以替换掉PSR-0了。

虽然psr-0 已经被废弃,但是还是应该先看psr-0协议:

1. 一个完全合格的namespace和class必须符合这样的结构:“\< Vendor Name>(< Namespace>)*< Class Name>”
2. 每个namespace必须有一个顶层的namespace("Vendor Name"提供者名字)
3. 每个namespace可以有多个子namespace   
4. 当从文件系统中加载时,每个namespace的分隔符(/)要转换成 DIRECTORY_SEPARATOR(操作系统路径分隔符)
5. 在类名中,每个下划线(_)符号要转换成DIRECTORY_SEPARATOR(操作系统路径分隔符)。在namespace中,下划线(_)符号是没有(特殊)意义的。
6. 当从文件系统中载入时,合格的namespace和class一定是以 .php 结尾的
7. verdor name,namespaces,class名可以由大小写字母组合而成(大小写敏感的)

psr-1 规范

1. PHP源文件必须只使用 <?php 和 <?= 这两种标签。
2. 源文件中php代码的编码格式必须是不带字节顺序标记(BOM)的UTF-8。
3. 一个源文件建议只用来做声明(类(class),函数(function),常量(constant)等)或者只用来做一些引起副作用的操作(例如:输出信息,修改.ini配置等),但不建议同时做这两件事。
4. 命名空间(namespace)和类(class) 必须遵守PSR-0标准。
5. 类名(class name) 必须使用骆驼式(StudlyCaps)写法 (注:驼峰式(cameCase)的一种变种,后文将直接用StudlyCaps表示)。
6. 类(class)中的常量必须只由大写字母和下划线(_)组成。
7. 方法名(method name) 必须使用驼峰式(cameCase)写法。

psr-4

1. 废除了PSR-0中_就是目录分割符的写法,_下划线在完全限定类名中是没有特殊含义了。 
2. 类文件名要以 .php 结尾。 
3. 类名必须要和对应的文件名要一模一样,大小写也要一模一样。

自动加载

由于时间原因可以暂时先看这篇博客

https://www.cnblogs.com/woider/p/6443854.html

【参考资料】

https://www.cnblogs.com/drunkhero/p/namespace.html

https://www.cnblogs.com/JohnABC/p/6595075.html

https://www.cnblogs.com/woider/p/6443854.html

https://www.php-fig.org/psr/psr-0/ psr-0 官方文档

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,999评论 4 368
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,102评论 1 302
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,709评论 0 250
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,439评论 0 217
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,846评论 3 294
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,881评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,062评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,783评论 0 205
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,517评论 1 248
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,762评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,241评论 1 264
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,568评论 3 260
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,236评论 3 241
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,145评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,941评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,965评论 2 283
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,802评论 2 275

推荐阅读更多精彩内容