【概論】
(1)簡述
在所有網站里,特別是用戶管理系統,都喜歡記錄用戶訪問的IP地址。對后期的業務開展有很大的意義,可以通過IP地址的記錄訪問出國內或全球范圍內,哪一塊用戶比較多。
在后期做產品時,可以針對這塊來重點推銷。所以不要只將IP看為地址信息,認為沒有什么用。
(2)獲取IP方法
①原生PHP里通過超全局變量:$_SERVER保存關於報頭、路徑、腳本位置等信息。例如
注意:$_SERVER方法缺點---->有時獲取不太准確
| $_SERVER['SERVER_ADDR'] | 返回當前運行腳本所在的服務器的 IP 地址。 |
| $_SERVER['SERVER_NAME'] | 返回當前運行腳本所在的服務器的主機名(比如 www.w3school.com.cn)。 |
其他具體的我在文章最后列出
②ThinkPHP封裝了get_slient_ip(獲取客戶IP)方法來獲取IP,准確來說,因為$_SERVER方法獲取不太准確,所以該方法是對原生$_SERVER的補充完善
位置:系統函數庫文件里function.php,接下來看下源碼
/** * 獲取客戶端IP地址 * @param integer $type 返回類型 0 返回IP地址 1 返回IPV4地址數字 * @param boolean $adv 是否進行高級模式獲取(有可能被偽裝) * @return mixed */ function get_client_ip($type = 0,$adv=false) { $type = $type ? 1 : 0; static $ip = NULL; if ($ip !== NULL) return $ip[$type]; if($adv){ if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); $pos = array_search('unknown',$arr); if(false !== $pos) unset($arr[$pos]); $ip = trim($arr[0]); }elseif (isset($_SERVER['HTTP_CLIENT_IP'])) { $ip = $_SERVER['HTTP_CLIENT_IP']; }elseif (isset($_SERVER['REMOTE_ADDR'])) { $ip = $_SERVER['REMOTE_ADDR']; } }elseif (isset($_SERVER['REMOTE_ADDR'])) { $ip = $_SERVER['REMOTE_ADDR']; } // IP地址合法驗證 $long = sprintf("%u",ip2long($ip)); $ip = $long ? array($ip, $long) : array('0.0.0.0', 0); return $ip[$type]; }
輸出查看下
echo get_client_ip();
瀏覽器輸出結果:

若檢驗方法里傳入數字1,則會輸出IP對應的數字地址,這里驗證下----->echo get_client_ip(1);
瀏覽器輸出結果:
什么是數字地址呢?其實簡單理解就是IP地址的數字格式,等價於IP地址。這里在瀏覽器輸入數字地址2130706433驗證下,會發現會顯示出localhost界面。具體后面有解釋
總結:對於方法get_client_id(可選參數數字)總結
1. 如果參數是0或者空,則表示返回正常的ipv4(127.0.0.1)地址,常見的正常的4段地址;
2. 如果參數為1,則會返回數字地址
【三】重點:TP中的使用--------------在ThinkPHP里將ip地址轉換為物理地址
(1)什么是物理地址?
物理地址就是可以一眼看出IP所屬地域,如下格式:

(2)重點:如何將IP地址轉化為物理地址?
1. 轉換原因:原因不多講,說下應用吧---例如網絡犯罪后快速定位
對於上面快速定位,這里補充下為什么黑客攻擊后可以全身而退?因為黑客攻擊服務器后,將歷史記錄刪除了,直接刪除了日志。
在ThinkPHP里系統提供了一個工具類來實現轉換,但系統不提供所使用的數據。所以相關的數據庫還需要開發人員去尋找對應數據庫,數據庫可以從純真官網(www.cz88.net)去尋找。現在國內所有IP數據庫基本都下載自純真網,因為更新十分頻繁,基本5天更新一次
2. 下載安裝IP數據庫
3. 測試:輸入上面百度查詢的IP

4. 因為PHP無法直接調取純真的接口,所以需要另想辦法~~~
5. 右擊打開文件位置,找到qqwry.dat便是我們所需數據庫

6. ThinkPHP里提供的類ThinkPHP\Library\Org\Net\locatiom.class.php,接下來看下源碼
①構造方法
/** * 構造函數,打開 QQWry.Dat 文件並初始化類中的信息 * * @param string $filename * @return IpLocation */ public function __construct($filename = "UTFWry.dat") { $this->fp = 0; if (($this->fp = fopen(dirname(__FILE__).'/'.$filename, 'rb')) !== false) { $this->firstip = $this->getlong(); $this->lastip = $this->getlong(); $this->totalip = ($this->lastip - $this->firstip) / 7; } }
由源碼即可分析出,IP文件位置應該和類文件同級。實例化時可以傳遞一個文件名,文件名所在位置和當前類屬於同級目錄
②getlocation方法:根據ip地址或域名返回所在地區信息
public function getlocation($ip='') {...}
分析后即可得知,該方法可以傳入一個參數即ip地址,如果為空則表示查詢當前用戶的ip地址
③析構函數:用於頁面執行結束后自動關閉打開的文件,所以不需要調用
public function __destruct() { if ($this->fp) { fclose($this->fp); } $this->fp = 0; }
分析代碼總結:需要調用的方法有兩個,①實例化時調用構造函數;②getlocation返回地區信息
(3)開始編寫方法
1. 先將qqwry.dat復制到IpLocation.class同級目錄下

2. 輸出ip驗證
$ip = new \Org\Net\IpLocation('qqwry.dat');//PS:這里我改用UTFWry.dat $location = $ip->getlocation('218.79.93.194'); dump($location);die;
輸出結果:
array(5) {
["ip"] => string(13) "218.79.93.194"
["beginip"] => string(11) "218.79.93.0"
["endip"] => string(13) "218.79.94.255"
["country"] => string(18) "上海市普陀區"
["area"] => string(20) "/靜安區電信ADSL"
}
這里我調整了一下,因為qqwry.dat無法獲取,所以查閱了一下,我改用UTFWry地址進行IP定位,具體我在文章thinkphp獲取ip地址及位置信息里做了總結
UTFWry是默認的,不過也需要下載。這里我試過自定義的無效。。。。。。以后有時間再研究研究,備注下
拓展:
后期會結合接口編程,去開發,這里先了解下。將上述代碼做下修改
// 實例化類 參數表示IP地址庫文件 $ip = new \Org\Net\IpLocation('UTFWry.dat');
//通過I方法接收ip,然后傳遞ip $ipInfo = I('get.ip'); // 獲取某個IP地址所在的位置 $location = $ip->getlocation($ipInfo); dump($location);die;
改寫完成后將之前的訪問連接http://www.1336.com/index.php/Admin/Doc/showList.html后面加上get傳參,例如?ip=6.6.6.6,便可以訪問對應IP(一般好的IP地址都被大佬級別的公司和集團占了,,,)。IP為6.6.6.6的輸出結果:美國國防部IP
array(5) {
["ip"] => string(7) "6.6.6.6"
["beginip"] => string(7) "6.1.0.0"
["endip"] => string(13) "6.255.255.255"
["country"] => string(6) "美國"
["area"] => string(57) "亞利桑那州華楚卡堡市美國國防部網絡中心"
}
【拓展】
(1) 數字地址


| 元素/代碼 | 描述 |
|---|---|
| $_SERVER['PHP_SELF'] | 返回當前執行腳本的文件名。 |
| $_SERVER['GATEWAY_INTERFACE'] | 返回服務器使用的 CGI 規范的版本。 |
| $_SERVER['SERVER_ADDR'] | 返回當前運行腳本所在的服務器的 IP 地址。 |
| $_SERVER['SERVER_NAME'] | 返回當前運行腳本所在的服務器的主機名(比如 www.w3school.com.cn)。 |
| $_SERVER['SERVER_SOFTWARE'] | 返回服務器標識字符串(比如 Apache/2.2.24)。 |
| $_SERVER['SERVER_PROTOCOL'] | 返回請求頁面時通信協議的名稱和版本(例如,“HTTP/1.0”)。 |
| $_SERVER['REQUEST_METHOD'] | 返回訪問頁面使用的請求方法(例如 POST)。 |
| $_SERVER['REQUEST_TIME'] | 返回請求開始時的時間戳(例如 1577687494)。 |
| $_SERVER['QUERY_STRING'] | 返回查詢字符串,如果是通過查詢字符串訪問此頁面。 |
| $_SERVER['HTTP_ACCEPT'] | 返回來自當前請求的請求頭。 |
| $_SERVER['HTTP_ACCEPT_CHARSET'] | 返回來自當前請求的 Accept_Charset 頭( 例如 utf-8,ISO-8859-1) |
| $_SERVER['HTTP_HOST'] | 返回來自當前請求的 Host 頭。 |
| $_SERVER['HTTP_REFERER'] | 返回當前頁面的完整 URL(不可靠,因為不是所有用戶代理都支持)。 |
| $_SERVER['HTTPS'] | 是否通過安全 HTTP 協議查詢腳本。 |
| $_SERVER['REMOTE_ADDR'] | 返回瀏覽當前頁面的用戶的 IP 地址。 |
| $_SERVER['REMOTE_HOST'] | 返回瀏覽當前頁面的用戶的主機名。 |
| $_SERVER['REMOTE_PORT'] | 返回用戶機器上連接到 Web 服務器所使用的端口號。 |
| $_SERVER['SCRIPT_FILENAME'] | 返回當前執行腳本的絕對路徑。 |
| $_SERVER['SERVER_ADMIN'] | 該值指明了 Apache 服務器配置文件中的 SERVER_ADMIN 參數。 |
| $_SERVER['SERVER_PORT'] | Web 服務器使用的端口。默認值為 “80”。 |
| $_SERVER['SERVER_SIGNATURE'] | 返回服務器版本和虛擬主機名。 |
| $_SERVER['PATH_TRANSLATED'] | 當前腳本所在文件系統(非文檔根目錄)的基本路徑。 |
| $_SERVER['SCRIPT_NAME'] | 返回當前腳本的路徑。 |
| $_SERVER['SCRIPT_URI'] | 返回當前頁面的 URI。 |
