کاربران سایت را با یک کلید را ردیابی کنید

فرض کنید سایتی دارید که عضویت ندارد و میخواهید کاربران آنرا بسنجید٬ چه میکنید؟ سراغ سرویسهای آمارگیری میروید؟ اما هیچگاه دقیق نیستند و آمار بازدید با آمار استفاده تفاوت فاحشی دارد.
در این بین سایتهایی هستند که اینگونه خدمات را ارائه میدهند تا ببینید کاربران شما چه رفتاری در سایت دارند؟ نمونه این سایتها میتوان به Mouse Flow و Crazy Egg اشاره کرد. البته این سایتها تفاوت بسیاری با گوگلآنالیتیکز و باقی سرویسهای آمارگیری دارند و تفاوت اینجاس که آنها بازدید را بررسی میکنند و اینها رفتار کاربران را زیر ذره بین قرار میدهند.
این مسئله در یکی از پروژههایی که کار میکردم به دلیل اینکه داخل بستری بود که دسترسی به خارج از سرور وجود نداشت و هم اینکه چیزی که میخواستم مابین آنالیتیکز و یوزر ترکینگ بود٬ باعث شد به فکر طراحی یه سیستمی باشم تا بشود که کاربران رو با دقت نسبتاً خوبی علامت گذاری کرد و رد پاهای آنها را ذخیره کرد تا به صورت حدودی فهمید سایت چقدر یوزر دارد؟
سیستمی که پیاده میکنیم امکان توسعه بسیاری خواهد داشت و شما خواهید توانست با کمی خلاقیت و منطق کافی بیشتر از کاربران بفهمید.

سیستم خیلی ساده است! یه کلید روی سیستم کاربر ذخیره میکنیم توسط کوکی و در دفعات بعدی چک میکنیم و اطلاعاتی که نیاز داریم رو ذخیره میکنیم!
مشکلش چیه؟ مشکل اینجاست که اگر کوکی پاک باشه یا سیستم عامل عوض شه یا برازر عوض شه٬ کاربر جدید شناخته میشه که البته این مشکل برای همه آمارگیرها وجود دارد.
قبل از هرچیزی باید بدونیم این اطلاعات رو کجا ذخیره میکنیم٬ که مشخصاً توی پایگاه داده خواهد بود و پایگاه دادهای که من به ذهنم رسید تا خلاصه و راحت باشه به شکل زیر خواهد بود:

البته میتوان جدول را به گونهای دیگر تعریف کرد که در یک جدول اطلاعات کلید و در جدول دیگر اطلاعات هربازدید جداگانه با اتصال به id این کلید ذخیره گردد که البته تعداد اطلاعات ذخیره شده خیلی زیاد خواهد شد.
اول از همه نیاز به تعریف کلید داریم٬
برای همین کار بهترین چیزی که به ذهنم رسید ایجاد یک عبارت ۴۰ کاراکتری متشکل از عدد و حروف بود که تکراری نباشد.
در نتیجه چنین تابعهایی خواهیم داشت:
function randstring($length){
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
$size = strlen( $chars );
$str='';
for( $i = 0; $i < $length; $i++ ) {
$str .= $chars[ rand( 0, $size - 1 ) ];
}
return $str;
}
function key_onlinecheck($key){
$this->db->where('key',$key);
$this->db->from('keys');
return $this->db->count_all_results();
}
function key_make(){
do{
$string=$this->randstring(40);
}while($this->key_onlinecheck($string)>0);
return $string;
}
function key_insert(){
$key=$this->key_make();
if($this->db->insert('keys',
array('key'=>$key,'ip'=>$this->input->ip_address(),'time_create'=>time(),'time_visit'=>time(),'visit'=>1))
){return $key;}else{return false;}
}
که در اینجا با تابع key_insert اطلاعات کلید جدید را بر اساس تاریخ ساخت٬ آیپی٬ تاریخ بازدید وارد دیتابیس میکنیم در عین حال از این کلید ساخته شده با استفاده از کوکی روی سیستم کاربر ذخیره میکنیم.
function key_save($key,$expire=31536000){
$this->input->set_cookie(array('name'=>'key','value'=>$key,'expire'=>time()+$expire));
}
که در اینجا مقدار expire بر اساس ثانیه بدست آمده و نشان دهنده یکسال کامل میباشد (60×60×24×365).
حالا بایستی اطلاعات ذخیره شده را استفاده کنیم تا بررسی کنیم کدام کاربر تکراری و کدام جدید است.
function key_offlinecheck(){
$cookie=$this->key_get();
if($cookie!=false && $this->key_onlinecheck($cookie)==1)
return true;
}else{return false;}
}
function key_get()
return $this->input->cookie('key', TRUE)
}
function key_ip($id,$key=false){
$this->CI->db->select('ip');
$query=$this->CI->db->get_where('keys',array((!$key)?'id':'key'=>$id));
return $query->row()->ip;
}
function key_byip(){
$this->db->order_by('id','desc');
$this->CI->db->where('ip',$this->input->ip_address());
$query=$this->db->get('keys');
if($query->num_rows()==0){return false;}else{return $query->row_array();}
}
که با تابع key_get مقدار کلید کوکی برگردانده میشود و اگر موجود نباشد false برگردانده میشود٬ سپس با key_offlinecheck بعد از دریافت کلید٬ صحت کلید را بررسی میکنیم تا از ایجاد آنها توسط خودمان مطمئن شویم.
همچنین تابع key_byip به ما کلیدی را برمیگرداند که مختص به آیپی کاربر باشد و تابع key_ip آیپی کاربر را بر اساس کلید یا شناسه کلید برمیگرداند.
سپس باید توابعی ایجاد کنیم که اطلاعات بدست آمده را ذخیره کند.
function key_visit($id,$key=false){
$where='`'.(!$key)?'id':"key'.'`='".$id."'";
return $this->db->query('UPDATE `keys` SET `visit`=`visit`+1 WHERE '.$where);
}
function key_update($id,$key=false){
return $this->db->update('keys',array('ip'=>$this->input->ip_address(),'time_update'=>time()),array((!$key)?'id':'key'=>$id));
}
function key_visittime($id,$key=false){
return $this->db->update('keys',array('time_visit'=>time()),array((!$key)?'id':'key'=>$id));
}
که با تابع key_visit یک رقم به تعداد بازدیدها اضافه میشود و تابع key_update اطلاعات کلید مثل تاریخ آخرین بروزرسانی و آیپی را بروز میکند و key_visittime تاریخ آخرین بازدید را بروز میکند.
در نهایت باید با یک تابع جامع بتوانیم بررسیهای آفلاین و آنلاین در شرایط آیپی جدید٬ آیپی تکراری٬ وجود کوکی عملیات مورد نظر را انجام دهیم.
function key(){
#its not for admin's
if($this->isadmin()){return false;}
#repeatetive
if($this->key_offlinecheck()){
$key=$this->key_get();
#visit time
$this->key_visittime($key,true);
#change ip
if($this->key_ip($key,true)!==$this->input->ip_address()){
$this->key_update($key,true);
#new visit
$this->key_visit($key,true);
}
#new
}else{
$kp=$this->key_byip();
#new ip
if($kp===false){
$key=$this->key_insert();
$this->key_save($key);
#repeatetive ip
}else{
#new key
if((time()-$kp['time_visit'])>3600){
$key=$this->key_insert();
$this->key_save($key);
#save key again locally
}else{
#save cookie
$this->key_save($kp['key']);
#visit time
$this->key_visittime($kp['key'],true);
#update data
$this->key_update($key,true);
#new visit
$this->key_visit($key,true);
}
}
}
}
که در اینجا با تابع isadmin (که بسته به نوع تشخیص شما از ادمین بودن کاربر) میخواهیم جلوی لاگ کردن مدیران سایت را بگیریم.
در حالت شرطی اول با بررسی وجود کوکی کاربر چک میکنیم که قبلاً وارد سایت شده یا نه٬
در صورتی که وارد سایت شده باشد٬ اطلاعات کلید بروز و در صورتی که آیپی کاربر تغییر کرده باشد٬ اطلاعات جدید ثبت و بازدید جدیدی ثبت خواهد شد.
اگر قبلاً وارد سایت نشده باشد٬
در پایگاه داده بررسی میکنیم آیا به این آیپی کلیدی تعلق گرفته یا نه٬ که اگر نگرفته باشد کلیک جدید تعلق میگیرد و اگر گرفته باشد دو حالت پیش میاید:
در حالتی که آخرین بازدید از زمان فعلی بیش از یک ساعت گذشته باشد٬ کلید جدید تعلق میگیرد و در غیر این صورت کلید روی کوکی ذخیره شده و اطلاعات کلید بروزرسانی میگردد.
حالا همه چیز برای اجرای این سامانه آماده است٬ میتوانید از این کلید آن طور که میخواهید استفاده کنید تا اطلاعات بیشتری از کاربران خود کسب کنید.


