<?php
declare(strict_types=1);
* +----------------------------------------------------------------------
* | ThinkAdmin Plugin for ThinkAdmin
* +----------------------------------------------------------------------
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
* +----------------------------------------------------------------------
* | 官方网站: https://thinkadmin.top
* +----------------------------------------------------------------------
* | 开源协议 ( https://mit-license.org )
* | 免责声明 ( https://thinkadmin.top/disclaimer )
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
* +----------------------------------------------------------------------
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
* +----------------------------------------------------------------------
*/
namespace think\admin\service;
use think\admin\Library;
use think\admin\Service;
* 图形验证码服务
* @class CaptchaService
*/
class CaptchaService extends Service
{
private $code;
private $uniqid;
private $charset = 'ABCDEFGHKMNPRSTUVWXYZ23456789';
private $width = 130;
private $height = 50;
private $length = 4;
private $fontsize = 20;
* 输出图形验证码
* @return string
*/
public function __toString()
{
return $this->getData();
}
* 验证码服务初始化.
* @return static
*/
public function initialize(array $config = []): CaptchaService
{
foreach ($config as $k => $v) {
if (isset($this->{$k})) {
$this->{$k} = $v;
}
}
$this->uniqid = uniqid('captcha') . mt_rand(1000, 9999);
[$this->code, $length] = ['', strlen($this->charset) - 1];
for ($i = 0; $i < $this->length; ++$i) {
$this->code .= $this->charset[mt_rand(0, $length)];
}
$this->app->cache->set($this->uniqid, $this->code, 360);
return $this;
}
* 动态切换配置.
* @return $this
*/
public function config(array $config = []): CaptchaService
{
return $this->initialize($config);
}
* 获取验证码值
*/
public function getCode(): string
{
return $this->code;
}
* 获取图片的内容.
*/
public function getData(): string
{
return "data:image/png;base64,{$this->_image()}";
}
* 获取验证码编号.
*/
public function getUniqid(): string
{
return $this->uniqid;
}
* 获取验证码数据.
*/
public function getAttrs(): array
{
return [
'code' => $this->getCode(),
'data' => $this->getData(),
'uniqid' => $this->getUniqid(),
];
}
* 获取字体文件.
*/
public static function font(): string
{
return __DIR__ . '/bin/captcha.ttf';
}
* 检查验证码是否正确.
* @param string $code 需要验证的值
* @param null|string $uniqid 验证码编号
*/
public static function check(string $code, ?string $uniqid = null): bool
{
$_uni = is_string($uniqid) ? $uniqid : input('uniqid', '-');
$_val = Library::$sapp->cache->get($_uni, '');
if (is_string($_val) && strtolower($_val) === strtolower($code)) {
Library::$sapp->cache->delete($_uni);
return true;
}
return false;
}
* 创建验证码图片.
*/
private function _image(): string
{
$img = imagecreatetruecolor($this->width, $this->height);
$color = imagecolorallocate($img, mt_rand(220, 255), mt_rand(220, 255), mt_rand(220, 255));
imagefilledrectangle($img, 0, $this->height, $this->width, 0, $color);
for ($i = 0; $i < 6; ++$i) {
$color = imagecolorallocate($img, mt_rand(0, 50), mt_rand(0, 50), mt_rand(0, 50));
imageline($img, mt_rand(0, $this->width), mt_rand(0, $this->height), mt_rand(0, $this->width), mt_rand(0, $this->height), $color);
}
for ($i = 0; $i < 100; ++$i) {
$color = imagecolorallocate($img, mt_rand(200, 255), mt_rand(200, 255), mt_rand(200, 255));
imagestring($img, mt_rand(1, 5), mt_rand(0, $this->width), mt_rand(0, $this->height), '*', $color);
}
$_x = $this->width / $this->length;
$fontfile = self::font();
for ($i = 0; $i < $this->length; ++$i) {
$fontcolor = imagecolorallocate($img, mt_rand(0, 156), mt_rand(0, 156), mt_rand(0, 156));
if (function_exists('imagettftext')) {
imagettftext($img, $this->fontsize, mt_rand(-30, 30), intval($_x * $i + mt_rand(1, 5)), intval($this->height / 1.4), $fontcolor, $fontfile, $this->code[$i]);
} else {
imagestring($img, 15, intval($_x * $i + mt_rand(10, 15)), mt_rand(10, 30), $this->code[$i], $fontcolor);
}
}
ob_start();
imagepng($img);
$data = ob_get_contents();
ob_end_clean();
if (version_compare(PHP_VERSION, '8.0.0', '<')) {
imagedestroy($img);
}
return base64_encode($data);
}
}