mirror of
http://124.126.16.154:8888/singularity/HyperfDevelopmentKitCore.git
synced 2026-01-15 06:55:06 +08:00
feat(utils): 重写了构造URL的方法,增加对应的单元测试
This commit is contained in:
@@ -7,9 +7,8 @@ namespace Singularity\HDK\Core\Service;
|
|||||||
use Closure;
|
use Closure;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Generator;
|
use Generator;
|
||||||
use Hyperf\Contract\StdoutLoggerInterface;
|
|
||||||
use Hyperf\Di\Annotation\Inject;
|
|
||||||
use Hyperf\HttpServer\Contract\RequestInterface;
|
use Hyperf\HttpServer\Contract\RequestInterface;
|
||||||
|
use JetBrains\PhpStorm\NoReturn;
|
||||||
use JetBrains\PhpStorm\Pure;
|
use JetBrains\PhpStorm\Pure;
|
||||||
use Psr\Http\Message\ResponseInterface;
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
|
||||||
@@ -18,47 +17,38 @@ use Psr\Http\Message\ResponseInterface;
|
|||||||
*/
|
*/
|
||||||
class UtilsService
|
class UtilsService
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @Inject
|
|
||||||
* @var RequestInterface
|
|
||||||
*/
|
|
||||||
private RequestInterface $request;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Inject()
|
|
||||||
* @var StdoutLoggerInterface
|
|
||||||
*/
|
|
||||||
private StdoutLoggerInterface $logger;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成验证码
|
* 生成验证码
|
||||||
*
|
*
|
||||||
* @param int $length
|
* @param int $length
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
|
#[Pure]
|
||||||
public function generateSecureCode(int $length = 4): string
|
public function generateSecureCode(int $length = 4): string
|
||||||
{
|
{
|
||||||
$code = '';
|
$code = '';
|
||||||
for ($times = 0; $times < $length; $times++) {
|
for ($times = 0; $times < $length; $times++) {
|
||||||
$code .= rand(1, 9);
|
$code .= random_int(1, 9);
|
||||||
}
|
}
|
||||||
return $code;
|
return $code;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getRealIpAddress(): string
|
/**
|
||||||
|
* 获取真实IP
|
||||||
|
* @param RequestInterface $request
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getRealIpAddress(RequestInterface $request): string
|
||||||
{
|
{
|
||||||
$ip = $this->request->server('remote_addr');
|
$x_real_ip = $request->header('x-real-ip');
|
||||||
if (empty($ip) or in_array(
|
var_dump(__METHOD__ . 'x-real-ip: ' . $x_real_ip);
|
||||||
$ip,
|
$remote_addr = $request->server('remote_addr');
|
||||||
[
|
var_dump(__METHOD__ . 'remote_addr: ' . $remote_addr);
|
||||||
'localhost',
|
return $x_real_ip
|
||||||
'127.0.0.1',
|
?? $remote_addr
|
||||||
]
|
?? 'unknown';
|
||||||
)) {
|
|
||||||
$ip = $this->request->header('x-real-ip');
|
|
||||||
}
|
|
||||||
return $ip ?? 'unknown';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -108,18 +98,74 @@ class UtilsService
|
|||||||
* 构建 URL
|
* 构建 URL
|
||||||
*
|
*
|
||||||
* @param string $url
|
* @param string $url
|
||||||
* @param array<string, string> $params
|
* @param array<string, string> $moreQueries 要附加的 query 参数
|
||||||
*
|
* @param bool $anchorQuery 开启后,query 参数将被尽量组合到锚点中,以支持 spa 路由
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function buildUrl(string $url, array $params = []): string
|
#[Pure]
|
||||||
|
public function buildUrl(string $url, array $moreQueries = [], bool $anchorQuery = false): string
|
||||||
{
|
{
|
||||||
$url_info = parse_url($url);
|
if (count($moreQueries) === 0) {
|
||||||
$base_url = str_replace('?' . $url_info['query'], '', $url);
|
return $url;
|
||||||
parse_str($url_info['query'], $origin_params);
|
}
|
||||||
$origin_params += $params;
|
|
||||||
|
|
||||||
return $base_url . '?' . http_build_query($origin_params);
|
$url_info = parse_url($url);
|
||||||
|
|
||||||
|
$result = '';
|
||||||
|
// 协议
|
||||||
|
if (isset($url_info['scheme'])) {
|
||||||
|
$result .= $url_info['scheme'];
|
||||||
|
}
|
||||||
|
// 域名
|
||||||
|
if (isset($url_info['host'])) {
|
||||||
|
if (!empty($result)) {
|
||||||
|
$result .= ':';
|
||||||
|
}
|
||||||
|
$result .= '//';
|
||||||
|
// 用户名
|
||||||
|
if (isset($url_info['user'])) {
|
||||||
|
$result .= $url_info['user'];
|
||||||
|
// 密码
|
||||||
|
if (isset($url_info['pass'])) {
|
||||||
|
$result .= ':' . $url_info['pass'];
|
||||||
|
}
|
||||||
|
$result .= '@';
|
||||||
|
}
|
||||||
|
$result .= $url_info['host'];
|
||||||
|
}
|
||||||
|
// 端口
|
||||||
|
if (isset($url_info['port'])) {
|
||||||
|
$result .= ':' . $url_info['port'];
|
||||||
|
}
|
||||||
|
// 路径
|
||||||
|
$result .= $url_info['path'];
|
||||||
|
// 查询参数
|
||||||
|
if (!empty($url_info['query'])) {
|
||||||
|
$query_params = $url_info['query'];
|
||||||
|
parse_str($query_params, $origin_params);
|
||||||
|
if (!$anchorQuery) {
|
||||||
|
$origin_params += $moreQueries;
|
||||||
|
}
|
||||||
|
$result .= '?' . http_build_query($origin_params);
|
||||||
|
} else {
|
||||||
|
if (!$anchorQuery) {
|
||||||
|
$result .= '?' . http_build_query($moreQueries);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 锚点
|
||||||
|
if (!empty($url_info['fragment'])) {
|
||||||
|
$fragment = $url_info['fragment'];
|
||||||
|
if ($anchorQuery) {
|
||||||
|
$fragment_data = parse_url($url_info['fragment']);
|
||||||
|
parse_str($fragment_data['query'] ?? '', $hash_queries);
|
||||||
|
$hash_queries += $moreQueries;
|
||||||
|
|
||||||
|
$fragment = $fragment_data['path'] . '?' . http_build_query($hash_queries);
|
||||||
|
}
|
||||||
|
$result .= '#' . $fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -191,6 +237,7 @@ class UtilsService
|
|||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
|
#[NoReturn]
|
||||||
public function unlimitedSubCategoriesQuicklyWithLevel(
|
public function unlimitedSubCategoriesQuicklyWithLevel(
|
||||||
array &$list,
|
array &$list,
|
||||||
int $level = 1,
|
int $level = 1,
|
||||||
@@ -198,11 +245,7 @@ class UtilsService
|
|||||||
string $childrenName = 'children',
|
string $childrenName = 'children',
|
||||||
?Closure $filterCallback = null
|
?Closure $filterCallback = null
|
||||||
): void {
|
): void {
|
||||||
$start_time = microtime(true);
|
|
||||||
$max_times = count($list);
|
|
||||||
$current_times = 0;
|
|
||||||
foreach ($list as $i => &$item) {
|
foreach ($list as $i => &$item) {
|
||||||
$current_times++;
|
|
||||||
if (!isset($item[$parentIdName])) {
|
if (!isset($item[$parentIdName])) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -221,11 +264,6 @@ class UtilsService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
$list = $list[$childrenName];
|
$list = $list[$childrenName];
|
||||||
$end_time = microtime(true);
|
|
||||||
$this->logger->debug("快速无极分类循环{$current_times}次,数组元素数量$max_times");
|
|
||||||
|
|
||||||
$cost_time = ($end_time - $start_time) * 1000;
|
|
||||||
$this->logger->debug("快速无极分类用时{$cost_time}ms");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -47,4 +47,4 @@ it('asserts oss policy can be generated', function ($setDir, $isImage, $maxSize)
|
|||||||
->and($signature)->toBe($sign);
|
->and($signature)->toBe($sign);
|
||||||
})->with([
|
})->with([
|
||||||
['uploaded', true, 1048576000],
|
['uploaded', true, 1048576000],
|
||||||
])->only();
|
]);
|
||||||
|
|||||||
62
tests/Unit/UtilsServiceTest.php
Normal file
62
tests/Unit/UtilsServiceTest.php
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* UtilsServiceTest.php@HDK-Core
|
||||||
|
*
|
||||||
|
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2023/1/12
|
||||||
|
*/
|
||||||
|
|
||||||
|
use Singularity\HDK\Core\Service\UtilsService;
|
||||||
|
|
||||||
|
$utils = new UtilsService();
|
||||||
|
|
||||||
|
$length_data = [];
|
||||||
|
for ($i = 0; $i < 5; $i++) {
|
||||||
|
try {
|
||||||
|
$length_data[] = random_int(1, 9);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
test('断言验证码可以正常生成指定长度', function (int $length) use ($utils) {
|
||||||
|
try {
|
||||||
|
$code = $utils->generateSecureCode($length);
|
||||||
|
expect($code)->toHaveLength($length);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
expect($e)->toBeNull();
|
||||||
|
}
|
||||||
|
})->with($length_data)->group('pure', 'utils');
|
||||||
|
|
||||||
|
test('断言可以根据参数构建 URL', function (string $url, array $params, bool $anchorQuery, string $expect) use ($utils) {
|
||||||
|
$url = $utils->buildUrl(url: $url, moreQueries: $params, anchorQuery: $anchorQuery);
|
||||||
|
expect($url)->toBe($expect);
|
||||||
|
})->with([
|
||||||
|
['baidu.com/list', ['a' => 'b'], false, 'baidu.com/list?a=b'],
|
||||||
|
['/api/v1/doc/categories/1?order=id', ['sort' => 'desc'], false, '/api/v1/doc/categories/1?order=id&sort=desc'],
|
||||||
|
['//google.com/search?c=d', ['a' => 'b'], false, '//google.com/search?c=d&a=b'],
|
||||||
|
[
|
||||||
|
'https://support.luxcreo.com/#/support?id=123',
|
||||||
|
['category' => 'abc'],
|
||||||
|
true,
|
||||||
|
'https://support.luxcreo.com/#/support?id=123&category=abc',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'https://support.luxcreo.com/#/support',
|
||||||
|
['category' => 'abc'],
|
||||||
|
true,
|
||||||
|
'https://support.luxcreo.com/#/support?category=abc',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'ssh://username:password@127.0.0.1/git/resp?id=1#/page?a=b',
|
||||||
|
['c' => 'd'],
|
||||||
|
false,
|
||||||
|
'ssh://username:password@127.0.0.1/git/resp?id=1&c=d#/page?a=b',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'http://username:password@127.0.0.1/git/resp?id=1#/page?a=b',
|
||||||
|
['c' => 'd'],
|
||||||
|
true,
|
||||||
|
'http://username:password@127.0.0.1/git/resp?id=1#/page?a=b&c=d',
|
||||||
|
]
|
||||||
|
])->group('pure', 'utils');
|
||||||
Reference in New Issue
Block a user