ThinkPHP---TP拓展之獲取IP信息


【概論】

(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。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM