php获取客户端真实ip地址,

  php获取客户端真实ip地址,

  准备工作:

  建议一个本地IP地址数据库。请从http://www.cz88.net/.的这个网站下载一个纯IP数据库,安装完成后,从安装目录中取出QQWry.dat文件。这是我们要的IP数据库,放在你要的目录下。

  本前端IP地址查询处理类

  ?服务器端编程语言(Professional Hypertext Preprocessor的缩写)

  * IP地理位置查询类

  类助手_ IpLocation

  /**

  * QQWry。Dat文件指针

  * @var资源

  private $ fp

  /**

  *第一个IP记录的偏移地址

  * @var int

  private $ firstip

  /**

  *最后一个IP记录的偏移地址

  * @var int

  private $ lastip

  /**

  * IP记录总数(不包括版本信息记录)

  * @var int

  私人$ totalip

  /**

  *构造函数,打开QQWry。Dat文件并初始化类中的信息

  * @ param string文件名

  public function _ _ construct($ filename= qqwry . dat )

  $ this-FP=0;

  if (($this- fp=fopen($filename, rb ))!==假){

  $ this-first IP=$ this-getlong();

  $ this-lastip=$ this-getlong();

  $ this-totalip=($ this-lastip-$ this-first IP)/7;

  //注册析构函数,以便它可以在程序执行结束时执行。

  寄存器_关闭_功能(数组(

  $这个,

  _ _毁灭

  ));

  /**

  *析构函数,用于在页面执行后自动关闭打开的文件。

  公共函数__destruct()

  if(this-FP){

  fclose(这-

  $ this-FP=0;

  /**

  *返回读取的长整数。

  * @访问私有

  * @return int

  私有函数getlong()

  //将读取的4字节little-endian编码转换成长整数。

  $result=unpack(Vlong ,fread($this- fp,4));

  返回$ result[ long ];

  /**

  *返回读取的3字节长整数。

  * @访问私有

  * @return int

  私有函数getlong3()

  //将读取的小端编码的3个字节转换为长整数

  $result=unpack(Vlong ,fread($this- fp,3)。chr(0));

  返回$ result[ long ];

  /**

  *返回可以比较的压缩IP地址。

  * @访问私有

  * @param string $ip

  * @返回字符串

  专用功能包(ip)

  //将IP地址转换为长整数,如果PHP5中IP地址错误则返回False,

  //此时intval将Flase转换成integer -1,然后压缩成big-endian编码的字符串。

  return pack(N ,intval(IP 2 long($ IP)));

  /**

  *返回读取的字符串。

  * @访问私有

  * @param string $data

  * @返回字符串

  私有函数getstring($data= )

  $char=fread($this- fp,1);

  While (ord($char) 0) {//字符串以C格式保存到结尾

  $data。=$ char//在给定字符串后连接读取的字符

  $char=fread($this- fp,1);

  返回iconv(gbk , utf-8 ,$ data);

  /**

  *返回地区信息

  * @访问私有

  * @返回字符串

  私有函数getarea()

  $byte=fread($this- fp,1);//标志字节

  switch(order($ byte)){

  0://如果没有区域信息

  $ area=“”;

  打破;

  案例1:

  2://标志字节为1或2,表示区域信息被重定向。

  fseek($this- fp,$ this-getlong 3());

  $ area=$ this-getstring();

  打破;

  Default: //否则,表示区域信息没有被重定向。

  $ area=$ this-getstring($ byte);

  打破;

  return $ area

  /**

  *根据给定的IP地址或域名,返回该地区的信息。

  * @访问公共

  * @param string $ip

  * @返回数组

  公共函数getlocation($ip)

  如果(!$this- fp)

  返回null//如果数据文件没有正确打开,直接返回null

  $ location[ IP ]=gethostbyname($ IP);//将输入的域名转换成IP地址

  $ IP=$ this-pack IP($ location[ IP ]);//将输入的IP地址转换成可比较的IP地址

  //非法IP地址将被转换为255.255.255.255

  //分割搜索

  $ l=0;//搜索的下限

  $ u=$ this-totalip;//搜索的上限

  $ findip=$ this-lastip;//如果没有找到,返回最后一条IP记录(QQWry的版本信息。Dat)

  While ($l=$u) {//当上边界小于下边界时,查找失败。

  $i=下限(($ l $ u)/2);//计算近似的中间记录

  fseek($this- fp,$ this-first IP $ I * 7);

  $beginip=strrev(fread($this- fp,4));//获取中间记录的开始互联网协议(互联网协议)地址

  //strrev函数在这里的作用是将小端的的压缩互联网协议(互联网协议)地址转化为大端的的格式

  //以便用于比较,后面相同。

  if ($ip $beginip) { //用户的互联网协议(互联网协议)小于中间记录的开始互联网协议(互联网协议)地址时

  $ u=$ I-1;//将搜索的上边界修改为中间记录减一

  }否则{

  fseek($this- fp,$ this-getlong 3());

  $endip=strrev(fread($this- fp,4));//获取中间记录的结束互联网协议(互联网协议)地址

  if ($ip $endip) { //用户的互联网协议(互联网协议)大于中间记录的结束互联网协议(互联网协议)地址时

  $ l=$ I 1;//将搜索的下边界修改为中间记录加一

  } else { //用户的互联网协议(互联网协议)在中间记录的互联网协议(互联网协议)范围内时

  $ findip=$ this-first IP $ I * 7;

  打破;//则表示找到结果,退出循环

  //获取查找到的互联网协议(互联网协议)地理位置信息

  fseek($this- fp,$ findip);

  $ location[ begin IP ]=long 2 IP($ this-getlong());//用户互联网协议(互联网协议)所在范围的开始地址

  $ offset=$ this-get long 3();

  fseek($this- fp,$ offset);

  $ location[ endip ]=long 2 IP($ this-getlong());//用户互联网协议(互联网协议)所在范围的结束地址

  $byte=fread($this- fp,1);//标志字节

  开关(顺序(字节)){

  案例1: //标志字节为1,表示国家和区域信息都被同时重定向

  $ country offset=$ this-get long 3();//重定向地址

  fseek($this- fp,$ country offset);

  $byte=fread($this- fp,1);//标志字节

  开关(顺序(字节)){

  案例二://标志字节为2,表示国家信息又被重定向

  fseek($this- fp,$ this-getlong 3());

  $ location[ country ]=$ this-getstring();

  fseek($this- fp,$ country offset 4);

  $ location[ area ]=$ this-get area();

  打破;

  默认值://否则,表示国家信息没有被重定向

  $ location[ country ]=$ this-getstring($ byte);

  $ location[ area ]=$ this-get area();

  打破;

  打破;

  案例二://标志字节为2,表示国家信息被重定向

  fseek($this- fp,$ this-getlong 3());

  $ location[ country ]=$ this-getstring();

  fseek($this- fp,$ offset 8);

  $ location[ area ]=$ this-get area();

  打破;

  默认值://否则,表示国家信息没有被重定向

  $ location[ country ]=$ this-getstring($ byte);

  $ location[ area ]=$ this-get area();

  打破;

  if(location[ country ]== CZ88 .NET) { //CZ88 .网表示没有有效信息

  $location[country]=未知;

  if(location[ area ]= CZ88 .NET) {

  $ location[ area ]= ;

  返回$位置

  调用方式:

  ?服务器端编程语言(专业超文本预处理器的缩写)

  包含“我的位置。PHP”;

  回声前

  $ IP= 180。76 .6 .130 ;

  $ I location=new I location();

  $ location=$ I location-get location($ IP);

  print _ r($ location);

php获取客户端真实ip地址,