Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
数据应用
ThinkLibrary
提交
37ced503
T
ThinkLibrary
项目概览
数据应用
/
ThinkLibrary
通知
2
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
代码片段
项目成员
Pages
T
ThinkLibrary
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
代码片段
代码片段
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
37ced503
编写于
5月 08, 2020
作者:
李光春
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
- update ip service
上级
b986e999
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
392 addition
and
0 deletion
+392
-0
src/service/ip/IpIpDistrictInfo.php
src/service/ip/IpIpDistrictInfo.php
+42
-0
src/service/ip/IpIpReader.php
src/service/ip/IpIpReader.php
+276
-0
src/service/ip/IpIpService.php
src/service/ip/IpIpService.php
+74
-0
未找到文件。
src/service/ip/IpIpDistrictInfo.php
0 → 100644
浏览文件 @
37ced503
<?php
// +----------------------------------------------------------------------
// | ThinkLibrary 6.0 for ThinkPhP 6.0
// +----------------------------------------------------------------------
// | 版权所有 2017~2020 [ https://www.dtapp.net ]
// +----------------------------------------------------------------------
// | 官方网站: https://gitee.com/liguangchun/ThinkLibrary
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | gitee 仓库地址 :https://gitee.com/liguangchun/ThinkLibrary
// | github 仓库地址 :https://github.com/GC0202/ThinkLibrary
// | Packagist 地址 :https://packagist.org/packages/liguangchun/think-library
// +----------------------------------------------------------------------
namespace
DtApp\ThinkLibrary\service\ip
;
class
IpIpDistrictInfo
{
public
$country_name
=
''
;
public
$region_name
=
''
;
public
$city_name
=
''
;
public
$district_name
=
''
;
public
$china_admin_code
=
''
;
public
$covering_radius
=
''
;
public
$longitude
=
''
;
public
$latitude
=
''
;
public
function
__construct
(
array
$data
)
{
foreach
(
$data
AS
$field
=>
$value
)
{
$this
->
{
$field
}
=
$value
;
}
}
public
function
__get
(
$name
)
{
return
$this
->
{
$name
};
}
}
src/service/ip/IpIpReader.php
0 → 100644
浏览文件 @
37ced503
<?php
// +----------------------------------------------------------------------
// | ThinkLibrary 6.0 for ThinkPhP 6.0
// +----------------------------------------------------------------------
// | 版权所有 2017~2020 [ https://www.dtapp.net ]
// +----------------------------------------------------------------------
// | 官方网站: https://gitee.com/liguangchun/ThinkLibrary
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | gitee 仓库地址 :https://gitee.com/liguangchun/ThinkLibrary
// | github 仓库地址 :https://github.com/GC0202/ThinkLibrary
// | Packagist 地址 :https://packagist.org/packages/liguangchun/think-library
// +----------------------------------------------------------------------
namespace
DtApp\ThinkLibrary\service\ip
;
use
BadMethodCallException
;
use
Exception
;
use
InvalidArgumentException
;
class
IpIpReader
{
const
IPV4
=
1
;
const
IPV6
=
2
;
private
$file
=
NULL
;
private
$fileSize
=
0
;
private
$nodeCount
=
0
;
private
$nodeOffset
=
0
;
private
$meta
=
[];
private
$database
=
''
;
/**
* Reader constructor.
* @param $database
* @throws Exception
*/
public
function
__construct
(
$database
)
{
$this
->
database
=
$database
;
$this
->
init
();
}
private
function
init
()
{
if
(
is_readable
(
$this
->
database
)
===
FALSE
)
{
throw
new
InvalidArgumentException
(
"The IP Database file
\"
{
$this
->
database
}
\"
does not exist or is not readable."
);
}
$this
->
file
=
@
fopen
(
$this
->
database
,
'rb'
);
if
(
$this
->
file
===
FALSE
)
{
throw
new
InvalidArgumentException
(
"IP Database File opening
\"
{
$this
->
database
}
\"
."
);
}
$this
->
fileSize
=
@
filesize
(
$this
->
database
);
if
(
$this
->
fileSize
===
FALSE
)
{
throw
new
\
UnexpectedValueException
(
"Error determining the size of
\"
{
$this
->
database
}
\"
."
);
}
$metaLength
=
unpack
(
'N'
,
fread
(
$this
->
file
,
4
))[
1
];
$text
=
fread
(
$this
->
file
,
$metaLength
);
$this
->
meta
=
json_decode
(
$text
,
1
);
if
(
isset
(
$this
->
meta
[
'fields'
])
===
FALSE
||
isset
(
$this
->
meta
[
'languages'
])
===
FALSE
)
{
throw
new
Exception
(
'IP Database metadata error.'
);
}
$fileSize
=
4
+
$metaLength
+
$this
->
meta
[
'total_size'
];
if
(
$fileSize
!=
$this
->
fileSize
)
{
throw
new
Exception
(
'IP Database size error.'
);
}
$this
->
nodeCount
=
$this
->
meta
[
'node_count'
];
$this
->
nodeOffset
=
4
+
$metaLength
;
}
/**
* @param $ip
* @param string $language
* @return array|NULL
*/
public
function
find
(
$ip
,
$language
)
{
if
(
is_resource
(
$this
->
file
)
===
FALSE
)
{
throw
new
BadMethodCallException
(
'IPIP DB closed.'
);
}
if
(
isset
(
$this
->
meta
[
'languages'
][
$language
])
===
FALSE
)
{
throw
new
InvalidArgumentException
(
"language :
{
$language
}
not support."
);
}
if
(
filter_var
(
$ip
,
FILTER_VALIDATE_IP
,
FILTER_FLAG_IPV4
|
FILTER_FLAG_IPV6
)
===
FALSE
)
{
throw
new
InvalidArgumentException
(
"The value
\"
$ip
\"
is not a valid IP address."
);
}
if
(
strpos
(
$ip
,
'.'
)
!==
FALSE
&&
!
$this
->
supportV4
())
{
throw
new
InvalidArgumentException
(
"The Database not support IPv4 address."
);
}
elseif
(
strpos
(
$ip
,
':'
)
!==
FALSE
&&
!
$this
->
supportV6
())
{
throw
new
InvalidArgumentException
(
"The Database not support IPv6 address."
);
}
try
{
$node
=
$this
->
findNode
(
$ip
);
if
(
$node
>
0
)
{
$data
=
$this
->
resolve
(
$node
);
$values
=
explode
(
"
\t
"
,
$data
);
return
array_slice
(
$values
,
$this
->
meta
[
'languages'
][
$language
],
count
(
$this
->
meta
[
'fields'
]));
}
}
catch
(
Exception
$e
)
{
return
NULL
;
}
return
NULL
;
}
public
function
findMap
(
$ip
,
$language
)
{
$array
=
$this
->
find
(
$ip
,
$language
);
if
(
NULL
===
$array
)
{
return
NULL
;
}
return
array_combine
(
$this
->
meta
[
'fields'
],
$array
);
}
private
$v4offset
=
0
;
private
$v6offsetCache
=
[];
/**
* @param $ip
* @return int
* @throws Exception
*/
private
function
findNode
(
$ip
)
{
$binary
=
inet_pton
(
$ip
);
$bitCount
=
strlen
(
$binary
)
*
8
;
// 32 | 128
$key
=
substr
(
$binary
,
0
,
2
);
$node
=
0
;
$index
=
0
;
if
(
$bitCount
===
32
)
{
if
(
$this
->
v4offset
===
0
)
{
for
(
$i
=
0
;
$i
<
96
&&
$node
<
$this
->
nodeCount
;
$i
++
)
{
if
(
$i
>=
80
)
{
$idx
=
1
;
}
else
{
$idx
=
0
;
}
$node
=
$this
->
readNode
(
$node
,
$idx
);
if
(
$node
>
$this
->
nodeCount
)
{
return
0
;
}
}
$this
->
v4offset
=
$node
;
}
else
{
$node
=
$this
->
v4offset
;
}
}
else
{
if
(
isset
(
$this
->
v6offsetCache
[
$key
]))
{
$index
=
16
;
$node
=
$this
->
v6offsetCache
[
$key
];
}
}
for
(
$i
=
$index
;
$i
<
$bitCount
;
$i
++
)
{
if
(
$node
>=
$this
->
nodeCount
)
{
break
;
}
$node
=
$this
->
readNode
(
$node
,
1
&
((
0xFF
&
ord
(
$binary
[
$i
>>
3
]))
>>
7
-
(
$i
%
8
)));
if
(
$i
==
15
)
{
$this
->
v6offsetCache
[
$key
]
=
$node
;
}
}
if
(
$node
===
$this
->
nodeCount
)
{
return
0
;
}
elseif
(
$node
>
$this
->
nodeCount
)
{
return
$node
;
}
throw
new
Exception
(
"find node failed."
);
}
/**
* @param $node
* @param $index
* @return mixed
* @throws Exception
*/
private
function
readNode
(
$node
,
$index
)
{
return
unpack
(
'N'
,
$this
->
read
(
$this
->
file
,
$node
*
8
+
$index
*
4
,
4
))[
1
];
}
/**
* @param $node
* @return mixed
* @throws Exception
*/
private
function
resolve
(
$node
)
{
$resolved
=
$node
-
$this
->
nodeCount
+
$this
->
nodeCount
*
8
;
if
(
$resolved
>=
$this
->
fileSize
)
{
return
NULL
;
}
$bytes
=
$this
->
read
(
$this
->
file
,
$resolved
,
2
);
$size
=
unpack
(
'N'
,
str_pad
(
$bytes
,
4
,
"
\x00
"
,
STR_PAD_LEFT
))[
1
];
$resolved
+=
2
;
return
$this
->
read
(
$this
->
file
,
$resolved
,
$size
);
}
public
function
close
()
{
if
(
is_resource
(
$this
->
file
)
===
TRUE
)
{
fclose
(
$this
->
file
);
}
}
/**
* @param $stream
* @param $offset
* @param $length
* @return bool|string
* @throws Exception
*/
private
function
read
(
$stream
,
$offset
,
$length
)
{
if
(
$length
>
0
)
{
if
(
fseek
(
$stream
,
$offset
+
$this
->
nodeOffset
)
===
0
)
{
$value
=
fread
(
$stream
,
$length
);
if
(
strlen
(
$value
)
===
$length
)
{
return
$value
;
}
}
throw
new
Exception
(
"The Database file read bad data."
);
}
return
''
;
}
public
function
supportV6
()
{
return
(
$this
->
meta
[
'ip_version'
]
&
self
::
IPV6
)
===
self
::
IPV6
;
}
public
function
supportV4
()
{
return
(
$this
->
meta
[
'ip_version'
]
&
self
::
IPV4
)
===
self
::
IPV4
;
}
public
function
getMeta
()
{
return
$this
->
meta
;
}
/**
* @return int UTC Timestamp
*/
public
function
getBuildTime
()
{
return
$this
->
meta
[
'build'
];
}
}
src/service/ip/IpIpService.php
0 → 100644
浏览文件 @
37ced503
<?php
// +----------------------------------------------------------------------
// | ThinkLibrary 6.0 for ThinkPhP 6.0
// +----------------------------------------------------------------------
// | 版权所有 2017~2020 [ https://www.dtapp.net ]
// +----------------------------------------------------------------------
// | 官方网站: https://gitee.com/liguangchun/ThinkLibrary
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | gitee 仓库地址 :https://gitee.com/liguangchun/ThinkLibrary
// | github 仓库地址 :https://github.com/GC0202/ThinkLibrary
// | Packagist 地址 :https://packagist.org/packages/liguangchun/think-library
// +----------------------------------------------------------------------
namespace
DtApp\ThinkLibrary\service\ip
;
use
Exception
;
/**
* IP - IPIP
* Class IpIpService
* @package DtApp\ThinkLibrary\service\ip
*/
class
IpIpService
{
public
$reader
=
null
;
/**
*
* IpIpService constructor.
* @throws Exception
*/
public
function
__construct
()
{
$this
->
reader
=
new
IpIpReader
(
__DIR__
.
'/bin/ipipfree.ipdb'
);
}
/**
* @param $ip
* @param $language
* @return array|NULL
*/
public
function
getFind
(
string
$ip
=
''
,
string
$language
=
'CN'
)
{
if
(
empty
(
$ip
))
$ip
=
get_ip
();
return
$this
->
reader
->
find
(
$ip
,
$language
);
}
/**
* @param $ip
* @param $language
* @return array|false|null
*/
public
function
getFindMap
(
string
$ip
=
''
,
string
$language
=
'CN'
)
{
if
(
empty
(
$ip
))
$ip
=
get_ip
();
return
$this
->
reader
->
findMap
(
$ip
,
$language
);
}
/**
* @param $ip
* @param $language
* @return IpIpDistrictInfo|null
*/
public
function
getFindInfo
(
string
$ip
=
''
,
string
$language
=
'CN'
)
{
if
(
empty
(
$ip
))
$ip
=
get_ip
();
$map
=
$this
->
getFindMap
(
$ip
,
$language
);
if
(
NULL
===
$map
)
return
NUll
;
return
new
IpIpDistrictInfo
(
$map
);
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录