Composer是 用PHP开发的用来管理项目依赖的工具,当你在项目中声明了依赖关系后,composer可以自动帮你下载和安装这些依赖库,并实现自动加载代码。
工作原理
主要由三个部分组成:命令行工具、包仓库、代码库:
命令行
命令行指的就是 composer
的各种命令。如:创建项目(create-project)、引入扩展包(require)、移除扩展包(remove)、清空缓存(clear-cache)等
仓库
Packagist
:官方仓库,也就是我们平常说的 Composer 源,它的作用是存储这些包的信息,版本,代码来源,依赖,作者,主页等信息。官网是 packagist.org, 你也可以将自己的包发布在上面,这样 Composer 工具就能搜索与安装你的包了- 公有仓库:https://packagist.org
- 私有仓库:https://packagist.com
Repository
:代码存储库仓库,Packagist 支持公开与私有仓库,通常是 GitHub 作为代码仓库,当然也可以是 Gitee
自动加载
只需要执行composer命令拉取扩展包,即可实现自动加载代码,包依赖管理和使用自动加载,PSR-0
和 PSR-4
自动加载规范。
步骤
要发布一个软件包,我们首先必须将它托管在版本控制系统存储库中。源代码应该放在根目录下,composer.json
文件应该根据下面的规则进行适当的配置。之后,您可以在不同的平台上提交您的软件包。
Step1. 创建代码仓库
在自己的github创建一个公共仓库,这里仓库名为hello
,创建好后克隆代码到自己本机电脑
git clone git@github.com:Tinywan/hello.git
Step2. 初始化 composer.json
D:\dnmp\www\hello> composer init
Welcome to the Composer config generator
This command will guide you through creating your composer.json config.
// 包名
Package name (<vendor>/<name>) [tinywan/hello]:
// 包描述
Description []: 开源技术小栈如何构建自己的Composer依赖包
// 作者信息
Author [Tinywan <756684177@qq.com>, n to skip]:
// 包类型和协议直接回车就好了
Minimum Stability []:
// 包的依赖,如最低PHP要求
Package Type (e.g. library, project, metapackage, composer-plugin) []: library
License []:
Define your dependencies.
Would you like to define your dev dependencies (require-dev) interactively [yes]? no
Add PSR-4 autoload mapping? Maps namespace "Tinywan\Hello" to the entered relative path. [src/, n to skip]:
{
"name": "tinywan/hello",
"description": "开源技术小栈如何构建自己的Composer依赖包",
"type": "library",
"autoload": {
"psr-4": {
"Tinywan\\Hello\\": "src/"
}
},
"authors": [
{
"name": "Tinywan",
"email": "756684177@qq.com"
}
],
"require": {}
}
Do you confirm generation [yes]?
Generating autoload files
Generated autoload files
Would you like the vendor directory added to your .gitignore [yes]?
PSR-4 autoloading configured. Use "namespace Tinywan\Hello;" in src/
Include the Composer autoloader with: require 'vendor/autoload.php';
最后生成的composer.json
文件内容
{
"name": "tinywan/hello",
"description": "开源技术小栈如何构建自己的Composer依赖包",
"type": "library",
"autoload": {
"psr-4": {
"Tinywan\\Hello\\": "src/"
}
},
"authors": [
{
"name": "Tinywan",
"email": "756684177@qq.com"
}
],
"require": {}
}
项目目录结构
src/
存放源代码文件vendor/
存放第三方依赖composer.json
定义项目的元数据和依赖信息README.md
项目的说明文档- 其他必要的文件和目录
Step3. 实现包功能
这里实现一个简单的加密工具类Encryption
<?php
/**
* @desc 加密工具类
* @author Tinywan(ShaoBo Wan)
* @date 2023/12/30 14:27
*/
declare(strict_types=1);
namespace tinywan\hello;
class Encryption
{
/** AES-128-ECB 加密方式*/
public const AES_128_ECB = 'AES-128-ECB';
/**
* @desc 加密
* @param string $data 加密的数据
* @param string $key 密钥,必须是16、24或32个字符长度
* @param string $algo 加密方式
* @param string $iv 初始向量(IV)
* @return string
* @author Tinywan(ShaoBo Wan)
*/
public static function encrypt(string $data, string $key, string $algo = self::AES_128_ECB, string $iv = ''): string
{
$encryptedBytes = openssl_encrypt($data, $algo, $key, OPENSSL_RAW_DATA);
return base64_encode($encryptedBytes);
}
/**
* @desc 解密
* @param string $data
* @param string $key 密钥,必须是16、24或32个字符长度
* @param string $algo 加密方式
* @param string $iv 初始向量(IV)
* @return false|string
* @author Tinywan(ShaoBo Wan)
*/
public static function decrypt(string $data, string $key, string $algo = self::AES_128_ECB, string $iv = '')
{
return openssl_decrypt(base64_decode($data), $algo, $key, OPENSSL_RAW_DATA);
}
}
Step4.编写单元测试用例
PHPUnit是一个轻量级的PHP测试框架,单元测试是几个现代敏捷开发方法的基础,使得PHPUnit成为许多大型PHP项目的关键工具。
安装PHP测试框架包phpunit/phpunit
composer require --dev phpunit/phpunit
EncryptionTest.php
用例
<?php
/**
* @desc EncryptionTest
* @author Tinywan(ShaoBo Wan)
* @email 756684177@qq.com
* @date 2023/12/29 23:46
*/
declare(strict_types=1);
class EncryptionTest extends \PHPUnit\Framework\TestCase
{
public function test()
{
$data = '开源技术小栈';
$key = '53vYPpTJIR1aYFiFh0PppZzF';
/** 加密*/
$encrypt = \tinywan\hello\Encryption::encrypt($data, $key);
self::assertIsString($encrypt);
/** 解密*/
$decrypt = \tinywan\hello\Encryption::decrypt($encrypt, $key);
// 判断解密明文是否和预期的相等
self::assertEquals($decrypt, $data);
}
}
运行这个单元测试,在命令行下输入代码
$ vendor/phpunit/phpunit/phpunit tests/EncryptionTest.php
PHPUnit 9.6.15 by Sebastian Bergmann and contributors.
. 1 / 1 (100%)
Time: 00:00.007, Memory: 4.00 MB
OK (1 test, 2 assertions)
结果中最重要的用红色标出的结果,点号.
代表一个用例通过(即assert系列函数都通过)
如果将上面的测试用例改为不等于self::assertNotEquals(decrypt, data);,则运行结果为:
$ vendor/phpunit/phpunit/phpunit tests/EncryptionTest.php
PHPUnit 9.6.15 by Sebastian Bergmann and contributors.
F 1 / 1 (100%)
Time: 00:00.010, Memory: 4.00 MB
There was 1 failure:
1) EncryptionTest::test
Failed asserting that '开源技术小栈' is not equal to '开源技术小栈'.
D:\dnmp\www\hello\tests\EncryptionTest.php:26
FAILURES!
Tests: 1, Assertions: 2, Failures: 1.
Step4. 提交代码到 GitHub
$ git commit -m "init"
[main ffed98a] init
13 files changed, 1833 insertions(+)
create mode 100644 .gitignore
create mode 100644 .idea/.gitignore
create mode 100644 .idea/hello.iml
create mode 100644 .idea/inspectionProfiles/Project_Default.xml
create mode 100644 .idea/modules.xml
create mode 100644 .idea/php-test-framework.xml
create mode 100644 .idea/php.xml
create mode 100644 .idea/vcs.xml
create mode 100644 .phpunit.result.cache
create mode 100644 composer.json
create mode 100644 composer.lock
create mode 100644 src/Encryption.php
create mode 100644 tests/EncryptionTest.php
可以看出以上提交了好多无效的代码,如.idea
目录,这里修改一下忽略提交文件.gitignore
,内容如下:
build
vendor
.idea
.vscode
.phpunit*
composer.lock
Step5. 提交至 Packagist
Packagist 为 composer 默认获取包元数据信息的地址,从 Packagist 获取到元数据信息后,再从 GitHub 上拉取代码。因此,当把你开发的包上传至 GitHub 后还需要将其在 Packagist 注册。
一旦你的包发布到Packagist上,其他人就可以通过Composer安装你的包,并在他们的项目中使用你的代码。
提交至 Packagist 三个步骤
- 注册帐号(有的话直接进行下一步)
- 在https://packagist.org/packages/submit 提交开发包
提交成功
Step6. 使用包
一旦提交的包在Packagist
发布了,则可以通过composer直接安装使用
composer require tinywan/hello dev-main
由于没有发布正式包,这里拉取包先要指定dev-main
分支
composer require tinywan/hello dev-main ./composer.json has been updated Running composer update tinywan/hello Loading composer repositories with package information Updating dependencies Lock file operations: 1 install, 0 updates, 0 removals - Locking tinywan/hello (dev-main c6f43d0) Writing lock file Installing dependencies from lock file (including require-dev) Package operations: 4 installs, 30 updates, 3 removals
如果要发布一个正式版本,需要在自己依赖包打标签tag
// 打标签
$ git tag v0.1
// 标签推送远程仓库
$ git push origin v0.1
Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
To github.com:Tinywan/hello.git
* [new tag] v0.1 -> v0.1
这时候再去拉取默认版本,就是刚才打标签的v0.1
版本了
小结
以上是一个简单的构建自己的Composer依赖包的步骤,通过 composer 来管理 PHP 的依赖,通过编写 composer package 去扩展自己的类库,通过引入其他的类库来填充自己的功能,就不用重复造轮子了。当然还有更多的细节和高级用法可以根据具体情况进行调整。希望对你有所帮助!