前言
大多时候都在搬别人写好的砖,那么这些砖到底是如何造好的呢,今天我们来一探究竟。本文我主要以实践的知识进行展示,不会在一些名词上做过多的解释,如果涉及到比较重要的名词知识会放上相关的官方文档链接参考。
开始
创建仓库
首先,在 github
或码云创建一个自己仓库,为于发布提交我们自己的扩展。
这里我在码云新建了一个仓库,仓库地址:https://gitee.com/zjq528/composer-test
,注意这个仓库是真实存在啊,我这里主要是以实践进行演示,当我们文章写完的时候,我们的一个 demoe
也就完成了。
克隆项目
将我们在码云或 github
创建的项目克隆到本地,然后进行我们的开发工作。
git clone https://gitee.com/zjq528/composer-test
这里我将这个项目克隆到我本地的 E/
根目录。克隆后目录如下:/e/composer-test
编写 composer.json
composer.json
文件我们可以自己手写,也可以通过命令生成。由于我们是第一次开发自己的扩展,我们哪里知道应该格式怎么写,都可以定哪些内容呢,是吧,所以,这里我们采用命令生成的方式来生成 composer.json
文件。
在 /e/composer-test
目录下执行:
composer init
然后会出现提示:
Welcome to the Composer config generator
This command will guide you through creating your composer.json config.
Package name (<vendor>/<name>) [gift/composer-test]:
这里是让我们为我们的扩展起一个响亮的名称,默认是我们上面创建的仓库的名称,这里建议使用默认的名称,也就是保持和我们的仓库名称一致就好。
那么这个名称到底是个什么意思呢,从安装扩展的角度来就,就是别人使用 composer require 扩展名
安装扩展时,这里的这个名称就是 require
后面的名称。从目录上来看,安装后会在 vendor
目录生成这样的目录:
vendor/gift/composer-test
这里我们敲一个响亮的回车,其实屁都没做使用了默认值,然后就出现了下面的内容:
Description []:
这里让我们输入一段对这个包的描述信息,建议输入一些对这个包的功能描述或其它对这个包做解释的描述,尽量不要输个屁用没有 test
或 测试
什么什么屁用没有的内容。这里我们输入一段简要的描述,然后回车:
Description []: study how to create my owen package
Author [gift <[email protected]>, n to skip]:
输入一段描述后回车,让我们输入作者的相关信息,如果与默认的相同,那就直接回,如果不同可以在后面输入你要输入的作者信息即可,注意格式保持与命令行中的相同,即 gift <[email protected]>
,然后回车:
Minimum Stability []:
这里是通过设置minimum-stability的值,来告诉Composer当前开发的项目的依赖要求的包的全局稳定性级别,它的值包括:dev、alpha、beta、RC、stable,stable是默认值。这里我们直接回车使用默认值:
Package Type (e.g. library, project, metapackage, composer-plugin) []:
这里让我们选一个我们包的类型,这里大家可以根据自己的情况选择一个合适的即可,如果不确实可以直接回车默认,这里我们选择 library
License []:
这里让我们输入证书,我们直接默认
Would you like to define your dependencies (require) interactively [yes]?
这里问我们是否定义我们的依赖,就是我这个包是否用到别的扩展中的东西,如果用到的话就说明我们这个包依赖别的扩展,这里我们假如我们要开发的这个包依赖一个打印的包吧,如 symfony/var-dumper
,当然我们怎么知道这个依赖名称,那肯定也不是我们记住的,我们需要用到哪个扩展还是要自己去 github
或扩展的文档中查一下,这里我们先输入 yes
然后输入上面那个扩展:
Would you like to define your dependencies (require) interactively [yes]? yes
Search for a package: symfony/var-dumper
Enter the version constraint to require (or leave blank to use the latest version):
输入回车后让我们输入这个扩展的版本,如果我们对扩展有版本要求,就输入我们想使用的版本,如果没有什么要求,可以直接回车使用最新的版本,这里直接回车,使用最新的版本:
Using version ^5.0 for symfony/var-dumper
Search for a package:
回车等一下,然后看到自动为我们找到了 ^5.0
的版本,再往下就还是重复上面那个输入扩展名,然后再输入版本号的过程,如果有多个依赖可以接着输入,如果没有了就回车,这里我们只使用这一个依赖,回车:
Search for a package:
Would you like to define your dev dependencies (require-dev) interactively [yes]?
回车,看到这里又让我们输入一个开发里的依赖,这个是什么意思呢,就是说我们在开发这个扩展的过程中需要使用依赖,这个一般都是进行调试或测试使用,在上线时不会安装的依赖,这里我们因为要使用 phpunit
写单元测试,所以我们输入 yes
,然后输入 phpunit/phpunit
Search for a package:
Would you like to define your dev dependencies (require-dev) interactively [yes]? yes
Search for a package: phpunit/phpunit
Enter the version constraint to require (or leave blank to use the latest version):
Using version ^8.4 for phpunit/phpunit
Search for a package:
这里我们只有一个开发依赖,所以再次回车
Using version ^8.4 for phpunit/phpunit
Search for a package:
{
"name": "gift/composer-test",
"description": "study how to create my owen package",
"type": "library",
"require": {
"symfony/var-dumper": "^5.0"
},
"require-dev": {
"phpunit/phpunit": "^8.4"
},
"authors": [
{
"name": "gift",
"email": "[email protected]"
}
]
}
Do you confirm generation [yes]?
上面列出了我们刚才设置的一些信息,看一下如果没有什么问题的话,就输入 yes
Would you like the vendor directory added to your .gitignore [yes]? yes
Would you like to install dependencies now [yes]? yes
上面又让我们输入了两个 yes
第一个是说我们是否把 vendor
目录添加到忽略,那当然了,我们这个vendor
目录是我们本地开发调试用的,第二个 yes
试问我们是否安装依赖,这个当然了,依赖我们开发时要用当然要安装了。当然如果在这里没有安装依赖,生成 composer.json
文件后也可以执行 composer install
进行,那我们还不如在这里一气呵成呢。
Would you like to install dependencies now [yes]? yes
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 31 installs, 0 updates, 0 removals
- Installing symfony/polyfill-mbstring (v1.13.1): Loading from cache
- Installing symfony/var-dumper (v5.0.0): Downloading (100%)
- Installing sebastian/version (2.0.1): Loading from cache
- Installing sebastian/type (1.1.3): Loading from cache
- Installing sebastian/resource-operations (2.0.1): Loading
.....
phpunit/phpunit suggests installing ext-xdebug (*)
Writing lock file
Generating autoload files
依赖安装完成后我们这个 composer.json
就算完美的生成了。接下来就可以进行开发了。接下来我们来说一下扩展的目录结构。
目录结构
通常我们安装别人的扩展时会发现目录结构大概是以下这样的:
src/
Hello.php
test/
大体上就是上面那样的,src
目录中放我们的扩展代码,当然也可以在 src
下新建目录,我们这里以简单的为例。tests
目录用来放我们单元测试的文件。
那我们的目录就只能是这样吗,当然不是,你想怎么样就怎样,没有强制要求,但是大家都这样我们肯定也这样做,一是统一,二是看着顺眼。当然至于为什么是这样的目录肯定也有一样的原因,有兴趣的话可以自行百度一下。
编写代码
vim src/Hello.php
内容如下:
<?php
namespace hello;
class Hello
{
public function test()
{
$data = [
1, 2, 3, 4
];
dd($data);
}
}
类虽然有了,那么我们使用时怎么样才能加载到呢,一种就是我们直接使用 include
,我们不会这样做了,我们既然使用 composer
我们就要使用 composer
中的类自动加载机制,这里我们使用 psr-4
进行加载,那么就需要我们在 composer.json
进行配置了:
{
"name": "gift/composer-test",
"description": "study how to create my owen package",
"type": "library",
"require": {
"symfony/var-dumper": "^5.0"
},
"require-dev": {
"phpunit/phpunit": "^8.4"
},
"authors": [
{
"name": "gift",
"email": "[email protected]"
}
],
"autoload": {
"psr-4": {
"hello\\": "src/"
}
}
}
添加最下面的 autoload
的代码,然后我们需要再次执行 composer install
才能生成自动加载文件
composer install
此时,在 vendor/composer/autload_psr4.php
就有了关于我们这个命名空间的映射
'hello\\' => array($baseDir . '/src'),
到这里,我们关于扩展开发的问题就基本完成了,如果有更多的功能代码直接按照 上面的思路进行开发即可。下面我们来说一下关于单元测试的问题
单元测试
扩展开发我们不能闭着去写对吧,而且随便版本的不断迭代更新,我们也不能每次都打印调试我们的每个方法吧,那样也太麻烦而且操作性也很差,这时候就用到我们的单元测试了,这里我们初始化时引入了开发依赖 phpunit
,下面我们进行测试代码的开发
在 src
同级目录新建 tests
目录
mkdir tests
在 tests
目录中新一个测试类,测试类名,以要测试的类开头,以 Test
结尾,下面我们新建 HelloTest
类并继承 PHPUnit\Framework\TestCase
类
vim tests/HelloTest
<?php
namespace tests;
use PHPUnit\Framework\TestCase;
class HelloTest extends TestCase
{
}
编写一个测试方法
<?php
namespace tests;
use PHPUnit\Framework\TestCase;
use hello\Hello;
class HelloTest extends TestCase
{
public function testEchoNumber()
{
$obj = new Hello();
$this->assertTrue(is_numeric($obj->echoNumber()));
}
}
执行测试
$ vendor/bin/phpunit tests
PHPUnit 8.4.3 by Sebastian Bergmann and contributors.
^ array:4 [
0 => 1
1 => 2
2 => 3
3 => 4
]
上面我们发现打印出了数据,但是没有我们断言的结果,因为我们在方法中使用了一个 dd
的方法,在那个方法中有 exit
所以后面的代码没有执行,我们注释掉方法中的 dd
打印,然后再次运行测试:
gift@DESKTOP-UF78TR1 MINGW64 /e/composer-test (master)
$ vendor/bin/phpunit tests
PHPUnit 8.4.3 by Sebastian Bergmann and contributors.
. 1 / 1 (100%)
Time: 87 ms, Memory: 4.00 MB
OK (1 test, 1 assertion)
我们看到共有一个测试,一个断方,并且成功。
关于 phpunit
的要关使用,需要学习同学可以查看官方文档 http://www.phpunit.cn/
发布
第一版开发完了,我们要进行发布别人才能使用,对吧。首先把我们的代码 commit
,但是先不要急着准送到 github
,因为我们还有一个非常重要的事情没有做,那就是给我们开发的扩展添加一个 tag
指定一个版本号,否则的话我们的扩展就是发布了别人也是安装不了的。
添加 tag
git tab 0.0.1
关于版本号的定义规范,可以参考 composer
官方文档进行定义,注意,随便定义也可以安装不了的。文档:https://docs.phpcomposer.com/02-libraries.html#Tags
将代码和标签推送到 github
:
# 推送代码
git push
# 推送所有的标签,注意标签不会和代码一起推送,需要单独推送标签
git push --tags
下面就是发布到 Packagist 上,关于发布的具体操作这里就不再描述了,可以参考下面文章:https://blog.csdn.net/whq19890827/article/details/79705531
到此整个教程就结束!!!