Check ip người dùng bằng cách dùng active record

0
483

Đây là ví dụ thực tế nhằm ứng dụng những gì đã biết về active record .Học đi đôi với hành nên hôm nay mình xin giới thiệu với các bạn 1 demo là check ip người dùng vào web .

Lý do cần check ip vào web nhiều lý do nhưng phổ biến nhất là auto chọn ngôn ngữ người dùng ,thứ 2 là check xem traffic vào web từ nước nào để phân phối thông tin đến người dùng phù hợp nhất .Kiểu web 2.5 là đây chứ đâu tích hợp deep learning vào web .Hầu như bạn vào youtube hay amazon đều có chức năng tự động hiển thị nội dung phù hợp này

Các yếu tố cần ở project này là phải có database ip của các nước  .Bạn download database này về import vào database của mình tại đây

Sau khi bạn import dữ liệu vào trong database ta sẽ tạo 1 active record liên kết với bảng đó trong mục common

<?php

namespace common\models;

use Yii;

/**
 * This is the model class for table "iplocation".
 *
 * @property string $ip_from
 * @property integer $id
 * @property string $ip_to
 * @property string $country_code
 * @property string $country_name
 */
class Iplocation extends \yii\db\ActiveRecord
{
    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return 'iplocation';
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['ip_from', 'ip_to'], 'integer'],
            [['country_code'], 'string', 'max' => 2],
            [['country_name'], 'string', 'max' => 64],
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'ip_from' => Yii::t('app', 'Ip From'),
            'id' => Yii::t('app', 'ID'),
            'ip_to' => Yii::t('app', 'Ip To'),
            'country_code' => Yii::t('app', 'Country Code'),
            'country_name' => Yii::t('app', 'Country Name'),
        ];
    }
}

Ok giờ là lúc chúng ta sử dụng chúng ở phần frontend .Tạo 1 file có tên IplocationController.php có nội dung như sau

<?php

namespace frontend\controllers;

use Yii;
use common\models\Iplocation;
use common\models\IplocationSearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use phpDocumentor\Reflection\Types\Array_;

/**
 * IplocationController implements the CRUD actions for Iplocation model.
 * @copyright Nguyễn Anh Hiến
 * @namespace frontend\controllers
 */
class IplocationController extends Controller {
	/**
	 * @inheritdoc
	 */
	public function behaviors() {
		return [ 
				'verbs' => [ 
						'class' => VerbFilter::className (),
						'actions' => [ 
								'delete' => [ 
										'POST' 
								] 
						] 
				] 
		];
	}
	
	/**
	 * Api find country when user import ip to url
	 * @param $ip
	 * @return json_array country_code,country_name
	 * @copyright nguyễn anh hiến
	 */
	public function actionCountry() {
		$ip = \Yii::$app->request->get ( 'ip', '' );
		if ($ip == '') {
			// trả về ip hiện tại của người dùng
			//$userHost = Yii::$app->request->userHost;
			$ip = Yii::$app->request->userIP;
			$array=	IplocationController::Ip($ip);
			echo $array;
		} else {
			//ip truyền lên 
			$array = IplocationController::Ip($ip);
			echo json_encode ( $array );
		}
	}
	/**
	 * Function convert ip from string to number
	 * @param unknown $ip
	 * @return number
	 */
	protected function Ipstringtoint($ip) {
		if ($ip == "") {
			return 0;
		} else {
			$ips = split ( "\.", "$ip" );
			return ($ips [3] + $ips [2] * 256 + $ips [1] * 256 * 256 + $ips [0] * 256 * 256 * 256);
		}
	}
	/**
	 * Function check ip when import ip 
	 * @return array country_name,country_code
	 */
	protected function Ip($ip)
	{
		// trả về kết quả
		$value = IplocationController::Ipstringtoint ( $ip );
		$data = Iplocation::find ()->where ( [
				'<=',
				'ip_from',
				$value
		] )->andWhere ( [
				'>=',
				'ip_to',
				$value
		] )->one ();
		$array = null;
		$array ['country_name'] = $data->attributes ['country_name'];
		$array ['country_code'] = $data->attributes ['country_code'];
		return $array;
	}
}

Tư duy thuật toán ở đây .Mình nhận ip người dùng gửi lên trong đường link có dạng như sau

http://localhost/demoyii2/frontend/web/iplocation/country.html?ip=99.187.14.159

Nếu muốn tạo url thân thiện ta có thể tùy chỉnh trong url manager  cho phần này.

Sau khi nhận dữ liệu vào controller sẽ xử lý dữ liệu check trường hợp dữ liệu nhập vào là dải ip hay nếu ko là dải ip thì chúng ta sẽ lấy trực tiếp ip gửi yêu cầu lên .

Ở đây mình dùng 2 function có 2 nhiệm vụ khác nhau là function chuyển ip từ dạng string sang dang int để so sánh .Function thứ 2 là truy ra đất nước sở hữu ip đó .Ở đây mình có 2 trường cần lấy ra là country_name và country_code

Lý do tại sao mình hay viết function bởi vì như vậy nó sẽ mạch lạc và dễ xử lý ,check bug.

Active record mình thấy so với câu lệnh sql truyền thống có những ưu điểm sau :

-Dễ hiểu ,dễ truy vấn do kiểu truy vấn hướng đối tượng và

-Theo cảm tính thì active record có vẻ truy vấn nhanh hơn