PHP to convert IP address to the real address of the method _php tips

Source: Internet
Author: User
Tags chr explode fread get ip pow strlen unpack
Want to convert IPV4 address to real address, must refer to IP database, commercial IP database stored in relational database, query and use is very convenient, but the cost is not individual and small companies willing to bear, So the idea of simple application is to use some free IP database or some large web site to provide the query API, their data is enough for us to use.
1. Using the Pure IP database
The advantage of using a local QQWry.Dat file is that the query is fast, with the disadvantage that the database file should be placed in its own space and that the database be updated occasionally. Time relationship nonsense is not much said, the following is the use of this file function, if it is in WordPress Use this function, the following code to write the subject of the functions.php inside, and then in the comments-list output <?php Echo Convertip (Get_comment_author_ip ());?>; if other program references, enter a valid IPV4 address to get a real address.
Copy Code code as follows:

function Convertip ($IP) {
IP Data File path
$dat _path = ' QQWry.Dat ';
Check IP Address
if (!preg_match ("/^d{1,3}.d{1,3}.d{1,3}.d{1,3}$/", $ip)) {
Return "IP address Error";
//}
Open IP Data file
if (! $fd = @fopen ($dat _path, ' RB ')) {
Return ' IP date file not exists or access denied ';
}
Decomposition of IP to calculate the number of plastic
$ip = Explode ('. ', $IP);
$ipNum = $ip [0] * 16777216 + $ip [1] * 65536 + $ip [2] * 256 + $IP [3];
Get IP Data index start and end locations
$DataBegin = Fread ($FD, 4);
$DataEnd = Fread ($FD, 4);
$ipbegin = Implode (', Unpack (' L ', $DataBegin));
if ($ipbegin < 0) $ipbegin + = POW (2, 32);
$ipend = Implode (', Unpack (' L ', $DataEnd));
if ($ipend < 0) $ipend + = POW (2, 32);
$ipAllNum = ($ipend-$ipbegin)/7 + 1;
$BeginNum = 0;
$EndNum = $ipAllNum;
Search for matching IP records from index records using the binary lookup method
while ($ip 1num> $ipNum | | $ip 2num< $ipNum) {
$Middle = Intval (($EndNum + $BeginNum)/2);
Offset pointer reads 4 bytes to index position
Fseek ($FD, $ipbegin + 7 * $Middle);
$ipData 1 = fread ($FD, 4);
if (strlen ($ipData 1) < 4) {
Fclose ($FD);
Return ' System Error ';
}
The extracted data is transformed and shaped, if the data is negative, plus 2 of the 32 power
$ip 1num = Implode (', Unpack (' L ', $ipData 1));
if ($ip 1num < 0) $ip 1num + + POW (2, 32);
The number of long integers fetched is greater than our IP address to modify the end position for the next loop
if ($ip 1num > $ipNum) {
$EndNum = $Middle;
Continue
}
Remove an index after fetching the previous index
$DataSeek = Fread ($FD, 3);
if (strlen ($DataSeek) < 3) {
Fclose ($FD);
Return ' System Error ';
}
$DataSeek = Implode (', Unpack (' L ', $DataSeek. chr (0)));
Fseek ($FD, $DataSeek);
$ipData 2 = fread ($FD, 4);
if (strlen ($ipData 2) < 4) {
Fclose ($FD);
Return ' System Error ';
}
$ip 2num = Implode (', Unpack (' L ', $ipData 2));
if ($ip 2num < 0) $ip 2num + + POW (2, 32);
I can't find the hint unknown.
if ($ip 2num < $ipNum) {
if ($Middle = = $BeginNum) {
Fclose ($FD);
Return ' Unknown ';
}
$BeginNum = $Middle;
}
}
$ipFlag = Fread ($FD, 1);
if ($ipFlag = = Chr (1)) {
$ipSeek = Fread ($FD, 3);
if (strlen ($ipSeek) < 3) {
Fclose ($FD);
Return ' System Error ';
}
$ipSeek = Implode (', Unpack (' L ', $ipSeek. chr (0)));
Fseek ($FD, $ipSeek);
$ipFlag = Fread ($FD, 1);
}
if ($ipFlag = = Chr (2)) {
$AddrSeek = Fread ($FD, 3);
if (strlen ($AddrSeek) < 3) {
Fclose ($FD);
Return ' System Error ';
}
$ipFlag = Fread ($FD, 1);
if ($ipFlag = = Chr (2)) {
$AddrSeek 2 = fread ($FD, 3);
if (strlen ($AddrSeek 2) < 3) {
Fclose ($FD);
Return ' System Error ';
}
$AddrSeek 2 = implode (', Unpack (' L ', $AddrSeek 2.chr (0)));
Fseek ($FD, $AddrSeek 2);
} else {
Fseek ($FD,-1, seek_cur);
}
while (($char = Fread ($FD, 1))!= chr (0))
$ipAddr 2. = $char;
$AddrSeek = Implode (', Unpack (' L ', $AddrSeek. chr (0)));
Fseek ($FD, $AddrSeek);
while (($char = Fread ($FD, 1))!= chr (0))
$ipAddr 1. = $char;
} else {
Fseek ($FD,-1, seek_cur);
while (($char = Fread ($FD, 1))!= chr (0))
$ipAddr 1. = $char;
$ipFlag = Fread ($FD, 1);
if ($ipFlag = = Chr (2)) {
$AddrSeek 2 = fread ($FD, 3);
if (strlen ($AddrSeek 2) < 3) {
Fclose ($FD);
Return ' System Error ';
}
$AddrSeek 2 = implode (', Unpack (' L ', $AddrSeek 2.chr (0)));
Fseek ($FD, $AddrSeek 2);
} else {
Fseek ($FD,-1, seek_cur);
}
while (($char = Fread ($FD, 1))!= chr (0)) {
$ipAddr 2. = $char;
}
}
Fclose ($FD);
Finally, the result is returned after the corresponding substitution operation
if (Preg_match ('/http/i ', $ipAddr 2)) {
$ipAddr 2 = ';
}
$IPADDR = "$ipAddr 1 $ipAddr 2";
$IPADDR = preg_replace ('/cz88.net/is ', ', ', $ipaddr);
$IPADDR = preg_replace ('/^s*/is ', ', ', $ipaddr);
$IPADDR = preg_replace ('/s*$/is ', ', ', $ipaddr);
if (Preg_match ('/http/i ', $ipaddr) | | $ipaddr = = ') {
$ipaddr = ' Unknown ';
}
$IPADDR = Iconv (' GBK ', ' Utf-8//ignore ', $ipaddr); Convert the encoding if the GBK of the page can delete this row
return $ipaddr;
}

2. Using the interface of the portal site
Currently known Tencent, Sina, NetEase, Sohu and Google to provide IP address query API, but find only Tencent, Sina and NetEase, Google's seemingly to use Google Maps so no research. Looked at the domestic several Tencent provided is JavaScript, NetEase provides is XML, and Sina has a variety of formats can be used, note that non-XML data sources are GBK format, whether it is JavaScript calls or PHP calls to convert the code, or get garbled. And more attention is that, if a one-time query multiple IP, using the Portal API to query will be very slow, I probably wrote a For loop to try, whether it is in the PHP parsing xml or file_get_contents () function to get content, query more than 10 times will become very slow, may even timeout.

Tencent IP Address API interface address: Http://fw.qq.com/ipaddress, returned the data format is: var ipdata = new Array ("123.124.2.85", "", "Beijing", "");, A JavaScript object that does not yet know how to enter an IP query.
Sina's IP address query interface: HTTP://INT.DPOOL.SINA.COM.CN/IPLOOKUP/IPLOOKUP.PHP?FORMAT=JS
Sina Multi-Region test method: http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=js&ip=123.124.2.85
NetEase Youdao IP Address query interface: http://www.youdao.com/smartresult-xml/search.s?type=ip&q=123.124.2.85
//Tencent API's PHP calling method
Copy Code code as follows:

function Getipplace () {
$ip =file_get_contents ("http://fw.qq.com/ipaddress");
$ip =str_replace (' ",", $IP);
$ip 2=explode ("(", $IP);
$a =substr ($ip 2[1],0,-2);
$b =explode (",", $a);
return $b;
}
$ip =getipplace ();
Print_r ($IP);

//Youdao API's PHP calling method
Copy Code code as follows:

$url = "http:www.youdao.com/smartresult-xml/search.s?type=ip&q=". $ip;
$doc = new DOMDocument ();
$doc->load ($url);
$smartresult = $doc->getelementsbytagname ("Product");
foreach ($smartresult as $product)
{
$locations = $product->getelementsbytagname ("location");
$location = $locations->item (0)->nodevalue;
}
if ($location!= "")
{
echo $i. "." $ip;
echo "from". $location. " of netizens ";
}
Else
{
echo $i. "." $ip;
echo "A netizen from Mars";
}
Public Function Sinaipapi ($IP) {
$str = file_get_contents ("http://int.dpool.sina.com.cn/iplookup/iplookup.php?ip=". $ip);
$str = Iconv ("GBK", "Utf-8//ignore", $str);
Preg_match_all ("/[/x{4e00}-/x{9fa5}]+/u", $str, $get);
$add = Implode (', $get [0]);
return $add;
}
//$get is a very good two-dimensional array

One of the Youdao and Sina is my own writing, Sina API can also be like Tencent API with the file_get_contents () function to obtain the address after the use of a series of string function processing, I wrote the function using regular expressions from Sina's return results to provide a string containing Chinese, and to deposit a two-dimensional array, this may only be useful for the Sina API and there are bugs. For example, after the IP address assigned to me by the school var_dump () the $get variable in the function gets the following result: Array (1) {[0]=> Array (6) {[0]=> string (6) "China" [1]=> string ( 6 "Beijing" [2]=> string (6) "Beijing" [3]=> string (9) "Education Network" [4]=> string (6) "School" [5]=> string (18) "Geosciences"}}, and the result of the function output Is "China Beijing Beijing Education Network School Geosciences", I hope that my ideas and methods can be useful to others.

Finally again, if it is WordPress please use the first method, otherwise use the API at the same time to query all the real address of the message will allow PHP timeout, I hope that all the way Daniel has a better way, as to limit the display and display methods such as God Horse is a wordpress application problem, At the same time for Java and C #, the idea is the same, these follow-up questions and so I finished the test and then elaborate.
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.