Skip to content

Commit

Permalink
fix bug running in php8.2
Browse files Browse the repository at this point in the history
  • Loading branch information
isszz committed Jul 28, 2023
1 parent 29ae1e3 commit 87d52e6
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 113 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@


## 避坑
- 务必开启session中间件,验证如果一直提示错误时,注意cookie的作用域,因为tp的sessionID是存储到cookie的,所以cookie作用域配置有问题也会导致无法正确验证
- 非token模式,务必开启session中间件,验证如果一直提示错误时,注意cookie的作用域,因为tp的sessionID是存储到cookie的,所以cookie作用域配置有问题也会导致无法正确验证
- 每个文字首次载入时还是需要读取字体,所以在使用英文,数字的情况缓存下来还是挺快的,因为文字种类比较少,能很快缓存下来
- 如果自行配置`charPreset`为中文,使用中文验证码时,请务必确认所使用字体包含该汉字
- 建议生产环境尽量使用缓存后的字形,提高生成验证码的速度
Expand Down
9 changes: 6 additions & 3 deletions src/Captcha.php
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ public function createMath(array $config = [], bool $api = false): self
$this->initFont($this->config['fontName']);

[$answer, $equation] = $this->random->mathExpr($this->config['mathMin'], $this->config['mathMax'], $this->config['math']);

$this->svg = $this->generate($equation, $answer);

return $this;
Expand Down Expand Up @@ -297,8 +298,8 @@ private function getLineNoise ($width, $height): array

$min = isset($this->config['inverse']) ? 7 : 1;
$max = isset($this->config['inverse']) ? 15 : 9;
$i = -1;

$i = -1;
$noiseLines = [];
while (++$i < $this->config['noise']) {
$start = Random::randomInt(1, 21) . ' ' . Random::randomInt(1, $height - 1);
Expand Down Expand Up @@ -438,11 +439,13 @@ private function encrypter(): object
*/
public function config($config = []): array
{
$defaultConfig = Config::get('scaptcha', []);

if (!empty($config['type'])) {
return array_merge($this->config, Config::get('scaptcha', []), Config::get('scaptcha.'. $config['type'], []), $config);
return array_merge($this->config, $defaultConfig, Config::get('scaptcha.' . $config['type'], []), $config);
}

return array_merge($this->config, Config::get('scaptcha', []), (array) $config);
return array_merge($this->config, $defaultConfig, (array) $config);
}

/**
Expand Down
59 changes: 32 additions & 27 deletions src/Ch2Path.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class Ch2Path
public $unitsPerEm;

public $fontName;
public $i = 0;
public $cache;

public function __construct($fontName)
{
Expand All @@ -42,22 +42,38 @@ public function __construct($fontName)
* 生成文字svg path
*
* @param string $text
* @param array $opts
* @param array $options
* @return object
*/
public function get($text, $opts)
public function get($text, $options)
{
$data = null;

// 开启缓存字形
if (!empty($opts['cache'])) {
unset($opts['cache']);
if (!empty($options['cache'])) {
unset($options['cache']);
// 取字形缓存
$data = $this->cache->get($text);
}

if (is_null($data)) {
$this->getGlyph($this->fontName);

if(empty($this->font)) {
throw new CaptchaException('Please load the font first.');
}

$fontSize = $options['size'];
$unitsPerEm = $this->unitsPerEm;
$ascender = $this->ascender;
$descender = $this->descender;
$fontScale = bcdiv("{$fontSize}", "{$unitsPerEm}", 18);

$this->glyph = new Glyph($unitsPerEm, $this->fontName);

if ($data) {
$glyphWidth = $this->charToGlyphPath($text);

} else {
$fontSize = $data['size'];
$unitsPerEm = $data['unitsPerEm'];
$fontScale = bcdiv("{$fontSize}", "{$unitsPerEm}", 18);
Expand All @@ -72,34 +88,23 @@ public function get($text, $opts)
// get points cache
$points = $this->cache->get($text, 'points');
$this->glyph->buildPath($points);

} else {

$this->getGlyph($this->fontName);

if(empty($this->font)) {
throw new CaptchaException('Please load the font first.');
}

$fontSize = $opts['size'];
$unitsPerEm = $this->unitsPerEm;
$ascender = $this->ascender;
$descender = $this->descender;
$fontScale = bcdiv("{$fontSize}", "{$this->unitsPerEm}", 18);

$this->glyph = new Glyph($unitsPerEm, $this->fontName);

$glyphWidth = $this->charToGlyphPath($text);
}

$width = $glyphWidth * $fontScale;
$left = $options['x'] - $width / 2;
$height = ($ascender + $descender) * $fontScale;
$top = $options['y'] + $height / 2;

/*
$width = bcmul("{$glyphWidth}", "{$fontScale}", 13);
$left = bcsub("{$opts['x']}", bcdiv("{$width}", '2', 13), 13);
$left = bcsub("{$options['x']}", bcdiv("{$width}", '2', 13), 13);
$height = bcmul(bcadd("{$ascender}", "{$descender}"), "{$fontScale}", 13);
$top = bcadd("{$opts['y']}", bcdiv("{$height}", "2", 14), 14);
$top = bcadd("{$options['y']}", bcdiv("{$height}", "2", 14), 14);
*/

$path = $this->glyph->getPath($left, $top - 4, $fontSize);

if (!$data) {
if (is_null($data)) {
// 写入缓存
$this->cache->put($text, [
'text' => $text,
Expand Down
133 changes: 57 additions & 76 deletions src/Controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@ public function index(Captcha $captcha, \think\Request $request)
$captcha->deleteCache();
}

$data = [];
try {
$data['code'] = 0;
$data['msg'] = 'success';
$data = [
'code' => 0,
'msg' => 'success',
'svg' => null,
'token' => null,
];

try {
$content = (string) $captcha->create($config, true)->base64(isset($config['compress']) ? 2 : 1);

if (app()->isDebug()) {
Expand All @@ -36,8 +39,7 @@ public function index(Captcha $captcha, \think\Request $request)

} catch (\Exception $e) {
$data['code'] = 1;
$data['svg'] = null;
$data['msg'] = $e->getMessage() ?? 'Unknown error';
$data['msg'] = $e->getMessage() ?: 'Unknown error';
}

return json($data);
Expand All @@ -59,7 +61,9 @@ public function svg(Captcha $captcha, \think\Request $request)

$content = (string) $captcha->create($config);

$headers['Content-Length'] = strlen($content);
$headers = [
'Content-Length' => strlen($content),
];

if (app()->isDebug()) {
$headers['X-Scaptcha-Mtime'] = $captcha->mctime(true);
Expand All @@ -73,8 +77,8 @@ public function svg(Captcha $captcha, \think\Request $request)
*/
public function check(Captcha $captcha, \think\Request $request)
{
$code = $request->param('code') ?? null;
$token = $request->param('token') ?? null;
$code = $request->param('code');
$token = $request->param('token');

$json = [
'code' => 0,
Expand All @@ -94,7 +98,7 @@ public function check(Captcha $captcha, \think\Request $request)
}
} catch (\Exception $e) {
$json['code'] = 3;
$json['msg'] = $e->getMessage() ?? 'Unknown error';
$json['msg'] = $e->getMessage() ?: 'Unknown error';
}

return json($json);
Expand All @@ -113,72 +117,49 @@ protected function buildParam($params = [])
return [];
}

// 额外配置类型
if(isset($params['t'])) {
$config['type'] = $params['t'];
}

// 运算模式,1=加法,2=减法,3=乘法,4=除法,或者随机四种
if(!empty($params['m'])) {
if($params['m'] == 1) {
$config['math'] = '+';
} elseif($params['m'] == 2) {
$config['math'] = '-';
} elseif($params['m'] == 3) {
$config['math'] = '*';
} elseif($params['m'] == 4) {
$config['math'] = '/';
} else {
$config['math'] = 'rand';
}
}

// 验证码宽度
if(!empty($params['w'])) {
$config['width'] = $params['w'];
}

// 验证码高度
if(!empty($params['h'])) {
$config['height'] = $params['h'];
}

// 文字大小
if(!empty($params['s'])) {
$config['fontSize'] = $params['s'];
}

// 显示文字数量, 非算数模式有效
if(!empty($params['l'])) {
$config['size'] = $params['l'];
}

// 干扰线条数量
if(!empty($params['n'])) {
$config['noise'] = $params['n'];
}

// 文字是否随机色
if(isset($params['c'])) {
$config['color'] = $params['c'] != '0';
}

// 背景色, fefefe
if(!empty($params['b'])) {
$config['background'] = $params['b'];
}

if(!empty($params['cs'])) {
$config['compress'] = true;
}

if(!empty($params['rt'])) {
$config['cache'] = false;
}

if(!empty($params['reset'])) {
$config['reset'] = true;
}
$configMapping = [
't' => 'type', // 额外配置类型
'w' => 'width', // 验证码宽度
'h' => 'height', // 验证码高度
's' => 'fontSize', // 文字大小
'l' => 'size', // 显示文字数量, 非算数模式有效
'n' => 'noise', // 干扰线条数量
'c' => 'color', // 文字是否随机色
'b' => 'background', // 背景色, fefefe
];

foreach ($params as $key => $value) {
if (isset($configMapping[$key])) {
$config[$configMapping[$key]] = $value;
}
}

// 运算模式,1=加法,2=减法,3=乘法,4=除法,或者随机四种
if (!empty($params['m'])) {
$mathMapping = [
1 => '+',
2 => '-',
3 => '*',
4 => '/',
];

$config['math'] = $mathMapping[$params['m']] ?? 'rand';
}

// api模式输出格式1=svg,2=base64
if (!empty($params['cs'])) {
$config['compress'] = true;
}

// 禁用缓存字形,生产模式不建议禁用
if (!empty($params['rt'])) {
$config['cache'] = false;
}

// 删除已缓存字形,不建议在生产模式一直加在url参数中,否则字形缓存无效,字体文件超过3MB会比较慢
if (!empty($params['reset'])) {
$config['reset'] = true;
}

return $config;
}
Expand Down
1 change: 1 addition & 0 deletions src/font/Glyph.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
class Glyph
{
public $path;
public $fontName;

public function __construct($unitsPerEm, $fontName, $commands = [])
{
Expand Down
8 changes: 2 additions & 6 deletions src/helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,13 @@ function scaptcha_src(array $config = []): string

$confs = [];
foreach ($config as $key => $value) {
if (!isset($defaults[$key])) {
continue;
if (isset($defaults[$key])) {
$confs[] = $key . '/' . $value ?: $defaults[$key];
}

$confs[] = $key . '/' . $value ?: $defaults[$key];
}

$urls = implode('/', $confs);



return \think\facade\Route::buildUrl('/scaptcha/svg/'. $urls);
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/support/Cache.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

class Cache
{
public string $fontName;

public function __construct(string $fontName)
{
$this->fontName = mb_substr($fontName, 0, strpos($fontName, '.'));
Expand Down

0 comments on commit 87d52e6

Please sign in to comment.