Composer是php用来管理依赖关系的工具,你可以在自己的项目中声明所依赖的外部工具库,Composer会帮助你安装这些依赖的库文件 –Composer中文网
关于Composer的安装和下载可以直接点击上方的链接查看,本篇博文主要讲解该怎样创建自己的Composer包,并把它提交到packgist
创建组件
产商名称和包名
在设置命名空间之前,先要确定产商名称和包名,类似于laravel/framework,确保它的唯一性,在packgist中不存在.厂商名称和包名是为了让packgist识别组件,而组件的命名空间是为了在php中使用组件,这是两个概念。
文件系统结构
- src:这个目录用于存放组件的源码
- tests:这个目录用于存放测试代码
- composer.json:Composer配置文件,用于描述组件,声明组件依赖以及自动加载配置等
- README.md:这个Markdown提供组件的相关信息,使用文档说明软件许可证等
- CONTRIBUTING.md:这个Markdown文件告知别人如何为这个组件做贡献
- LICENSE:纯文本文件,声明组件的软件许可证
- CHANGELOG.md:Markdown文件,列出组件在每个版本中引入的改动
文件系统结构
我们新建一个组件目录(~/Packages/urlscanner),然后在urlscanner目录下通过如下命令生成composer.json文件:
composer init
然后在终端会让我们按照提示向导一步步填写composer.json内容:
最后回车,会生成相应的composer.json文件,我们对该文件作如下修改: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{
"name": "graychen/container",
"description": "a container for interface and container",
"license": "MIT",
"authors": [
{
"name": "Graychen",
"email": "13780185250@sina.cn"
}
],
"minimum-stability": "dev",
"require": {},
"require-dev": {
"phpunit/phpunit" : "~4.3"
},
"autoload":{
"psr-4":{
"graychen\\container\\" : "src"
}
},
"autoload-dev":{
"psr-4":{
"graychen\\container\\Tests\\":"tests/"
}
}
}
我们来仔细研究一下这个文件,看看每个部分究竟是什么意思:
- name:组件的厂商名和包名,也是Packagist中的组件名
- description:简要说明组件
- keywords:描述属性的关键字
- homepage:组件网站URL
- license:PHP组件采用的软件许可证(更多软件许可证参考:http://choosealicense.com/)
- authors:作者信息数组
- support:组件用户获取技术支持的方式
- require:组件自身依赖的组件
- require-dev:开发这个组件所需的依赖
- suggest:建议安装的组件
- autoload:告诉Composer自动加载器如何自动加载这个组件
READEME.md
通常这个是用户最先阅读的文件,对托管在Github和Bitbucket中的组件来说,更是如此。标准的READEME.md文件至少提供以下信息:
- 组件的名称和描述
- 安装说明
- 使用说明
- 测试说明
- 贡献方式
- 支持资源
- 作者信息
- 软件许可证
实现组件
开始之前我们使用如下命令安装依赖:1
composer install
该命令会把依赖组件安装到vendor目录并生成自动加载器。
安装好以后我们来实现组件的具体功能。将所有的类,接口和Trait都放到src这个目录下。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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
namespace container;
/**
* @brief 服务容器
* author Graychen
*/
class Container implements \ArrayAccess{
private $_bindings = [];//服务列表
private $_instances= [];//已经实例化的服务
//获取服务
public function get($name,$params=[]){
//先从实例化的列表中查找
if(isset($this->$_instances[$name])){
return $this->$_instances[$name];
}
//检测有没有注册该服务
if(!isset($this->$_bindings[$name])){
return null;
}
$concrete = $this->$_bindings[$name]['class'];//对象具体注册内容
$obj = null;
if($concrete instanceof \Closure){ //匿名函数方式
$obj = call_user_func_array($concrete,$params);
}elseif(is_string($concrete)){ //字符串方式
if(empty($params)){
$obj = new $concrete;
}else{
//带参数的类实例化,使用反射
$class = new \reflectionClass($concrete);
$obj = $class->newInstanceArgs($params);
}
}
//如果是共享服务,则写入_instances列表,下次直接取回
if($this->_bindings[$name]['shared']==true && $ojb){
$this->_instances[$name]=$obj;
}
return $obj;
}
//检测是否已经绑定
public function has($name){
return isset($this->_bindings[$name]) or isset($this->_instances[$name]);
}
//卸载服务
public function remove($name){
unset($this->_bindings[$name],$this->_instances[$name]);
}
//设置服务
public function set($name,$class){
$this->_registerService($name,$class);
}
//设置共享服务
public function setShared($name,$class){
$this->_registerService($name,$class,true);
}
//注册服务
private function _registerService($name,$class,$shared=false){
$this->remove($name);
if(!($class instanceof \Closure) && is_object($class)){
$this->_instances[$name]=$class;
}else{
$this->_bindings[$name]=array("class"=>$class,"shared"=>$shared);
}
}
//ArrayAccess接口,检测服务是否存在
public function offsetExists($offset){
return $this->has($offset);
}
//ArrayAccess接口,以$di[$name]方式获取服务
public function offsetGet($offset){
return $this->get($offset);
}
//ArrayAccess接口,以$di[$name]方式获取服务
public function offsetSet($offset,$value){
return $this->set($offset,$value);
}
//卸载服务
public function offsetUnset($offset){
return $this->remove($offset);
}
}
提交到packglist
我们先将代码提交到GitHub,注意将vendor目录添加到.gitignore仓库,我的是graychen/container:1
2
3
4
5
6git init
git remote add origin https://github.com/nonfu/urlscanner.git
git add .
git commit -m “urlscanner"
git pull origin master
git push origin master
然后在Packagist中通过GitHub账户登录,通过https://packagist.org/packages/submit提交组件,在输入框中输入刚刚提交的GitHub仓库地址:
check成功后点击submit即可将组件提交到Packagist:
使用组件
至此,我们已经成功将自己的组件提交到Packagist,现在任何人都可以使用Composer安装这个URL扫描器组件,然后在自己的PHP应用中使用。在终端执行如下命令安装这个组件:
composer require graychen/container dev-master