1 命名空间

1.1 介绍

在一个大的项目中,可能会遇到同名的类、函数、常量,为了区分这些元素,我们可以将这些元素分别存放到不同的命名空间中。

1、命名空间就是包,用来存放项目中的类、函数、常量

2、通过namespace关键字来声明命名空间

1.2 声明命名空间

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
namespace China; //定义命名空间
function getInfo() {
echo '我是中国人<br>';
}

namespace USA; //定义命名空间
function getInfo() {
echo 'I am a America<br>';
}
//调用
getInfo(); //I am a America
\USA\getInfo(); //I am a America
\China\getInfo(); //我是中国人

注意:\表示公共空间

1.3 多级命名空间

命名空间的名字可以是多级的(子级命名空间)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
namespace China\Beijing\Shunyi;
class Student {

}
namespace USA\Washington;
class Student {

}
//测试:
$stu1=new Student(); //相对路径
$stu2=new \USA\Washington\Student(); //绝对路径
$stu3=new \China\Beijing\Shunyi\Student(); //绝对路径
var_dump($stu1,$stu2,$stu3);

//object(USA\Washington\Student)#1 (0) { }
//object(USA\Washington\Student)#2 (0) { }
//object(China\Beijing\Shunyi\Student)#3 (0) { }

总结:如果将相对路径转成绝对路径

1
2
3
公共空间+命名空间+空间元素
公共空间           命名空间                 空间元素
  \         China\Shanghai\PuDong\       Student

1.4 访问空间元素的三种方式

1、非限定名称访问

2、完全限定名称访问

3、限定名称访问

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
namespace China\Beijing\Shunyi;
function getInfo() {
echo '顺义...<br>';
}

namespace China\Beijing;
function getInfo() {
echo '北京...<br>';
}
//访问空间元素的三种方式
getInfo(); //非限定名称访问 北京...
\China\Beijing\getInfo(); //完全限定名称访问 北京...
Shunyi\getInfo(); //限定名称访问 顺义...
//转成绝对路径如下:
// \China\Beijing\Shunyi\getInfo();

1.5 引入命名空间

完全限定名称访问元素路径太长,可以将其他空间引入到当前空间来

通过use引入命名空间

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
namespace China\Beijing\Shunyi;
function getInfo() {
echo '李白<br>';
}
namespace USA;
function getInfo() {
echo 'Lincoln<br>';
}
//引入命名空间
use China\Beijing\Shunyi;
//测试
getInfo(); //Lincoln
Shunyi\getInfo(); //李白
/*
分析:
第一步:通过当前空间拼接成绝对路径:\USA\Shunyi\getInfo(),这个地址没有对应的空间元素
第二步:通过引入的空间拼接绝对路径:\China\Beijing\Shunyi+Shunyi\getInfo(),Shunyi是公共部分,只需要取一个,最后拼接的地址是:\China\Beijing\Shunyi\getInfo(),这个地址可以找到对应的元素
*/

引入命名空间的拼接规则

1
2
3
4
5
6
7
8
9
10
公共空间+引入空间+(去除公共部分,公共部分只能有一级)空间元素

比如:
namespace A\B\C;
function getInfo(){}

namespace D\E;
use A\B\C; //引入命名空间
C\getInfo(); //正确 \A\B\C\getInfo();
B\C\getInfo(); //错误   \A\B\C\B\C\getInfo();

1.6 引入空间元素

引入类:use

引入函数:use function [php7.0以后支持]

引入常量:use const [php7.0以后支持]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
namespace China\Beijing\Shunyi;
class Student {
}
function getInfo() {
echo '李白<br>';
}
const TYPE='学生';
namespace USA;
//引入类
use China\Beijing\Shunyi\Student;
//引入函数
use function China\Beijing\Shunyi\getInfo;
//引入常量
use const China\Beijing\Shunyi\TYPE;

//测试
$stu=new Student;
var_dump($stu);
echo '<br>';
getInfo();
echo TYPE;

1.7 给类、函数取别名

如果引入的类和函数与当前空间的类和函数名称相同,需要给引入的类和函数取别名。

通过as取别名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php
namespace China\Beijing\Shunyi;
class Student {

}
function getInfo() {
echo '李白<br>';
}
namespace USA\Washington;
class Student {

}
function getInfo() {
echo 'Lincoln<br>';
}
//引入类取别名
use China\Beijing\Shunyi\Student as ChinaStudent;
//引入函数
use function China\Beijing\Shunyi\getInfo as info1;

//测试
$stu=new ChinaStudent;
var_dump($stu);

getInfo(); //Lincoln
info1(); //李白

1.8 公共空间

如果一个页面没有namespace声明空间,这个页面的元素在公共空间下

公共空间用\表示

1
2
3
4
5
<?php
function getInfo() {
echo '李白<br>';
}
\getInfo(); //李白

1.9 命名空间注意事项

1、命名空间只能存放类、函数、const常量

2、第一个namespace前面不能有任何的代码,空白字符、header()也不行。

3、包含文件不影响当前的命名空间

2 trait(原型)

trait 为了减少单继承语言的限制,可以在不同层次结构内独立的类中复用类的方法集。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
//原型
trait A{
public function getInfo() {
echo '锄禾日当午<br>';
}
}
//使用原型
class Student {
use A; //代码复用
}
//测试
$stu=new Student;
$stu->getInfo(); //锄禾日当午

引入多个 trait

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
//原型
trait A{
public function getInfo1() {
echo '锄禾日当午<br>';
}
}
trait B{
public function getInfo2() {
echo '床前明月光<br>';
}
}
//使用原型
class Student {
use A,B; //引入A、B trait
}
//测试
$stu=new Student;
$stu->getInfo1(); //锄禾日当午
$stu->getInfo2(); //床前明月光

trait和继承结合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
trait A{
public function getInfo() {
echo '这是trait原型<br>';
}
}
class Person {
public function getInfo() {
echo '这是Person类<br>';
}
}
//继承类同时代码复用
class Student extends Person {
use A; //继承了getInfo,有被A中getInfo覆盖
}
//测试
$stu=new Student;
$stu->getInfo(); //这是trait原型

解决同名冲突

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?php
//原型
trait A{
public function getInfo() {
echo '锄禾日当午<br>';
}
}
trait B{
public function getInfo() {
echo '床前明月光<br>';
}
}
//使用原型
class Student {
use A,B{ //引入ABtrait,同时解决名称冲突
//方法一:方法替换
//A::getInfo insteadof B; //将A中的getInfo替换掉B中的getInfo
//B::getInfo insteadof A; //将B中的getInfo替换到A中的getInfo

//方法二:改名
A::getInfo insteadof B;
B::getInfo as show; //将B的getInfo改名为show
}
}
//测试
$stu=new Student;
$stu->getInfo(); //锄禾日当午
$stu->show(); //床前明月光
/*
同名冲突的解决方法有两个:
第一:方法替换
第二:方法改名

更改权限

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
trait A{
private function show() {
echo '锄禾日当午<br>';
}
}
class Student {
use A{
//show as public; //将show方法权限设为public;
show as public show2; //将show方法设置public,并改名为show2
}
}

$stu=new Student;
//$stu->show();
$stu->show2();

多学一招:具体参见手册

1、 多个trait可以组成一个trait

2、 trait可以定义抽象成员

3、 trait可以定义静态成员

4、 trait可以定义属性

3 迭代器

3.1 遍历数组

手动遍历数组

步骤:

1、复位数组指针 reset()

2、检查指针是否合法 获取当前指针,如果不为null就是合法的

3、获取当前值 current()

4、获取当前键 key()

5、指针下移 next()

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
$stu=['tom','berry','ketty','rose'];
reset($stu); //复位指针
while(key($stu)!==null){//键合法
echo key($stu),'-',current($stu),'<br>';//获取键、值
next($stu); //指针下移
}
/*
0-tom
1-berry
2-ketty
3-rose
*/

3.2 迭代器

迭代器是PHP内置的接口

场景:遍历对象,获取的是对象中属性保存的数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<?php
//定义类实现迭代器接口
class MyClass implements Iterator{
//$list属性用来保存学生数组
private $list=array();
//添加学生
public function addStu($name) {
$this->list[]=$name;
}
//实现接口中的复位方法
public function rewind() {
reset($this->list);
}
//验证当前指针是否合法
public function valid() {
return key($this->list)!==null;
}
//获取值
public function current() {
return current($this->list);
}
//获取键
public function key() {
return key($this->list);
}
//指针下移
public function next() {
next($this->list);
}
}

//创建班级
$class=new MyClass();
//添加学生
$class->addStu('tom');
$class->addStu('berry');
$class->addStu('ketty');
//遍历班级
foreach($class as $k=>$v){
echo "{$k}-{$v}<br>";
}
/*
0-tom
1-berry
2-ketty
*/

4 PSR编码规范

4.1 概述

  1. PSR 是 PHP Standard Recommendations 的简写,由 PHP FIG 组织制定的 PHP 规范,是 PHP 开发的实践标准。
  2. 目前已表决通过了 6 套标准,已经得到大部分 PHP 框架的支持和认可。
  3. 网址:http://psr.phphub.org/

1560769585637.png

4.2 PSR-1 基础编码规范

1
2
3
4
1、PHP代码文件 必须 以 <?php 或 <?= 标签开始
2、类的命名大写开头的驼峰命名规范
3、类中的常量所有字母都必须大写,单词间用下划线分隔
4、方法名称必须符合小写开头驼峰命名规范5、

副作用:(side effects),一个文件只做一件事情,如果做了其他事情就是产生了副作用

不产生副作用:一个文件只做一件事

产生副作用:一个文件做了多件事情

4.3 PSR-2 编码风格规范

1
2
3
4
5
代码 必须 使用 4 个空格符而不是「Tab 键」进行缩进
每个 namespace 命名空间声明语句和 use 声明语句块后面,必须 插入一个空白行
类的开始花括号({) 必须 写在类声明后自成一行,结束花括号(})也 必须 写在类主体后自成一行
方法的开始花括号({) 必须 写在函数声明后自成一行,结束花括号(})也 必须 写在函数主体后自成一行。
类的属性和方法 必须 添加访问修饰符(private、protected 以及 public),abstract 以及 final 必须 声明在访问修饰符之前,而 static 必须 声明在访问修饰符之后。

本站由 RuntimeBroker 使用 Stellar 主题创建。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。

本"页面"访问 次 | 👀总访问 次 | 总访客