Namespaces-Interface-Traits

计划第一天

今天是计划的第一天,主要在看《Moder PHP》,看了三块内容,一个是 Namespace,一个是 Interface,另一个是 Trait。都是 php 的面向对象特性里面比较突出的一些。Namespace 以前在 Laracast 上看过教程所以还算熟悉。Trait 今天是好好了解了一下,以前开发的时候都不常用这东西。今天在实现代码的时候又发现了一个好用的 php 插件在 atom 上,能给我自动补全 Namespace 还能跳转定义的地方。

Namespace

为什么要用 Namespace

就跟Java里的那些包名类似,是为了防止各个不同的类之间发生冲突,一个人的时候还好,自己知道写过哪些类,当团队开发的时候或者引入了其他人的一个扩展包的话,如果没有命名空间就极易发生冲突。所以使用 Namespace 还是很必须的,可以说是php面向对象的基础。

使用 composer

如果像平常那样写一些小的测试就不用 composer 了,但这次是要学习现代化的 php 用法,如果不用 composer 就要 require 这样把一个个包联系起来,用了 composer 自动加载之后,只要定义命名空间然后 use 就行。

下面我们从头开始用composer 自动加载来实现我们的测试。

1. 首先我们要安装 composer

Composer 在 windoes 下安装很简单,直接用安装包安装就行,安装完之后将镜像地址换到国内,这样下载扩展包是能够快点。

Composer官网

Composer国内镜像

2. 然后在自己的工程目录下新建 composer.json

1
2
3
4
5
6
7
{
"autoload":{
"psr-4":{
"Lsu\\":"src/"
}
}
}

这里第4行的Lsu是我以后要使用的命名空间顶级名称,src是我实际使用的顶级目录。

新建好 composer.json 之后就在命令行使用 composer install 这个时候文件目录就会生成,让自己再手动新建 src 目录,在里面写要测试的代码就行。

3. 使用命名空间空间

1
2
3
4
5
6
7
8
9
10
<?php
namespace Lsu;
interface Documentable
{
public function getId();
public function getContent();
}
?>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
namespace Lsu; //定义命名空间
use Lsu\Documentable; //因为下面我依赖注入的时候使用了这个类,所以我要引入这类
class DocumentStore
{
protected $data = [];
public function addDocument(Documentable $document)
{
$key = $document->getId();
$value = $document->getContent();
$this->data[$key] = $value;
}
public function getDocuments()
{
return $this->data;
}
}
?>

这样命名空间就定义好了,然后类和类之间引用使用 use 就可以了。

Interface

接口这个,是面向抽象语言必不可少的特性,可以用来降低耦合。
具体用法和其他语言相同。先定义一个接口,然后在其他需要它的类中 implements 这个接口。
上面使用 composer 的那个例子同样也是一个接口实现的例子。

Trait

这个特性是一般语言不具有的 像 Ruby 和 PHP 才有,感觉是一种语法糖。书里先给我讲了个场景,大意是现在有个地图, 地图上有商店,有正在行驶的车,让要给这两个东西都实现获取经纬度的方法。如果使用继承,那么他们两个没有太大关系的类如果继承同一个类就显得不合理。如果使用接口的话,两个类明明需要实现的都是同一个方法,用接口就要实现两遍,所以没有很好的复用(用抽象类,就回到了第一个继承同一个类的问题了)。

所以,这时候 PHP 的 trait 作用就体现出来了,它可以先想 class 那样写好一个 trait 让在需要使用它的地方 use 就可以了。像场景里那个例子,先实现好获取经纬的的 trait。让在商店和车这两个类中 use

我拿举个简单的例子

先定义了一个 trait

1
2
3
4
5
6
7
8
9
10
11
12
<?php
namespace Lsu;
trait TraitSayHello
{
function sayHello()
{
print_r("hello");
}
}
?>

然后在需要这个 trait 的类里面使用它

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
namespace Lsu;
class DocumentTest implements Documentable
{
use TraitSayHello;
public function getId()
{
return "id test ok";
}
public function getContent()
{
return "content test ok";
}
}
?>

这样 DocumentTest 类 new 出来的对象就能直接使用 sayHello 方法了

1
2
3
<?php
$documentTest = new DocumentTest();
$documentTest->sayHello();

明天继续

今天书上这三块内容还是将得不错的,比我以前看的详细了不少,明天继续往下看下去,希望能更多的了解一些 PHP 的特性。