实现自己的Composer包

一、Composer简介

Composer 是 PHP 的一个依赖管理工具。它允许你申明项目所依赖的代码库,它会在你的项目中为你安装他们。

二、准备工作

  1. 一个github账号
  2. 一个packagist账号
  3. 一台安装composer的开发机
packagist github composer
packagist注册链接 github注册链接 composer文档

三、发布流程

1.首先在github上创建一个项目

2.把项目克隆到本地

1
git clone git@github.com:chendujin/validator.git

3.进入项目根目录初始化项目

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
➜  validator git:(master) composer init

Welcome to the Composer config generator

This command will guide you through creating your composer.json config.
Package name (<vendor>/<name>) [chendujin/validator]:
Description []: a xdp framework
Author [北行10000 <13341007105@163.com>, n to skip]:
Minimum Stability []: dev
Package Type (e.g. library, project, metapackage, composer-plugin) []:
License []: MIT
Define your dependencies.
Would you like to define your dependencies (require) interactively [yes]?
Search for a package:
Would you like to define your dev dependencies (require-dev) interactively [yes]?
Search for a package:
{
"name": "chendujin/validator",
"description": "各种验证类包",
"type": "library",
"license": "MIT",
"authors": [
{
"name": "chendujin",
"email": "1096381436@qq.com"
}
],
"minimum-stability": "alpha",
"require": {
"php": ">=7.1.0"
},
"autoload": {
"psr-4": {
"DataTrans\\": "src/"
}
}
}
Do you confirm generation [yes]?
Would you like the vendor directory added to your .gitignore [yes]? yes

此时目录下回程车一个composer.json文件,文件内容形如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
"name": "chendujin/validator",
"description": "各种验证类包",
"type": "library",
"license": "MIT",
"authors": [
{
"name": "chendujin",
"email": "1096381436@qq.com"
}
],
"minimum-stability": "alpha",
"require": {
"php": ">=7.1.0"
},
"autoload": {
"psr-4": {
"DataTrans\\": "src/"
}
}
}

4.编写自己的composer包

4.1 此处我创建了一个src目录并实现了Validator类

1
2
3
4
5
6
validator git:(master) ✗ tree
.
├── README.md
├── composer.json
└── src
└── Validator.php

4.2 Validator类

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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
<?php

/**
* 全局数据验证类。
* @author fingerQin
*/

namespace DataTrans;

class Validator {

/**
* 判断是否为合法的用户名。
* @param string $username
* @param int $min_len 最小长度。包含。
* @param int $max_len 最大长度。包含。
* @param string $mode 用户名模式:digit、alpha、digit_alpha、chinese、digit_alpha_chinese、mix
* digit:数字
* aplha:字母
* digit_alpha:数字和字母
* chinese:中文
* digit_alpha_chinese:数字字母中文
* mix:混合型:数字字母中文下划线破折号
* @return bool
*/
public static function is_username($username, $min_len, $max_len, $mode = 'mix') {
switch ($mode) {
case 'digit':
return preg_match("/^\d{{$min_len},{$max_len}}$/", $username) ? true : false;
break;

case 'alpha':
return preg_match("/^([a-zA-Z]){{$min_len},{$max_len}}$/", $username) ? true : false;
break;

case 'digit_alpha':
return preg_match("/^([a-z0-9_-]){{$min_len},{$max_len}}$/", $username) ? true : false;
break;

case 'chinese':
return (preg_match("/^[\x7f-\xff]{{$min_len},{$max_len}}$/", $username)) ? true : false;
break;

case 'digit_alpha_chinese':
return (preg_match("/^[\x7f-\xff|0-9a-zA-Z]{{$min_len},{$max_len}}$/", $username)) ? true : false;
break;

case 'mix':
default:
return (preg_match("/^[\x7f-\xff|0-9a-zA-Z-_]{{$min_len},{$max_len}}$/", $username)) ? true : false;
break;
}
}

/**
* 判断是否为合法的密码。
* @param string $password
* @param int $min_len 最小长度。包含。
* @param int $max_len 最大长度。包含。
* @param string $mode 用户名模式:digit_alpha、mix
* digit_alpha:数字和字母
* mix:混合型:数字字母下划线破折号
* @return bool
*/
public static function is_password($password, $min_len, $max_len, $mode = 'mix') {
switch ($mode) {
case 'digit_alpha':
return preg_match("/^([a-z0-9]){{$min_len},{$max_len}}$/", $password) ? true : false;
break;

case 'mix':
default:
return (preg_match("/^[0-9a-zA-Z-_]{{$min_len},{$max_len}}$/", $password)) ? true : false;
break;
}
}

/**
* 判断是否为QQ号码。
* @param string $qq
* @return boolean
*/
public static function is_qq($qq) {
return preg_match('/^[1-9]\d{4,12}$/', $qq) ? true : false;
}

/**
* 判断是否为手机号码。
* @param string $mobilephone
* @return boolean
*/
public static function is_mobilephone($mobilephone) {
return preg_match('/^13[\d]{9}$|14^[0-9]\d{8}|^15[0-9]\d{8}$|^18[0-9]\d{8}$/', $mobilephone) ? true : false;
}

/**
* 判断是否为座机号码。
* @param string $telphone
* @return boolean
*/
public static function is_telphone($telphone) {
return preg_match('/^((\(\d{2,3}\))|(\d{3}\-))?(\(0\d{2,3}\)|0\d{2,3}-)?[1-9]\d{6,7}(\-\d{1,4})?$/', $telphone) ? true : false;
}

/**
* 判断是否为邮政编码。
* @param string $zipcode
* @return boolean
*/
public static function is_zipcode($zipcode) {
return preg_match('/^[1-9]\d{5}$/', $zipcode) ? true : false;
}

/**
* 判断字母是否在某个区域内。用于判断某个字符只能介于[a-h](包含)之间的类似情况。
* @param string $alpha 原值。
* @param string $start_alpha 起始值。
* @param string $end_alpha 截止值。
* @return boolean
*/
public static function alpha_between($alpha, $start_alpha, $end_alpha) {
if (Validator::is_alpha($alpha) === false) {
return false;
}
if (Validator::is_alpha($start_alpha) === false) {
return false;
}
if (Validator::is_alpha($end_alpha) === false) {
return false;
}
if ($start_alpha >= $end_alpha) {
return false;
}
if ($alpha < $start_alpha) {
return false;
}
if ($alpha > $end_alpha) {
return false;
}
return true;
}

/**
* 判断数字是否在某个区域之间。[2, 10],包含边界值。
* @param int $value 原值。
* @param int $start_value 起始值。
* @param int $end_value 截止值。
* @return boolean
*/
public static function number_between($value, $start_value, $end_value) {
if (is_numeric($value) === false || is_numeric($start_value) === false || is_numeric($end_value) === false) {
return false;
}
if ($start_value >= $end_value) {
return false;
}
if ($value < $start_value) {
return false;
}
if ($value > $end_value) {
return false;
}
return true;
}

/**
* 验证是否为中文。
* @param string $char
* @return bool
*/
public static function is_chinese($char) {
if (strlen($char) === 0) {
return false;
}
return (preg_match("/^[\x7f-\xff]+$/", $char)) ? true : false;
}

/**
* 判断是否为字母、数字、下划线(_)、破折号(-)。
* @param string $str
* @return boolean
*/
public static function is_alpha_dash($str) {
return preg_match('/^([a-z0-9_-])+$/i', $str) ? true : false;
}

/**
* 验证身份证号码是否合法。
* @param string $vStr
* @return bool
*/
public static function is_idcard($vStr) {
$vCity = array(
'11','12','13','14','15','21','22',
'23','31','32','33','34','35','36',
'37','41','42','43','44','45','46',
'50','51','52','53','54','61','62',
'63','64','65','71','81','82','91'
);
if (!preg_match('/^([\d]{17}[xX\d]|[\d]{15})$/', $vStr)) {
return false;
}
if (!in_array(substr($vStr, 0, 2), $vCity)) {
return false;
}
$vStr = preg_replace('/[xX]$/i', 'a', $vStr);
$vLength = strlen($vStr);

if ($vLength == 18) {
$vBirthday = substr($vStr, 6, 4) . '-' . substr($vStr, 10, 2) . '-' . substr($vStr, 12, 2);
} else {
$vBirthday = '19' . substr($vStr, 6, 2) . '-' . substr($vStr, 8, 2) . '-' . substr($vStr, 10, 2);
}
if (date('Y-m-d', strtotime($vBirthday)) != $vBirthday) {
return false;
}
if ($vLength == 18) {
$vSum = 0;
for ($i = 17 ; $i >= 0 ; $i--) {
$vSubStr = substr($vStr, 17 - $i, 1);
$vSum += (pow(2, $i) % 11) * (($vSubStr == 'a') ? 10 : intval($vSubStr, 11));
}
if($vSum % 11 != 1) {
return false;
}
}
return true;
}

/**
* 验证日期时间格式。
* -- 1、验证$value是否为$format格式。
* -- 2、只能验证格式,不能验证时间是否正确。比如:2014-22-22
* @param string $format 格式。格式如:Y-m-d 或H:i:s
* @param string $value 日期。
* @return boolean
*/
public static function is_date_format($format, $value) {
return date_create_from_format($format, $value) !== false;
}

/**
* 判断是否为整数。
* @param string $str
* @return boolean
*/
public static function is_integer($str) {
return filter_var($str, FILTER_VALIDATE_INT) !== false;
}

/**
* 判断是否为字母数字。
* @param string $str
* @return boolean
*/
public static function is_alpha_number($str) {
return preg_match('/^([a-z0-9])+$/i', $str) ? true : false;
}

/**
* 判断是否为字母。
* @param string $str
* @return boolean
*/
public static function is_alpha($str) {
return preg_match('/^([a-z])+$/i', $str) ? true : false;
}

/**
* 验证IP是否合法。
* @param string $ip
* @return bool
*/
public static function is_ip($ip) {
return filter_var($ip, FILTER_VALIDATE_IP) !== false;
}

/**
* 验证URL是否合法。
* -- 合法的URL:http://www.baidu.com
* @param string $url
* @return bool
*/
public static function is_url($url) {
return filter_var($url, FILTER_VALIDATE_URL) !== false;
}

/**
* 判断email格式是否正确。
* @param string $email
* @return bool
*/
function is_email($email) {
return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
}

/**
* 是否必需。
* @param string $str
* @return bool
*/
public static function is_require($str) {
return strlen($str) ? true : false;
}

/**
* 判断字符串是否为utf8编码,英文和半角字符返回ture。
* @param string $string
* @return bool
*/
public static function is_utf8($string) {
return preg_match('%^(?:
[\x09\x0A\x0D\x20-\x7E] # ASCII
| [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
| \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
| \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
| \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
| [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
| \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
)*$%xs', $string) ? true : false;
}

/**
* 检查字符串长度。
* @param string $str 字符串。
* @param int $min 最小长度。
* @param int $max 最大长度。
* @param bool $is_utf8 是否UTF-8字符。
* @return boolean
*/
public static function len($str, $min = 0, $max = 255, $is_utf8 = false) {
$len = $is_utf8 ? mb_strlen($str) : strlen($str);
if (($len >= $min) && ($len <= $max)) {
return true;
} else {
return false;
}
}
}

4.3 自动加载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
4.2添加了src的加载运行composer install实现自动加载
➜ validator git:(master) ✗ composer install
Loading composer repositories with package information
Updating dependencies (including require-dev)
Nothing to install or update
Generating autoload files
此时目录中会生成一个vendor 它实现了加载方法
➜ validator git:(master) ✗ tree
.
├── README.md
├── composer.json
├── src
│ └── Validator.php
└── vendor
├── autoload.php
└── composer
├── ClassLoader.php
├── LICENSE
├── autoload_classmap.php
├── autoload_namespaces.php
├── autoload_psr4.php
├── autoload_real.php
├── autoload_static.php
└── installed.json

4.4 测试结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
创建test.php
<?php
require '../vendor/autoload.php';

use \DataTrans\Validator;

$mobilephone = '18665027895';
$ok = Validator::is_mobilephone($mobilephone);
if ($ok) {
echo '是手机号码';
} else {
echo '不是手机号码';
}
命令行中运行
➜ validator git:(master) ✗ php test.php
是手机号码

4.5 忽略vendor、composer.json文件

1
2
3
4
修改.gitignore增加下面两行
.vscode
/vendor/
composer.lock

4.6提交代码到 github

1
2
3
git add .
git commit -m "提交Validator扩展包"
git push origin master

5. Packagist配置

5.1 github关联到Packagist

  1. 首先要在Packagist上登录
  2. 点击顶部导航条中的Summit按钮
  3. 在输入框中输入github上的仓库地址,如:git@github.com:chendujin/validator.git
  4. 然后点击Check按钮
  5. Packagist会去检测此仓库地址的代码是否符合Composer的Package包的要求
  6. 检测正常的话,会出现Submit按钮,再点击一下Submit按钮,我们的包就提交到Packagist上了

5.2 配置自动同步

  1. 从Packagist点击个人中心点击profile获取token然后复制
  2. 到github项目首页上点击settings、点击webhooks、点击addwebhook
  3. https://packagist.org/api/bitbucket?username=USERNAME&apiToken=TOKEN 复制到Payload URL,在下方输入密码后保存

四、引用包

1
composer require chendujin/validator

注意事项

如果下载不下来到话就换一下镜像
composer config -g repo.packagist composer https://packagist.laravel-china.org
刚发布上去可能会下载不到,没有同步过来– 可以等一会在试试看


实现自己的Composer包
https://www.chendujin.com/posts/5339145e.html
作者
托马斯
发布于
2022年4月5日
许可协议