Fp, 4); return $ result ['long'];} /*** return the number of long integers of the three bytes read ** @ access private * @ return int */function getlong3 () {// convert the three bytes of the read little-endian encoding into the number of long integers $ result = unpack ('vlong', fread ($ this-> fp, 3 ). chr (0); return $ result ['long'];} /*** return the compressed ip address ** @ access private * @ param string $ ip * @ return string */function packip ($ ip) {// Convert the IP address to a long integer. If an IP address error occurs in PHP5, False is returned. // intval converts Flase to an integer-1, and then compress it into a big-endian encoded string r. Eturn pack ('N', intval (ip2long ($ ip )));} /*** return the read string ** @ access private * @ param string $ data * @ return string */function getstring ($ data = "") {$ char = fread ($ this-> fp, 1); while (ord ($ char)> 0) {// The string is saved in C format, end $ data with \ 0. = $ char; // connect the read characters to the given string $ char = fread ($ this-> fp, 1);} return $ data ;} /*** return region information ** @ access private * @ return string */function getarea () {$ byte = fread ($ this-> fp, 1 ); // Mark byte switch (Ord ($ byte) {case 0: // no region information $ area = ""; break; case 1: case 2: // indicates that the byte is 1 or 2, fseek ($ this-> fp, $ this-> getlong3 (); $ area = $ this-> getstring (); break; default: // otherwise, the region information is not redirected $ area = $ this-> getstring ($ byte); break;} return $ area ;} /*** return region information based on the given IP address or domain name ** @ access public * @ param string $ ip * @ return array */function getlocation ($ ip) {if (! $ This-> fp) return null; // if the data file is not properly opened, a blank $ location ['IP'] = gethostbyname ($ ip) is returned ); // Convert the entered domain name to an ip address $ ip = $ this-> packip ($ location ['IP']); // Convert the entered IP address to a comparable IP address // an invalid IP address is converted to 255.255.255.255.255 // You can search for $ l = 0; // search for the bottom boundary $ u = $ this-> totalip; // search for the top boundary $ findip = $ this-> lastip; // if not found, return the last IP record (QQWry. dat version information) while ($ l <= $ u) {// when the boundary is smaller than the bottom boundary, the query fails $ I = floor ($ l $ u) /2); // calculate the approximate intermediate record fseek ($ this-> fp, $ thi S-> firstip $ I * 7); $ beginip = strrev (fread ($ this-> fp, 4 )); // Obtain the starting IP address of the intermediate record. // The strrev function is used to convert the compressed IP address of little-endian to the format of big-endian. // This function is used for comparison. If ($ ip <$ beginip) {// when the user's IP address is smaller than the starting ip address of the intermediate record, $ u = $ I-1; // change the upper boundary of the search to an intermediate record minus one} else {fseek ($ this-> fp, $ this-> getlong3 ()); $ endip = strrev (fread ($ this-> fp, 4); // Obtain the end ip address of the intermediate record if ($ ip> $ endip) {// when the user's IP address is greater than the end IP address of the intermediate record $ l = $ I 1; // change the bottom boundary of the search to an intermediate record plus} else {// when the user's IP address is within the IP range of the intermediate record $ findip = $ this-> firstip $ I * 7; break; // indicates finding the result and exiting the loop }}// obtain the IP location information fseek ($ this-> fp, $ findip ); $ location ['beginip'] = long2i P ($ this-> getlong (); // start address of the user's IP address range $ offset = $ this-> getlong3 (); fseek ($ this-> fp, $ offset); $ location ['enabled'] = long2ip ($ this-> getlong ()); // end address of the user's IP address range $ byte = fread ($ this-> fp, 1); // Mark byte switch (ord ($ byte) {case 1: // The flag byte is 1, indicating that the country and region information is redirected at the same time $ countryOffset = $ this-> getlong3 (); // redirect address fseek ($ this-> fp, $ countryOffset); $ byte = fread ($ this-> fp, 1); // Mark byte switch (ord ($ byte) {case 2: // The flag byte is 2, indicating Country Information is redirected to fseek ($ this-> fp, $ this-> getlong3 (); $ location ['country'] = $ this-> getstring (); fseek ($ this-> fp, $ countryOffset 4); $ location ['region'] = $ this-> getarea (); break; default: // otherwise, the country information is not Redirected. $ location ['country'] = $ this-> getstring ($ byte); $ location ['region'] = $ this-> getarea (); break;} break; case 2: // The flag byte is 2, indicating that the country information is redirected to fseek ($ this-> fp, $ this-> getlong3 ()); $ location ['country'] = $ this-> getstring (); fseek ($ This-> fp, $ offset 8); $ location ['region'] = $ this-> getarea (); break; default: // otherwise, the country information is not Redirected. $ location ['country'] = $ this-> getstring ($ byte); $ location ['region'] = $ this-> getarea (); break;} if ($ location ['country'] = "CZ88.NET") {// CZ88.NET indicates no valid information. $ location ['country'] = "unknown ";} if ($ location ['region'] = "CZ88.NET") {$ location ['region'] = "" ;}return $ location ;}/ *** constructor, open QQWry. dat file and initialize information in the class ** @ param String $ filename * @ return IpLocation */function IpLocation ($ filename = "QQWry. dat ") {if ($ this-> fp = @ fopen ($ filename, 'RB '))! = False) {$ this-> firstip = $ this-> getlong (); $ this-> lastip = $ this-> getlong (); $ this-> totalip = ($ this-> lastip-$ this-> firstip)/7; // register the destructor, execute register_shutdown_function (array (& $ this, '_ iplocation') ;}/ *** destructor at the end of program execution, used to automatically close opened files after Page execution ends. **/Function _ IpLocation () {fclose ($ this-> fp) ;}}?>
|