php简单的网站流量统计程序(来源,搜索引擎,ip,关键词)

 更新时间:2016年11月25日 17:25  点击:2241
这是一个基于php 与mysql的网站流量统计实例,可以统计出来过来访问网站人员的来源,搜索引擎,ip,关键词,希望此实例对各位同学会有所帮助。

流量统计工具,诸如cnzz,百度统计,51啦,都是非常不错的,功能也很强大。闲来没事,自己写了一个简单的流量统计工具,不过只能统计访问时间,访问者ip,访问来路,受访页面,来自seo/seo.html" target="_blank">搜索引擎和搜索关键词。对比专业的流量统计工作来说肯定是微不足道的,但是说名了一点,其实大多数统计到的数据都没有我们想象那么难,有时候只需一个系统变量或者提取url中的一些信息就可以得出相应的统计信息。

 

(数据表结构和统计到的部分数据信息)

程序部分:

 代码如下 复制代码


visited();    //调用统计函数(最好放在公共页面)

//访问量
function visited(){
    $now_time = time();
    $referer_url = $_SERVER['HTTP_REFERER'];    //来自的页面地址
    $from_spider = $keywords = '';
    if(!empty($referer_url)){
        if(strstr($referer_url,'www.baidu.com')){
            $referer_url = explode("&",$referer_url);
            foreach($referer_url as $val){
                if(strstr($val,'wd=')){
                    $keywords = explode("wd=",$val);
                    $keywords = $keywords[1];
                }
            }
            $from_spider = '百度';
            $keywords = urldecode($keywords);
        }elseif(strstr($referer_url,'www.google')){
            $referer_url = explode("&",$referer_url);
            foreach($referer_url as $val){
                if(strstr($val,'q=')){
                    $keywords = explode("q=",$val);
                    $keywords = $keywords[1];
                }
            }
            $from_spider = '谷歌';
            $keywords = urldecode($keywords);
        }   
    }
    //只判断了百度和谷歌的,其他的原理一样
    $theData = array(
        'access_time'    => $now_time,
        'access_date'    => date("Y-m-d",$now_time),
        'access_url'    => $_SERVER['REQUEST_URI'],
        'referer_url'    => $_SERVER['HTTP_REFERER'],
        'keywords'        => $keywords,
        'ip_address'    => $_SERVER['REMOTE_ADDR'],
        'from_spider'    => $from_spider,
    );
    $sql = "insert into stats (access_time,access_date,access_url,referer_url,keywords,ip_address,from_spider) values ('".$theData['access_time']."','".$theData['access_date']."','".$theData['access_url']."','".$theData['referer_url']."','".$theData['keywords']."','".$theData['ip_address']."','".$theData['from_spider']."')";
    echo $sql; exit;mysql_query($sql);
}

本例以统计某产品在各省份的活跃用户数为背景,数据来源于mysql数据库,根据各省份的活跃用户数,分成不同等级,并以不同的背景色显示各省份的活跃程度,符合实际应用需求。

效果如下图

HTML

和本站上篇文章使用raphael.js绘制中国地图一样,首先在head部分载入raphael.js库文件和chinamapPath.js路径信息文件。

 代码如下 复制代码

<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="raphael.js"></script>
<script type="text/javascript" src="chinamapPath.js"></script>

然后在body中需要放置地图的位置放置div#map。

<div id="map"></div>

PHP

我们准备一张mysql表名为mapdata,这张表存储的是产品在各个省份的活跃用户数据。我们使用PHP读取mysql表中的数据,并将读取的数据以json格式输出,并将PHP文件命名为json.php。

 代码如下 复制代码

$host="localhost";//主机
$db_user="root";//数据库用户名
$db_pass="";//密码
$db_name="demo";//数据库名称
 
$link=mysql_connect($host,$db_user,$db_pass);//连接数据库
mysql_select_db($db_name,$link);
mysql_query("SET names UTF8");
 
$sql = "select active from mapdata order by id asc";//查询
$query = mysql_query($sql);
 
while($row=mysql_fetch_array($query)){
    $arr[] = $row['active'];
}
echo json_encode($arr);//JSON格式
mysql_close($link);//关闭连接

值得注意的是,我们要把mapdata表中各省份的排序与chinamapPath.js文件中的各省份顺序一致,这样才能保证读取的数据能和地图中的省份对应上。
jQuery

首先我们使用jquery的get()方法获取json数据。

 代码如下 复制代码

$(function(){
    $.get("json.php",function(json){
        ...
    });
});

获取到json数据后,我们先要将json数据转换为数组,然后我们遍历整个数组,根据json数据中各省份活跃用户数的多少,我们作一个等级区分,这里我将等级分为0-5六个等级,活跃用户数越大背景颜色越深,这样在地图上显示就会一目了然的看出不同省份的数据等级程度。绘制地图的时候和本站上篇文章使用raphael.js绘制中国地图介绍的基本一样,不同之处在于给每个不同省份填充对应的颜色,请看整理好的代码:

 代码如下 复制代码
$(function(){
    $.get("json.php",function(json){//获取数据
    var data = string2Array(json);//转换数组
    
    var flag;
    var arr = new Array();//定义新数组,对应等级
    for(var i=0;i<data.length;i++){
        var d = data[i];
        if(d<100){
            flag = 0;
        }else if(d>=100 && d<500){
            flag = 1;
        }else if(d>=500 && d<2000){
            flag = 2;
        }else if(d>=2000 && d<5000){
            flag = 3;
        }else if(d>=5000 && d<10000){
            flag = 4;
        }else{
            flag = 5;
        }
        arr.push(flag);
    }
    //定义颜色
    var colors = ["#d7eef8","#97d6f5","#3fbeef","#00a2e9","#0084be","#005c86"];
    
    //调用绘制地图方法
    var R = Raphael("map", 600, 500);
    paintMap(R);
    
    var textAttr = {
        "fill": "#000",
        "font-size": "12px",
        "cursor": "pointer"
    };
            
    var i=0;
    for (var state in china) {
        china[state]['path'].color = Raphael.getColor(0.9);
        (function (st, state) {
            
            //获取当前图形的中心坐标
            var xx = st.getBBox().x + (st.getBBox().width / 2);
            var yy = st.getBBox().y + (st.getBBox().height / 2);
            
            //修改部分地图文字偏移坐标
            switch (china[state]['name']) {
                case "江苏":
                    xx += 5;
                    yy -= 10;
                    break;
                case "河北":
                    xx -= 10;
                    yy += 20;
                    break;
                case "天津":
                    xx += 10;
                    yy += 10;
                    break;
                case "上海":
                    xx += 10;
                    break;
                case "广东":
                    yy -= 10;
                    break;
                case "澳门":
                    yy += 10;
                    break;
                case "香港":
                    xx += 20;
                    yy += 5;
                    break;
                case "甘肃":
                    xx -= 40;
                    yy -= 30;
                    break;
                case "陕西":
                    xx += 5;
                    yy += 10;
                    break;
                case "内蒙古":
                    xx -= 15;
                    yy += 65;
                    break;
                default:
            }
            //写入文字
            china[state]['text'] = R.text(xx, yy, china[state]['name']).attr(textAttr);
            
            var fillcolor = colors[arr[i]];//获取对应的颜色
            
            st.attr({fill:fillcolor});//填充背景色
            
            st[0].onmouseover = function () {
                st.animate({fill: "#fdd", stroke: "#eee"}, 500);
                china[state]['text'].toFront();
                R.safari();
            };
            st[0].onmouseout = function () {
                st.animate({fill: fillcolor, stroke: "#eee"}, 500);
                china[state]['text'].toFront();
                R.safari();
            };
                    
         })(china[state]['path'], state);
         i++;
    }
    });
});

上述代码中,使用var fillcolor = colors[arr[i]];获取对应等级的颜色值,然后通过st.attr({fill:fillcolor});将颜色填充到对应的省份区块中。此外string2Array()函数是将字符串转换为数组。

 代码如下 复制代码

function string2Array(string) { 
    eval("var result = " + decodeURI(string)); 
    return result; 
}

这样,我们可以看到一个不同省份不同背景色的中国地图,根据不同颜色可以区分省份之间的活跃用户数差异程度,达到预期目标。


 实例下载地址:http://file.111cn.net/upload/2013/12/chinamap-data.zip

文章给大家提供一个php字符串与byte字节数组转化类示例,希望文章对各位同学会有所帮助。
 代码如下 复制代码
<?php
 
/**
 
* byte数组与字符串转化类
 
*/
 
class Bytes {
 
   
/**
    
* 转换一个String字符串为byte数组
    
* @param $str 需要转换的字符串
    
* @param $bytes 目标byte数组
    
* @author Zikie
    
*/
    public static function getBytes($string) {
        $bytes = array();
        for($i = 0; $i < strlen($string); $i++){
             $bytes[] = ord($string[$i]);
        }
        return $bytes;
    }
 
   
/**
    
* 将字节数组转化为String类型的数据
    
* @param $bytes 字节数组
    
* @param $str 目标字符串
    
* @return 一个String类型的数据
    
*/
 
    public static function toStr($bytes) {
        $str = '';
        foreach($bytes as $ch) {
            $str .= chr($ch);
        }
 
           return $str;
    }
 
   
/**
    
* 转换一个int为byte数组
    
* @param $byt 目标byte数组
    
* @param $val 需要转换的字符串
    
*
    
*/
 
    public static function integerToBytes($val) {
        $byt = array();
        $byt[0] = ($val & 0xff);
        $byt[1] = ($val >> 8 & 0xff);
        $byt[2] = ($val >> 16 & 0xff);
        $byt[3] = ($val >> 24 & 0xff);
        return $byt;
    }
 
   
/**
    
* 从字节数组中指定的位置读取一个Integer类型的数据
    
* @param $bytes 字节数组
    
* @param $position 指定的开始位置
    
* @return 一个Integer类型的数据
    
*/
 
    public static function bytesToInteger($bytes, $position) {
        $val = 0;
        $val = $bytes[$position + 3] & 0xff;
        $val <<= 8;
        $val |= $bytes[$position + 2] & 0xff;
        $val <<= 8;
        $val |= $bytes[$position + 1] & 0xff;
        $val <<= 8;
        $val |= $bytes[$position] & 0xff;
        return $val;
    }
 
   
/**
    
* 转换一个shor字符串为byte数组
    
* @param $byt 目标byte数组
    
* @param $val 需要转换的字符串
    
*
    
*/
 
    public static function shortToBytes($val) {
        $byt = array();
        $byt[0] = ($val & 0xff);
        $byt[1] = ($val >> 8 & 0xff);
        return $byt;
    }
 
   
/**
    
* 从字节数组中指定的位置读取一个Short类型的数据。
    
* @param $bytes 字节数组
    
* @param $position 指定的开始位置
    
* @return 一个Short类型的数据
    
*/
 
    public static function bytesToShort($bytes, $position) {
        $val = 0;
        $val = $bytes[$position + 1] & 0xFF;
        $val = $val << 8;
        $val |= $bytes[$position] & 0xFF;
        return $val;
    }
 
}
?>
下面这个函数是一个php 打印出字符串的16进制实例,这里面的核心函数就是 chr获取二进制然后再进行转成16进制数。
 代码如下 复制代码

<?php
/*
php 打印出字符串的16进制数据
*/
function hex_dump($data, $newline="n")
{
  static $from = '';
  static $to = '';
 
  static $width = 16; # number of bytes per line
 
  static $pad = '.'; # padding for non-visible characters
 
  if ($from==='')
  {
    for ($i=0; $i<=0xFF; $i++)
    {
      $from .= chr($i);
      $to .= ($i >= 0x20 && $i <= 0x7E) ? chr($i) : $pad;
    }
  }
 
  $hex = str_split(bin2hex($data), $width*2);
  $chars = str_split(strtr($data, $from, $to), $width);
 
  $offset = 0;
  foreach ($hex as $i => $line)
  {
    echo sprintf('%6X',$offset).' : '.implode(' ', str_split($line,2)) . ' [' . $chars[$i] . ']' . $newline;
    $offset += $width;
  }
}
 
$info="this is a testx00x99hex_dump";
print_r(hex_dump($info));
/*
输出结果:
 
0 : 74 68 69 73 20 69 73 20 61 20 74 65 73 74 00 99 [this is a test..]
 
10 : 68 65 78 5f 64 75 6d 70 [hex_dump]
*/
?>


 

现在我们智能手机用户很多了,访问网站也有很多朋友使用手机直接访问,这样存在问题了如果是pc版本手机访问肯定不好看还费人家流量了,所以很多公司做了wap站了,但是要如何判断用户是手机还是pc访问网站呢,下面我整理了一些方法。

最近做一个手机查询系统,自然就牵扯到了此问题,那我就根据对wap的认识浅谈下通过php判断用户访问方式是通过wap访问还是电脑直接访问。
首先说最根本的解决方法:
手机访问时,会附带发送user-agent信息,这个信息里面会有手机号码信息,那么如果能取得手机号码,则可以肯定是通过手机wap访问的。但是目前中国移动已经屏蔽了user-agent信息,所以获取不到手机号码。有关系的朋友可以联系移动公司,把wap网站服务器的ip提交给中国移动,加入白名单后即可取得ua信息。目前中国联通可以直接取到手机号,对联通用户此方案可完美实施。
接下来说我的解决方案:
手机访问,原理是手机通过移动公司的代理服务器进行的访问。那么我们就可以理解是一台普通电脑使用了代理服务器。当手机通过代理服务器访问的时候,http头信息会毫无疑问的包含一个信息:via。这个信息提供了有价值的判断信息。
例如河南移动取得的via信息是:
http/1.1 hazz-b-gw001-wap(infox-wisg, huawei technologies)
河南联通的via信息是:
zxwap gateway,zte technologies
其他各省的http头信息和这个大同小异,判断是否手机访问的方案就出来了:获取http的via信息字符串看是否包含wap字符,如果有则是通过手机访问。这样做的结果是没有人能伪造手机访问,判断绝对准确。自然,这样对于网上流行的手机wap模拟器也做了屏蔽----从根本上屏蔽。
操作代码也很简单:

 代码如下 复制代码
// check if wap by xhat
function check_wap() {
return stristr($_SERVER['HTTP_VIA'],"wap") ? true : false;
}
// check over

从我查阅的资料来看,目前此方法应该是迄今互联网上准确率最高、最简单的判断手机访问方法。

iphone智能手机

为discuz做的iphone版本基本完工,为了方便访问,直接在首页对iphone的访问进行了判断,然后直接跳转

使用以上代码判断,经测试效果很好。

自己用的一个判断类,比较全面了

 代码如下 复制代码

/*
 判断访问用户是否为手机111cn.net
 //判断是否属手机
 */
 function is_mobile() {
  $user_agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  //echo $user_agent;
  $mobile_agents = Array("ipad","wap","android","iphone","sec","sam","ericsson","240x320","acer","acoon","acs-","abacho","ahong","airness","alcatel","amoi","anywhereyougo.com","applewebkit/525","applewebkit/532","asus","audio","au-mic","avantogo","becker","benq","bilbo","bird","blackberry","blazer","bleu","cdm-","compal","coolpad","danger","dbtel","dopod","elaine","eric","etouch","fly ","fly_","fly-","go.web","goodaccess","gradiente","grundig","haier","hedy","hitachi","htc","huawei","hutchison","inno","ipaq","ipod","jbrowser","kddi","kgt","kwc","lenovo","lg","lg2","lg3","lg4","lg5","lg7","lg8","lg9","lg-","lge-","lge9","longcos","maemo","mercator","meridian","micromax","midp","mini","mitsu","mmm","mmp","mobi","mot-","moto","nec-","netfront","newgen","nexian","nf-browser","nintendo","nitro","nokia","nook","novarra","obigo","palm","panasonic","pantech","philips","phone","pg-","playstation","pocket","pt-","qc-","qtek","rover","sagem","sama","samu","sanyo","samsung","sch-","scooter","sec-","sendo","sgh-","sharp","siemens","sie-","softbank","sony","spice","sprint","spv","symbian","tcl-","teleca","telit","tianyu","tim-","toshiba","tsm","up.browser","utec","utstar","verykool","virgin","vk-","voda","voxtel","vx","wellco","wig browser","wii","windows ce","wireless","xda","xde","zte","ben","hai","phili");
  $is_mobile = false;
  foreach ($mobile_agents as $device) {
   if (stristr($user_agent, $device)) {
    if( 'ipad' == $device )
    {
     return $is_mobile;
    }
    $is_mobile = true;
    break;
   }
  }
  return $is_mobile;
 }

 

[!--infotagslink--]

相关文章

  • C#开发Windows窗体应用程序的简单操作步骤

    这篇文章主要介绍了C#开发Windows窗体应用程序的简单操作步骤,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-04-12
  • C++调用C#的DLL程序实现方法

    本文通过例子,讲述了C++调用C#的DLL程序的方法,作出了以下总结,下面就让我们一起来学习吧。...2020-06-25
  • 微信小程序 页面传值详解

    这篇文章主要介绍了微信小程序 页面传值详解的相关资料,需要的朋友可以参考下...2017-03-13
  • C#使用Process类调用外部exe程序

    本文通过两个示例讲解了一下Process类调用外部应用程序的基本用法,并简单讲解了StartInfo属性,有需要的朋友可以参考一下。...2020-06-25
  • 使用GruntJS构建Web程序之构建篇

    大概有如下步骤 新建项目Bejs 新建文件package.json 新建文件Gruntfile.js 命令行执行grunt任务 一、新建项目Bejs源码放在src下,该目录有两个js文件,selector.js和ajax.js。编译后代码放在dest,这个grunt会...2014-06-07
  • uniapp微信小程序:key失效的解决方法

    这篇文章主要介绍了uniapp微信小程序:key失效的解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-01-20
  • 将c#编写的程序打包成应用程序的实现步骤分享(安装,卸载) 图文

    时常会写用c#一些程序,但如何将他们和photoshop一样的大型软件打成一个压缩包,以便于发布....2020-06-25
  • PHP常用的小程序代码段

    本文实例讲述了PHP常用的小程序代码段。分享给大家供大家参考,具体如下:1.计算两个时间的相差几天$startdate=strtotime("2009-12-09");$enddate=strtotime("2009-12-05");上面的php时间日期函数strtotime已经把字符串...2015-11-24
  • 微信小程序自定义tabbar组件

    这篇文章主要为大家详细介绍了微信小程序自定义tabbar组件,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-03-14
  • 微信小程序二维码生成工具 weapp-qrcode详解

    这篇文章主要介绍了微信小程序 二维码生成工具 weapp-qrcode详解,教大家如何在项目中引入weapp-qrcode.js文件,通过实例代码给大家介绍的非常详细,需要的朋友可以参考下...2021-10-23
  • 微信小程序 网络请求(GET请求)详解

    这篇文章主要介绍了微信小程序 网络请求(GET请求)详解的相关资料,需要的朋友可以参考下...2016-11-22
  • 微信小程序如何获取图片宽度与高度

    这篇文章主要给大家介绍了关于微信小程序如何获取图片宽度与高度的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-10
  • Python爬取微信小程序通用方法代码实例详解

    这篇文章主要介绍了Python爬取微信小程序通用方法代码实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-09-29
  • 微信小程序(应用号)开发新闻客户端实例

    这篇文章主要介绍了微信小程序(应用号)开发新闻客户端实例的相关资料,需要的朋友可以参考下...2016-10-25
  • 微信小程序手势操作之单触摸点与多触摸点

    这篇文章主要介绍了微信小程序手势操作之单触摸点与多触摸点的相关资料,需要的朋友可以参考下...2017-03-13
  • 微信小程序实现canvas分享朋友圈海报

    这篇文章主要为大家详细介绍了微信小程序实现canvas分享朋友圈海报,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-21
  • 手把手教你uniapp和小程序分包(图文)

    本文主要介绍了手把手教你uniapp和小程序分包,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-02
  • 微信小程序 页面跳转传递值几种方法详解

    这篇文章主要介绍了微信小程序 页面跳转传递值几种方法详解的相关资料,需要的朋友可以参考下...2017-01-16
  • 微信小程序实现点击导航条切换页面

    这篇文章主要为大家详细介绍了微信小程序实现点击导航条切换页面,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-11-19
  • 微信小程序实现登录页云层漂浮的动画效果

    微信小程序目前的火热程度相信不用多言,最近利用空余时间用小程序实现了个动态的登录页效果,所以下面这篇文章主要给大家介绍了利用微信小程序实现登录页云层漂浮动画效果的相关资料,需要的朋友可以参考借鉴,下面来一起看看吧。...2017-05-09