<?php
if
( !function_exists(
'ftok'
) )
{
function
ftok
(
$filename
=
""
,
$proj
=
""
)
{
if
(
empty
(
$filename
) ││ !
file_exists
(
$filename
) )
{
return
-1;
}
else
{
$filename
=
$filename
. (string)
$proj
;
for
(
$key
=
array
(); sizeof(
$key
) <
strlen
(
$filename
);
$key
[] = ord(
substr
(
$filename
, sizeof(
$key
), 1)));
return
array_sum
(
$key
);
}
}
}
class
IpLocation {
var
$shm_id
;
var
$firstip
;
var
$lastip
;
var
$totalip
;
var
$pos
;
function
getlong() {
$result
= unpack(
'Vlong'
, shmop_read(
$this
->shm_id,
$this
->pos, 4));
$this
->pos += 4;
return
$result
[
'long'
];
}
function
getlong3() {
$result
= unpack(
'Vlong'
, shmop_read(
$this
->shm_id,
$this
->pos, 3).
chr
(0));
$this
->pos += 3;
return
$result
[
'long'
];
}
function
packip(
$ip
) {
return
pack(
'N'
,
intval
(
ip2long
(
$ip
)));
}
function
getstring(
$data
=
""
) {
$char
= shmop_read(
$this
->shm_id,
$this
->pos++, 1);
while
(ord(
$char
) > 0) {
$data
.=
$char
;
$char
= shmop_read(
$this
->shm_id,
$this
->pos++, 1);
}
return
$data
;
}
function
getarea() {
$byte
= shmop_read(
$this
->shm_id,
$this
->pos++, 1);
switch
(ord(
$byte
)) {
case
0:
$area
=
""
;
break
;
case
1:
case
2:
$this
->pos =
$this
->getlong3(
$this
->pos);
$area
=
$this
->getstring();
break
;
default
:
$area
=
$this
->getstring(
$byte
);
break
;
}
return
$area
;
}
function
getlocation(
$ip
) {
if
(!
$this
->shm_id)
return
null;
$location
[
'ip'
] =
gethostbyname
(
$ip
);
$ip
=
$this
->packip(
$location
[
'ip'
]);
$l
= 0;
$u
=
$this
->totalip;
$findip
=
$this
->lastip;
while
(
$l
<=
$u
) {
$i
=
floor
((
$l
+
$u
) / 2);
$this
->pos =
$this
->firstip +
$i
* 7;
$beginip
=
strrev
(shmop_read(
$this
->shm_id,
$this
->pos, 4));
if
(
$ip
<
$beginip
) {
$u
=
$i
- 1;
}
else
{
$this
->pos += 4;
$this
->pos =
$this
->getlong3();
$endip
=
strrev
(shmop_read(
$this
->shm_id,
$this
->pos, 4));
if
(
$ip
>
$endip
) {
$l
=
$i
+ 1;
}
else
{
$findip
=
$this
->firstip +
$i
* 7;
break
;
}
}
}
$this
->pos =
$findip
;
$location
[
'beginip'
] = long2ip(
$this
->getlong());
$this
->pos =
$offset
=
$this
->getlong3();
$location
[
'endip'
] = long2ip(
$this
->getlong());
$byte
= shmop_read(
$this
->shm_id,
$this
->pos++, 1);
switch
(ord(
$byte
)) {
case
1:
$this
->pos =
$countryOffset
=
$this
->getlong3();
$byte
= shmop_read(
$this
->shm_id,
$this
->pos++, 1);
switch
(ord(
$byte
)) {
case
2:
$this
->pos =
$this
->getlong3();
$location
[
'country'
] =
$this
->getstring();
$this
->pos =
$countryOffset
+ 4;
$location
[
'area'
] =
$this
->getarea();
break
;
default
:
$location
[
'country'
] =
$this
->getstring(
$byte
);
$location
[
'area'
] =
$this
->getarea();
break
;
}
break
;
case
2:
$this
->pos =
$this
->getlong3();
$location
[
'country'
] =
$this
->getstring();
$this
->pos =
$offset
+ 8;
$location
[
'area'
] =
$this
->getarea();
break
;
default
:
$location
[
'country'
] =
$this
->getstring(
$byte
);
$location
[
'area'
] =
$this
->getarea();
break
;
}
if
(
$location
[
'country'
] ==
" CZ88.NET"
) {
$location
[
'country'
] =
"未知"
;
}
if
(
$location
[
'area'
] ==
" CZ88.NET"
) {
$location
[
'area'
] =
""
;
}
return
$location
;
}
function
IpLocation(
$filename
) {
$shm_key
=
ftok
(
$filename
,
'R'
);
if
(!(
$this
->shm_id = @shmop_open(
$shm_key
,
"a"
, 0, 0))) {
$content
=
file_get_contents
(
$filename
);
$this
->shm_id = shmop_open(
$shm_key
,
"c"
, 0644,
strlen
(
$content
));
shmop_write(
$this
->shm_id,
$content
, 0);
}
$this
->pos = 0;
$this
->firstip =
$this
->getlong();
$this
->lastip =
$this
->getlong();
$this
->totalip = (
$this
->lastip -
$this
->firstip) / 7;
register_shutdown_function(
array
(&
$this
,
'_IpLocation'
));
}
function
_IpLocation() {
shmop_close(
$this
->shm_id);
}
function
&getInstance(
$filename
=
"QQWry.Dat"
) {
static
$instance
= null;
if
(
is_null
(
$instance
)) {
$instance
=
new
IpLocation(
$filename
);
}
return
$instance
;
}
}
?>