EasySwoole 验证码组件

EasySwoole 提供了独立的 验证码组件 ,几行代码即可实现输出一个验证码,支持用户自定义验证码字体

组件要求

  • php: >=7.1
  • ext-gd: *
  • easyswoole/spl: ^1.0

安装方法

composer require easyswoole/verifycode=3.x

仓库地址

easyswoole/verifycode=3.x

基本使用

配置

生成验证码前需要传入 \EasySwoole\VerifyCode\Conf 的对象实例,\EasySwoole\VerifyCode\Conf 类实例化后会有默认配置,无需配置也可生成验证码图片。

下面是 \EasySwoole\VerifyCode\Conf 类提供的相关配置方法。

  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | easySwoole [ use swoole easily just like echo "hello world" ]
  4. // +----------------------------------------------------------------------
  5. // | WebSite: https://www.easyswoole.com
  6. // +----------------------------------------------------------------------
  7. // | Welcome Join QQGroup 853946743
  8. // +----------------------------------------------------------------------
  9. namespace EasySwoole\VerifyCode;
  10. use EasySwoole\Spl\SplBean;
  11. /**
  12. * 验证码配置文件
  13. * Class VerifyCodeConf
  14. * @author : evalor <master@evalor.cn>
  15. * @package Vendor\VerifyCode
  16. */
  17. class Conf extends SplBean
  18. {
  19. public $charset = '1234567890AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz'; // 字母表
  20. public $useCurve = false; // 混淆曲线
  21. public $useNoise = false; // 随机噪点
  22. public $useFont = null; // 指定字体
  23. public $fontColor = null; // 字体颜色
  24. public $backColor = null; // 背景颜色
  25. public $imageL = null; // 图片宽度
  26. public $imageH = null; // 图片高度
  27. public $fonts = []; // 额外字体
  28. public $fontSize = 25; // 字体大小
  29. public $length = 4; // 生成位数
  30. public $mime = MIME::PNG; // 设置类型
  31. public $temp = '/tmp'; // 设置缓存目录
  32. public function setTemp($temp){
  33. if (!is_dir($temp)) mkdir($temp,0755) && chmod($temp,0755);
  34. $this->temp = $temp;
  35. }
  36. /**
  37. * 设置图片格式
  38. * @param $MimeType
  39. * @author : evalor <master@evalor.cn>
  40. * @return Conf
  41. */
  42. public function setMimeType($MimeType)
  43. {
  44. $allowMime = [ MIME::PNG, MIME::GIF, MIME::JPG ];
  45. if (in_array($MimeType, $allowMime)) $this->mime = $MimeType;
  46. return $this;
  47. }
  48. /**
  49. * 设置字符集
  50. * @param string $charset
  51. * @return Conf
  52. */
  53. public function setCharset($charset)
  54. {
  55. is_string($charset) && $this->charset = $charset;
  56. return $this;
  57. }
  58. /**
  59. * 开启混淆曲线
  60. * @param bool $useCurve
  61. * @return Conf
  62. */
  63. public function setUseCurve($useCurve = true)
  64. {
  65. is_bool($useCurve) && $this->useCurve = $useCurve;
  66. return $this;
  67. }
  68. /**
  69. * 开启噪点生成
  70. * @param bool $useNoise
  71. * @return Conf
  72. */
  73. public function setUseNoise($useNoise = true)
  74. {
  75. is_bool($useNoise) && $this->useNoise = $useNoise;
  76. return $this;
  77. }
  78. /**
  79. * 使用自定义字体
  80. * @param string $useFont
  81. * @return Conf
  82. */
  83. public function setUseFont($useFont)
  84. {
  85. is_string($useFont) && $this->useFont = $useFont;
  86. return $this;
  87. }
  88. /**
  89. * 设置文字颜色
  90. * @param array|string $fontColor
  91. * @return Conf
  92. */
  93. public function setFontColor($fontColor)
  94. {
  95. if (is_string($fontColor)) $this->fontColor = $this->HEXToRGB($fontColor);
  96. if (is_array($fontColor)) $this->fontColor = $fontColor;
  97. return $this;
  98. }
  99. /**
  100. * 设置背景颜色
  101. * @param null $backColor
  102. * @return Conf
  103. */
  104. public function setBackColor($backColor)
  105. {
  106. if (is_string($backColor)) $this->backColor = $this->HEXToRGB($backColor);
  107. if (is_array($backColor)) $this->backColor = $backColor;
  108. return $this;
  109. }
  110. /**
  111. * 设置图片宽度
  112. * @param int|string $imageL
  113. * @return Conf
  114. */
  115. public function setImageWidth($imageL)
  116. {
  117. $this->imageL = intval($imageL);
  118. return $this;
  119. }
  120. /**
  121. * 设置图片高度
  122. * @param null $imageH
  123. * @return Conf
  124. */
  125. public function setImageHeight($imageH)
  126. {
  127. $this->imageH = intval($imageH);
  128. return $this;
  129. }
  130. /**
  131. * 设置字体集
  132. * @param array|string $fonts
  133. * @return Conf
  134. */
  135. public function setFonts($fonts)
  136. {
  137. if (is_string($fonts)) array_push($this->fonts, $fonts);
  138. if (is_array($fonts) && !empty($fonts)) {
  139. if (empty($this->fonts)) {
  140. $this->fonts = $fonts;
  141. } else {
  142. array_merge($this->fonts, $fonts);
  143. }
  144. }
  145. return $this;
  146. }
  147. /**
  148. * 设置字体尺寸
  149. * @param int $fontSize
  150. * @return Conf
  151. */
  152. public function setFontSize($fontSize)
  153. {
  154. $this->fontSize = intval($fontSize);
  155. return $this;
  156. }
  157. /**
  158. * 设置验证码长度
  159. * @param int $length
  160. * @return Conf
  161. */
  162. public function setLength($length)
  163. {
  164. $this->length = intval($length);
  165. return $this;
  166. }
  167. /**
  168. * 获取配置值
  169. * @param $name
  170. * @author : evalor <master@evalor.cn>
  171. * @return mixed
  172. */
  173. public function __get($name)
  174. {
  175. return $this->$name;
  176. }
  177. /**
  178. * 十六进制转RGB
  179. * @param $hexColor
  180. * @author : evalor <master@evalor.cn>
  181. * @return array
  182. */
  183. function HEXToRGB($hexColor)
  184. {
  185. $color = str_replace('#', '', $hexColor);
  186. if (strlen($color) > 3) {
  187. $rgb = array(
  188. hexdec(substr($color, 0, 2)),
  189. hexdec(substr($color, 2, 2)),
  190. hexdec(substr($color, 4, 2))
  191. );
  192. } else {
  193. $color = $hexColor;
  194. $r = substr($color, 0, 1) . substr($color, 0, 1);
  195. $g = substr($color, 1, 1) . substr($color, 1, 1);
  196. $b = substr($color, 2, 1) . substr($color, 2, 1);
  197. $rgb = array(
  198. hexdec($r),
  199. hexdec($g),
  200. hexdec($b)
  201. );
  202. }
  203. return $rgb;
  204. }
  205. }

配置方法

需要对验证码进行自定义配置可以使用上文提到的组件提供的 \EasySwoole\VerifyCode\Conf 类进行动态配置。

  1. use EasySwoole\VerifyCode\Conf;
  2. $Conf = new Conf();

设置字符集合

可以自定义验证码生成时使用的字符集合,设置后从集合中随机选取,不设置则从 [0-9A-Za-z] 中随机选取

  1. $Conf->setCharset('123456ABCD');

设置背景色

设置验证码的背景颜色,不设置则默认使用白色,支持使用完整 HEX、缩写 HEX 和 RGB 值设置

  1. $Conf->setBackColor('#3A5FCD');
  2. $Conf->setBackColor('CCC');
  3. $Conf->setBackColor([30, 144, 255]);

设置文字颜色

设置验证码的文字颜色,不设置则随机生成一个颜色,支持使用完整 HEX、缩写 HEX 和 RGB 值设置

  1. $Conf->setFontColor('#3A5FCD');
  2. $Conf->setFontColor('CCC');
  3. $Conf->setFontColor([30, 144, 255]);

设置混淆

支持两种混淆方式,默认两种混淆都是关闭的,需要手动开启

  1. // 开启或关闭混淆曲线
  2. $Conf->setUseCurve();
  3. // 开启或关闭混淆噪点
  4. $Conf->setUseNoise();

设置字体

默认验证码类已经带有 6 种字体,如果需要增加自己的字体库来提高识别难度,或者指定使用的字体,可以进行如下设置,注意字体路径需要使用绝对路径,即文件的完整路径

  1. // 增加单个字体传入路径字符串
  2. $Conf->setFonts('path/to/file.ttf');
  3. // 增加多个字体传入路径的数组
  4. $Conf->setFonts(['path/to/file1.ttf', 'path/to/file2.ttf']);
  5. // 指定生成使用的字体文件
  6. $Conf->setUseFont('path/to/file.ttf');

其他设置

可以指定验证码图片宽高,字体大小,随机生成的验证码位数等

  1. // 设置验证码图片的宽度
  2. $Conf->setImageWidth(400);
  3. // 设置验证码图片的高度
  4. $Conf->setImageHeight(200);
  5. // 设置生成字体大小
  6. $Conf->setFontSize(30);
  7. // 设置生成验证码位数
  8. $Conf->setLength(4);

链式调用

为了更流畅的进行设置,所有的配置项均支持链式调用

  1. $Conf = new Conf();
  2. $Conf->setUseNoise()->setUseCurve()->setFontSize(30);

可以使用上方的动态配置,将设置好的配置类传入给验证码类。

  1. $Conf = new \EasySwoole\VerifyCode\Conf();
  2. $Conf->setFontSize(30);
  3. $VCode = new \EasySwoole\VerifyCode\VerifyCode($Conf);

如果配置比较多,也需要全站统一验证码配置,可以将验证码的配置放入配置文件,在生成时读取配置,验证码的配置类继承自 \EasySwoole\Spl\SplBean,可以在设置好后使用配置类的 toArray 方法直接获得配置数组,实例化验证码时,读取数组重新生成 \EasySwoole\VerifyCode\Conf 类即可。

验证码生成

\EasySwoole\VerifyCode\VerifyCode 验证码操作类,如果不传入 \EasySwoole\VerifyCode\Conf 实例,则自动实例化一个 \EasySwoole\VerifyCode\Conf 实例。

  1. <?php
  2. $config = new \EasySwoole\VerifyCode\Conf([
  3. // 以下配置均为可选配置,用户可根据需求自行配置
  4. # 'charset' => '1234567890AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz', # 设置验证码字符集合,默认为 数字 + 大小写字母
  5. # 'useCurve' => false, # 设置不开启 混淆曲线,默认不开启
  6. # 'useNoise' => false, # 设置不开启 随机噪点,默认不开启
  7. # 'useFont' => null, # 设置验证码使用的字体,默认随机获取内置字体
  8. # 'fontColor' => null, # 设置 字体颜色,默认随机获取,支持使用完整 HEX,缩写 HEX 和 RGB 值设置
  9. # 'backColor' => null, # 设置 背景颜色,默认白色,支持使用完整 HEX,缩写 HEX 和 RGB 值设置
  10. # 'imageL' => null, # 设置 验证码宽度,默认 162.5px
  11. # 'imageH' => null, # 设置 验证码高度,默认 50px
  12. # 'fonts' => [], # 设置 验证码可能使用的字体集合,默认组件内置支持 5 种
  13. # 'fontSize' => 25, # 设置 验证码字体大小,默认 25px
  14. # 'length' => 4, # 设置 验证码位数,默认 4 位
  15. ]);
  16. # 使用方法单独配置 和 上述在构造函数中配置 等价
  17. // 设置验证码长度为 4 【其他配置方法请看上文 \EasySwoole\VerifyCode\Conf 类】
  18. # $config->setLength(4);
  19. $code = new \EasySwoole\VerifyCode\VerifyCode($config);
  20. $code->DrawCode();// 生成验证码,返回一个 \EasySwoole\VerifyCode\Result 对象

验证码结果类

验证码结果类,由 VerifyCode 验证码操作类调用 DrawCode() 方法时创建并返回。

下面是 \EasySwoole\VerifyCode\Result 类的具体实现,可获取创建验证码之后得到相关结果。

  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | easySwoole [ use swoole easily just like echo "hello world" ]
  4. // +----------------------------------------------------------------------
  5. // | WebSite: https://www.easyswoole.com
  6. // +----------------------------------------------------------------------
  7. // | Welcome Join QQGroup 853946743
  8. // +----------------------------------------------------------------------
  9. namespace EasySwoole\VerifyCode;
  10. /**
  11. * 验证码结果类
  12. * Class Result
  13. * @author : evalor <master@evalor.cn>
  14. * @package easySwoole\VerifyCode
  15. */
  16. class Result
  17. {
  18. private $captchaByte; // 验证码图片
  19. private $captchaMime; // 验证码类型
  20. private $captchaCode; // 验证码内容
  21. private $createTime;
  22. function __construct($Byte, $Code, $Mime)
  23. {
  24. $this->captchaByte = $Byte;
  25. $this->captchaMime = $Mime;
  26. $this->captchaCode = $Code;
  27. $this->createTime = time();
  28. }
  29. function getCreateTime():int
  30. {
  31. return $this->createTime;
  32. }
  33. function getCodeHash($code = null,$time = null)
  34. {
  35. if(!$code){
  36. $code = $this->captchaCode;
  37. }
  38. if(!$time){
  39. $time = $this->createTime;
  40. }
  41. return substr(md5($code.$time),8,16);
  42. }
  43. /**
  44. * 获取验证码图片
  45. * @author : evalor <master@evalor.cn>
  46. * @return mixed
  47. */
  48. function getImageByte()
  49. {
  50. return $this->captchaByte;
  51. }
  52. /**
  53. * 返回图片Base64字符串
  54. * @author : evalor <master@evalor.cn>
  55. * @return string
  56. */
  57. function getImageBase64()
  58. {
  59. $base64Data = base64_encode($this->captchaByte);
  60. $Mime = $this->captchaMime;
  61. return "data:{$Mime};base64,{$base64Data}";
  62. }
  63. /**
  64. * 获取验证码内容
  65. * @author : evalor <master@evalor.cn>
  66. * @return mixed
  67. */
  68. function getImageCode()
  69. {
  70. return $this->captchaCode;
  71. }
  72. /**
  73. * 获取Mime信息
  74. * @author : evalor <master@evalor.cn>
  75. */
  76. function getImageMime()
  77. {
  78. return $this->captchaMime;
  79. }
  80. }

使用示例

  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: Apple
  5. * Date: 2018/11/12 0012
  6. * Time: 16:30
  7. */
  8. namespace App\HttpController;
  9. use EasySwoole\Http\AbstractInterface\Controller;
  10. use EasySwoole\VerifyCode\Conf;
  11. class VerifyCode extends Controller
  12. {
  13. function index()
  14. {
  15. // 配置验证码
  16. $config = new Conf();
  17. $code = new \EasySwoole\VerifyCode\VerifyCode($config);
  18. // 生成验证码
  19. $drawCode = $code->DrawCode();
  20. // 获取生成的验证码内容字符串 string(4) "0rnh"
  21. // 可存储起来和用户输入的验证码比对
  22. $codeStr = $drawCode->getImageCode();
  23. // 设置响应文件内容类型
  24. $this->response()->withHeader('Content-Type','image/png');
  25. // 向客户端输出验证码图片
  26. $this->response()->write($drawCode->getImageByte());
  27. }
  28. function getBase64()
  29. {
  30. // 配置验证码
  31. $config = new Conf();
  32. $code = new \EasySwoole\VerifyCode\VerifyCode($config);
  33. // 生成验证码
  34. $drawCode = $code->DrawCode();
  35. // 获取生成的验证码内容字符串 string(4) "0rnh"
  36. // 可存储起来和用户输入的验证码比对
  37. $codeStr = $drawCode->getImageCode();
  38. // 向客户端输出验证码的 base64 编码,前端可用来生成图片
  39. $this->response()->write($drawCode->getImageBase64());
  40. }
  41. }

访问 http://localhost:9501/VerifyCode/index (示例请求地址) 即可看到验证码图片,访问 http://localhost:9501/VerifyCode/getBase64 (示例请求地址) 即可得到验证码图片的 base64 编码结果。

进阶使用

生成二维码图片并返回,然后进行校验。

首先新建一个验证码工具类 \App\Utility\VerifyCodeTools,内容如下所示:

  1. <?php
  2. /**
  3. * User: luffyQAQ
  4. * Date: 2019/9/5 15:29
  5. * Email: <1769360227@qq.com>
  6. */
  7. namespace App\Utility;
  8. class VerifyCodeTools
  9. {
  10. const DURATION = 5 * 60;
  11. // 校验验证码
  12. public static function checkVerifyCode($code, $time, $hash)
  13. {
  14. if ($time + self::DURATION < time()) {
  15. return false;
  16. }
  17. $code = strtolower($code);
  18. return self::getVerifyCodeHash($code, $time) == $hash;
  19. }
  20. // 生成验证码 hash 字符串
  21. public static function getVerifyCodeHash($code, $time)
  22. {
  23. return md5($code . $time);
  24. }
  25. }

生成验证码及对验证码进行校验。

  1. <?php
  2. /**
  3. * User: luffyQAQ
  4. * Date: 2019/9/5 15:29
  5. * Email: <1769360227@qq.com>
  6. */
  7. namespace App\HttpController;
  8. use App\Utility\VerifyCodeTools;
  9. use EasySwoole\Http\AbstractInterface\Controller;
  10. use EasySwoole\Http\Message\Status;
  11. use EasySwoole\Utility\Random;
  12. use EasySwoole\VerifyCode\Conf;
  13. class VerifyCode extends Controller
  14. {
  15. static $VERIFY_CODE_TTL = 120;
  16. static $VERIFY_CODE_LENGTH = 4;
  17. // 生成验证码
  18. public function verifyCode()
  19. {
  20. // 配置验证码
  21. $config = new Conf();
  22. $code = new \EasySwoole\VerifyCode\VerifyCode($config);
  23. // 获取随机数(即验证码的具体值)
  24. $random = Random::character(self::$VERIFY_CODE_LENGTH, '1234567890abcdefghijklmnopqrstuvwxyz');
  25. // var_dump($random); string(4) "m02t"
  26. // 绘制验证码
  27. $code = $code->DrawCode($random);
  28. // 获取验证码的 base64 编码及设置验证码有效时间
  29. $time = time();
  30. $result = [
  31. 'verifyCode' => $code->getImageBase64(), // 得到绘制验证码的 base64 编码字符串
  32. 'verifyCodeTime' => $time,
  33. ];
  34. // 将验证码加密存储在 Cookie 中,方便进行后续验证。用户也可以把验证码保存在 Session 或者 Redis中,方便后续验证。
  35. $this->response()->setCookie("verifyCodeHash", VerifyCodeTools::getVerifyCodeHash($random, $time), $time + self::$VERIFY_CODE_TTL, '/');
  36. $this->response()->setCookie('verifyCodeTime', $time, $time + self::$VERIFY_CODE_TTL, '/');
  37. $this->writeJson(Status::CODE_OK, $result, 'success');
  38. }
  39. // 校验验证码
  40. public function checkVerifyCode()
  41. {
  42. $code = $this->request()->getRequestParam('code');
  43. $verifyCodeHash = $this->request()->getRequestParam('verifyCodeHash');
  44. $verifyCodeTime = $this->request()->getRequestParam('verifyCodeTime');
  45. if (!VerifyCodeTools::checkVerifyCode($code, $verifyCodeTime, $verifyCodeHash)) {
  46. $this->writeJson(Status::CODE_OK, '验证码错误!', []);
  47. }
  48. $this->writeJson(Status::CODE_OK, '验证码正确!', []);
  49. }
  50. }

调用对应的路径接口(即访问 http://localhost:9501/VerifyCode/verifyCode [示例请求地址]),即可实现前台验证码显示。在 http://localhost:9501/VerifyCode/checkVerifyCode [示例请求地址] 接口中传递参数即可校验验证码是否正确。