随着滚动条滚动的Tab切换 – js例子

在电商网站,我们有一些tab 想要他,随着下拉,tab自动切换的方式,

这样无论对seo还是客户体验都很不错,下面是实现的一个例子,代码如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
<html xmlns="http://www.w3.org/1999/xhtml">  
<head>  
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  
<title>随着滚动条滚动的Tab切换</title>  
<style>  
*{  
    list-style:none;  
    margin:0;  
    padding:0;  
    text-decoration:none;  
    font-family:'Microsoft YaHei';  
  
}  
li{  
    width:100px;  
    height:50px;  
    line-height:50px;  
    float:left;  
    border-right:2px solid #eee;  
    text-align:center;  
    cursor:pointer;  
}  
ul{  
    width:1200px;     
    margin:0 auto;  
}  
.nav{  
    height:52px;  
    width:100%;  
    background:#f5f5f5;  
}  
.nav .cur{  
    background:#fff;  
    border-top:2px solid #1a92cf;  
    color:#1a92cf;  
}  
.fixed{  
    position:fixed;  
    top:0;  
    left:0;  
}  
a{  
    color:#505050;  
}  
</style>  
</head>  
<body>  
<br/><br/><br/><br/><br/><br/><br/>  
<div class="nav" id="nav-container">  
    <ul id="nav-box">
        <li class="cur">text1-nav</li>  
        <li>text2-nav</li>  
        <li>text3-nav</li>  
    </ul>  
</div>  
<div id="text">  
    <div style="width:100%;height:500px;background:green;text-align:center;">text1</div>  
    <div style="width:100%;height:500px;background:yellow;text-align:center;">text2</div>  
    <div style="width:100%;height:500px;background:blue;text-align:center;">text3</div>   
</div>  
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>  
  
<script>  
var navContainer = document.getElementById("nav-container");  
var navBox = document.getElementById("nav-box");  
var text = document.getElementById("text");  
var navBoxChild = navBox.children;  
var textChild = text.children;  
var num = navContainer.offsetTop;  
var a = navContainer.offsetHeight;  
window.onscroll = function(){  
    var scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;  
    if(scrollTop >= num){  
        navContainer.className = "nav fixed";  
        text.style.paddingTop = a +"px";  
    }else{  
        navContainer.className = "nav";  
        text.style.paddingTop = "";  
    }  
    //当导航与相应文档接触的时候自动切换  
    //method1  
    for(var i=0;i<navBoxChild.length;i++){  
        if( scrollTop + a >= textChild[i].offsetTop){  
            for(var j=0;j<navBoxChild.length;j++){  
                navBoxChild[j].className = "";  
            }  
            navBoxChild[i].className = "cur";  
       }  
    }  
};  
for(var i=0;i<navBoxChild.length;i++){  
    var interval;  
    navBoxChild[i].index = i;  
    navBoxChild[i].onclick = function(){  
        var self = this;  
        clearInterval(interval);  
    if(document.body.scrollTop){
      scroll = document.body;
    }else if(document.documentElement.scrollTop){
      scroll = document.documentElement;
    }
        interval = setInterval(function(){  
      if(scroll.scrollTop + a<=textChild[self.index].offsetTop){  
        scroll.scrollTop += 40;  
        if(scroll.scrollTop + a>=textChild[self.index].offsetTop){  
          scroll.scrollTop = textChild[self.index].offsetTop-a;  
          clearInterval(interval);  
        }  
      }else{  
        scroll.scrollTop /= 1.1;  
        if(scroll.scrollTop + a<=textChild[self.index].offsetTop){  
          scroll.scrollTop = textChild[self.index].offsetTop-a;  
          clearInterval(interval);  
        }  
      }  
    },40); 
    };  
}  
</script>    
</body>  
</html>

 

Geoip geoip-api-php 库包使用 – 通过ip 找到国家

通过js 接收了用户的ip,我们需要通过ip得到用户的国家,可以通过一个库包来实现,下面是详细:
1.下载geoip的数据库:

cd geoip/  
wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz  
gzip -d GeoIP.dat.gz  
ls  
GeoLiteCity.dat

 

其他库: 查看

GeoLite免费数据库

 

2. 下载php库包:

wget http://www.maxmind.com/download/geoip/api/php/php-latest.tar.gz  
unzip php-latest.tar.gz

3.使用:

include("/www/web/develop/marketsystem/common/lib/geoip-api-php-1.14/src/geoip.inc");  
  
//得到国家。通过ip  
function getCountryByIp($ip){  
    $gi = geoip_open("/www/web/develop/marketsystem/common/lib/geoip/GeoIP.dat", GEOIP_STANDARD);  
    if(strstr($ip,":")){  
        $country_code = geoip_country_code_by_addr_v6($gi,$ip);  
        $country_name = geoip_country_name_by_addr_v6($gi,$ip);  
    }else{  
        $country_code = geoip_country_code_by_addr($gi,$ip);  
        $country_name = geoip_country_name_by_addr($gi,$ip);  
    }  
    geoip_close($gi);  
    return [  
        "country_code" => $country_code,  
        "country_name" => $country_name,  
    ];  
}

 

类似谷歌,在网站里面嵌入js,接收各种浏览器信息以及网站信息

需要3个步骤:js 收集,调动接口, php接收,通过ip找到国家,然后存储

1.

需要在网页里面嵌入js代码:

<script type="text/javascript">
  var _maq = _maq || [];
  _maq.push(['website_id', '3']);
  (function() {
    var ma = document.createElement('script'); ma.type = 'text/javascript'; ma.async = true;
    ma.src = ('https:' == document.location.protocol ? 'https://' : 'http://') + 'static.tomtop-cdn.com/tomtop/js/trace.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ma, s);
  })();
</script>

上下面的代码,是在每一个页面都需要加入,您可以加入到页面的底部

如果您想收集某些页面的单独的数据,譬如:产品页面的sku,你可以加入下面的代码,这个代码必须在上面的代码的前面:

<script type="text/javascript">
  var _maq = _maq || [];
  _maq.push(['sku', '$sku']);
</script>

一定要注意,这个代码一定要在上面

如果传递购物车信息,可以用json个数传递

2. 全局加入的js代码可以看到有个trace.js    这个js文件就是下面的内容

(function () {
  
  var nVer = navigator.appVersion;
  var nAgt = navigator.userAgent;
  var browserName  = navigator.appName;
  var fullVersion  = ''+parseFloat(navigator.appVersion); 
  var majorVersion = parseInt(navigator.appVersion,10);
  var nameOffset,verOffset,ix;

  // In Opera, the true version is after "Opera" or after "Version"
  if ((verOffset=nAgt.indexOf("Opera"))!=-1) {
   browserName = "Opera";
   fullVersion = nAgt.substring(verOffset+6);
   if ((verOffset=nAgt.indexOf("Version"))!=-1) 
     fullVersion = nAgt.substring(verOffset+8);
  }
  // In MSIE, the true version is after "MSIE" in userAgent
  else if ((verOffset=nAgt.indexOf("MSIE"))!=-1) {
   browserName = "Microsoft Internet Explorer";
   fullVersion = nAgt.substring(verOffset+5);
  }
  // In Chrome, the true version is after "Chrome" 
  else if ((verOffset=nAgt.indexOf("Chrome"))!=-1) {
   browserName = "Chrome";
   fullVersion = nAgt.substring(verOffset+7);
  }
  // In Safari, the true version is after "Safari" or after "Version" 
  else if ((verOffset=nAgt.indexOf("Safari"))!=-1) {
   browserName = "Safari";
   fullVersion = nAgt.substring(verOffset+7);
   if ((verOffset=nAgt.indexOf("Version"))!=-1) 
     fullVersion = nAgt.substring(verOffset+8);
  }
  // In Firefox, the true version is after "Firefox" 
  else if ((verOffset=nAgt.indexOf("Firefox"))!=-1) {
   browserName = "Firefox";
   fullVersion = nAgt.substring(verOffset+8);
  }
  // In most other browsers, "name/version" is at the end of userAgent 
  else if ( (nameOffset=nAgt.lastIndexOf(' ')+1) < 
        (verOffset=nAgt.lastIndexOf('/')) ) 
  {
   browserName = nAgt.substring(nameOffset,verOffset);
   fullVersion = nAgt.substring(verOffset+1);
   if (browserName.toLowerCase()==browserName.toUpperCase()) {
    browserName = navigator.appName;
   }
  }
  // trim the fullVersion string at semicolon/space if present
  if ((ix=fullVersion.indexOf(";"))!=-1)
     fullVersion=fullVersion.substring(0,ix);
  if ((ix=fullVersion.indexOf(" "))!=-1)
     fullVersion=fullVersion.substring(0,ix);

  majorVersion = parseInt(''+fullVersion,10);
  if (isNaN(majorVersion)) {
   fullVersion  = ''+parseFloat(navigator.appVersion); 
   majorVersion = parseInt(navigator.appVersion,10);
  }

//////////////////////得到手机的设备名称
  operate_relase = "";
  var OS_Name = navigator.appVersion;
          if (OS_Name.indexOf("Win") != -1) {	 
        operate = "Windows";
        
        if ((OS_Name.indexOf("Windows 95") != -1)||
        (OS_Name.indexOf("Win95") != -1) ||
        (OS_Name.indexOf("Windows_95") != -1)
        ) {	 
          operate_relase = "Windows 95";
        }else if ((OS_Name.indexOf("Windows 98") != -1)||
        (OS_Name.indexOf("Win98") != -1)) {	
          operate_relase = "Win98";
          
        }else if ((OS_Name.indexOf("Windows NT 5.0") != -1)||
        (OS_Name.indexOf("Windows 2000") != -1)) {	
          operate_relase = "Windows 2000";
          
        }else if ((OS_Name.indexOf("Windows NT 5.1") != -1)||
        (OS_Name.indexOf("Windows XP") != -1)) {	
          operate_relase = "Windows XP";
          
        }else if (OS_Name.indexOf("Win16") != -1) {	
          operate_relase = "Windows 3.11";
          
        }else if (OS_Name.indexOf("Windows NT 5.2") != -1) {	
          operate_relase = "Windows Server 2003";
          
        }else if (OS_Name.indexOf("Windows NT 6.0") != -1) {	
          operate_relase = "Windows Vista";
          
        }else if (OS_Name.indexOf("Windows NT 6.1") != -1) {	
          operate_relase = "Windows 7";
          
        }else if ((OS_Name.indexOf("Windows NT 4.0") != -1)||
        (OS_Name.indexOf("WinNT4.0") != -1) ||
        (OS_Name.indexOf("WinNT") != -1)||
        (OS_Name.indexOf("Windows NT") != -1)) {	
          operate_relase = "Windows NT 4.0";
        }else if (OS_Name.indexOf("Windows ME") != -1) {	
          operate_relase = "Windows ME";
        }

        
          } else if (OS_Name.indexOf("Mac") != -1) {
        operate = "Mac OS";	
          } else if (OS_Name.indexOf("X11") != -1) {
        operate = "Unix";	
          } else if (OS_Name.indexOf("Linux") != -1) {
        operate = "Linux";
          } else if (OS_Name.indexOf("SunOS") != -1) {
        operate = "Sun OS";
          } else if (OS_Name.indexOf("OpenBSD") != -1) {
        operate = "Open BSD";
        
      } else if (OS_Name.indexOf("QNX") != -1) {
        operate = "QNX";
      } else if (OS_Name.indexOf("BeOS") != -1) {
        operate = "BeOS";
      } else if (OS_Name.indexOf("OS/2") != -1) {
        operate = "OS/2";
      } else if ((OS_Name.indexOf("nuhk") != -1) 
      || (OS_Name.indexOf("Googlebot") != -1)
      || (OS_Name.indexOf("Yammybot") != -1)
      || (OS_Name.indexOf("Openbot") != -1)
      || (OS_Name.indexOf("Slurp") != -1)
      || (OS_Name.indexOf("MSNBot") != -1)
      || (OS_Name.indexOf("Ask Jeeves/Teoma") != -1)
      || (OS_Name.indexOf("ia_archiver") != -1)
      ) {
        operate = "Search Bot";
      }else{
        operate = "unknow";
      }
  /////////////////////

  //通过参数,得到url中参数的值
  function getParameterByName(name) {
    name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
    var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
      results = regex.exec(location.search);
    return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
  }
  //得到当前的时间
  function getDate(){
    var currentdate = new Date(); 
    
    month = currentdate.getMonth();if(month<10){month = "0"+month;}
    day = currentdate.getDate();if(day<10){day = "0"+day;}
    hours = currentdate.getHours();if(hours<10){hours = "0"+hours;}
    minutes = currentdate.getMinutes();if(minutes<10){minutes = "0"+minutes;}
    second = currentdate.getSeconds();if(second<10){second = "0"+second;}
    var datetime =  currentdate.getFullYear() + "-"  
        + month  + "-" 
        + day + " "
                + hours + ":"  
                + minutes + ":" 
                + second;
    return datetime ;
  }
  
  
  
  //得到设备名称
  function getDevice(){
    var isMobile = {
      Android: function() {
      return navigator.userAgent.match(/Android/i);
      },
      webOS:function() {
      return navigator.userAgent.match(/webOS/i);
      },
      BlackBerry: function() {
      return navigator.userAgent.match(/BlackBerry/i);
      },
      iPhone: function() {
      return navigator.userAgent.match(/iPhone/i);
      },
      iPad: function() {
      return navigator.userAgent.match(/iPad/i);
      },
      iPod: function() {
      return navigator.userAgent.match(/iPod/i);
      },
      Opera: function() {
      return navigator.userAgent.match(/Opera Mini/i);
      },
      Windows: function() {
      return navigator.userAgent.match(/IEMobile/i);
      },
      any: function() {
      return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iPad() ||isMobile.iPod() || isMobile.iPhone() || isMobile.Opera() || isMobile.Windows());
      }
    };
    var str = "";
    if( isMobile.Android() ) { str = "Android";  }
    if( isMobile.webOS() ) { str = "webOS";  }
    if( isMobile.BlackBerry() ) { str = "BlackBerry";  }
    if( isMobile.iPhone() ) { str =  "iPhone";  }
    if( isMobile.iPad() ) { str =  "iPad";  }
    if( isMobile.iPod() ) { str =  "iPod";  }
    if( isMobile.Opera() ) { str =  "Opera";  }
    if( isMobile.Windows() ) { str =  "Windows";  }
    if(str){
      return "Mobile:"+str;
    }else{
      return "PC";
    }
    
  }
  
  //////////////
  function s4() {
    return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
  };
   
  function guid() {
    return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
  }
  ////得到唯一标示码uuid 
  var uuid = guid();
  ////设置cookie,默认是设置天  expires代表的是天数。
  function Set_Cookie( name, value, expires, path, domain, secure )
  {
    // set time, it's in milliseconds
    
    domain = document.domain;
    
    domain = domain.replace("www.","");
    
    var today = new Date();
    today.setTime( today.getTime() );

    /*
    if the expires variable is set, make the correct
    expires time, the current script below will set
    it for x number of days, to make it for hours,
    delete * 24, for minutes, delete * 60 * 24
    */
    if ( expires )
    {
      expires = expires * 1000 * 60 * 60 * 24;
    }else{
      expires = expires * 20 * 365 * 1000 * 60 * 60 * 24;
    }
    var expires_date = new Date( today.getTime() + (expires) );
    
    this_expires = expires/1000;
    //document.write("thisdomain:"+domain+"<br/>");
    document.cookie = name + "=" +escape( value ) +
    ( ( expires ) ? ";expires=" + expires_date.toGMTString() : "" ) +
    ( ( path ) ? ";path=" + path : "" ) +
    ( ( domain ) ? ";domain=" + domain : "" ) +
    ( ( secure ) ? ";secure" : "" );
    
    
  }
  //得到cookie
  function Get_Cookie( check_name ) {
    // first we'll split this cookie up into name/value pairs
    // note: document.cookie only returns name=value, not the other components
    var a_all_cookies = document.cookie.split( ';' );
    var a_temp_cookie = '';
    var cookie_name = '';
    var cookie_value = '';
    var b_cookie_found = false; // set boolean t/f default f

    for ( i = 0; i < a_all_cookies.length; i++ )
    {
      // now we'll split apart each name=value pair
      a_temp_cookie = a_all_cookies[i].split( '=' );


      // and trim left/right whitespace while we're at it
      cookie_name = a_temp_cookie[0].replace(/^\s+|\s+$/g, '');

      // if the extracted name matches passed check_name
      if ( cookie_name == check_name )
      {
        b_cookie_found = true;
        // we need to handle case where cookie has no value but exists (no = sign, that is):
        if ( a_temp_cookie.length > 1 )
        {
          cookie_value = unescape( a_temp_cookie[1].replace(/^\s+|\s+$/g, '') );
        }
        // note that in cases where cookie is initialized but no value, null is returned
        return cookie_value;
        break;
      }
      a_temp_cookie = null;
      cookie_name = '';
    }
    if ( !b_cookie_found )
    {
      return null;
    }
  }
  //删除cookie
  function Delete_Cookie( name, path, domain ) {
    if ( Get_Cookie( name ) ) document.cookie = name + "=" +
    ( ( path ) ? ";path=" + path : "") +
    ( ( domain ) ? ";domain=" + domain : "" ) +
    ";expires=Thu, 01-Jan-1970 00:00:01 GMT";
  }
  
  
    var params = {};
  
  // 设置  cid   如果新的cid访问,那么cid将会被覆盖。 
  cid = getParameterByName("cid");
  var cookie_cid = Get_Cookie("cid");
  
  if(cid){
    //set cid cookie.
    params.cid = cid;
    Set_Cookie( "cid", cid, 7, "/", '', '' );
  }else if(cookie_cid){
    params.cid = cookie_cid;
  }
  
  //设备
  params.devide = getDevice();
  params.user_agent = navigator.userAgent;
  var userLang = navigator.language || navigator.userLanguage; 
  params.browser_name 	= browserName;  //浏览器名称
  params.browser_version 	= majorVersion;  //浏览器版本
  params.browser_date 	= getDate();  //浏览器时间
  params.browser_lang 	= userLang;   //浏览器语言
  params.operate 			= operate;     //操作系统
  params.operate_relase 	= operate_relase;  //操作系统详细
  
  
  
    //Document对象数据
  //通过加入下面的代码,来辨别是否是老客户
  //标准为:refer domain为空,或者不包含  && _fta 这个cookie存在
  //在数据分析中,客户中间客户点击刷新页面,也会被标示成return:1,因此,在分析的时候,需要找UID
  //最小的那个,查看refer。
    if(document) {
    params.domain = document.domain || '';   //域名
    params.url = document.URL || '';    //当前url
    params.title = document.title || '';   //当前title
    params.refer_url = document.referrer || '';  //来源referrer
    
    
    //thisrefer =  document.referrer || '';
    //refer_fta_cookie = Get_Cookie( '_fta' );
    
    //此cookie用来判断客户是否是持续的访问网站,如果设置的是6个小时,如果客户在6个小时内第二次访问网站
    //系统会认为这是客户的一次连贯的访问。第二次访问后,此cookie会更新超时时间
    _fto = Get_Cookie( '_fto' );  
    // //永久cookie,这个cookie存在,那么说明是老客户了
    _fta = Get_Cookie( '_fta' );   
    
    if(_fto){
      //继续的访问,访问的延伸。无所谓refer,和return
      //更新超时时间:
      Set_Cookie( '_fto',1, 0.25, '/', '', '' );   //online - one day
    }else{
      //相当于第一次访问。
      
      thisreferrer = document.referrer || '';
      // 存在refer 则记录refer  ,如果不存在,则设置redirect
      if(!thisreferrer){
        thisreferrer_domain = "redirect";
      }else{
        thisreferrer_domain = thisreferrer.replace('http://','').replace('https://','').split(/[/?#]/)[0];
      }
      // 第一次访问网站的时候会记录访问来源。
      Set_Cookie( '_ftreferdomain',thisreferrer_domain, 1, '/', '', '' );   //refer  - one day
      // 第一次访问的时候会设置_fto为6个小时。
      Set_Cookie( '_fto',1, 0.25, '/', '', '' );   //online - one day
          
        
      //如果存在_fta 则代表这个客户肯定访问过网站信息。
      if(_fta){
        //老客户,设置的cookie:来源域名,是否在线,是否是老客户
        Set_Cookie( '_ftreturn',1, 36500, '/', '', '' );   // is return  - one day
      }else{
        //新客户
        Set_Cookie( '_ftreturn',0, 36500, '/', '', '' );   // is return  - one day
      }
    }
    //referrer 域名,是否是老客户,是否是在线状态
    params.first_referrer_domain = Get_Cookie('_ftreferdomain');
    params.is_return = Get_Cookie('_ftreturn');
    //params.online = Get_Cookie('_fto');

    
    //设置uuid,如果 _fta存在,那么设置uuid为它的值,如果不存在,那么重新获取uuid。
    if(cookie_uuid = Get_Cookie('_fta') ){
      params.uuid = cookie_uuid;
    }else{
      params.uuid = uuid;
      Set_Cookie( '_fta', uuid, 36500, '/', '', '' );
    }
    
    
    
    }
    //Window对象数据
    if(window && window.screen) {
    //params.sh = window.screen.height || 0;
    //屏幕分辨率和屏幕的画质
    if(window.devicePixelRatio){
      devicePixelRatio = window.devicePixelRatio;
      params.device_pixel_ratio = devicePixelRatio;
      params.resolution = (window.screen.width*devicePixelRatio || 0) +"x"+ (window.screen.height*devicePixelRatio || 0);
    }else{
      params.resolution = (window.screen.width || 0) +"x"+ (window.screen.height || 0);
    }
    params.color_depth = window.screen.colorDepth || 0;
    }
  
    
  
  
    //解析_maq配置
  if(_maq) {
    for(var i in _maq) {
      x = _maq[i][0];
      if(x){
        //email
        //当前的customer email如果和cookie一样,那么使用customer email
        //如果不一样,那么保存customer email到cookie _fte
        //对于customer name同样也是这样
        if(x == 'login_email'){
          current_customer_email = _maq[i][1];
          //存在cookie 
          if(cookie_customer_email = Get_Cookie( '_fte' )){
            //当前cookie存在,并且与传递过来的相同
            if(current_customer_email != cookie_customer_email){
              Set_Cookie( '_fte', current_customer_email, '36500', '/', '', '' );
            }
          //不存在cookie
          }else{
            Set_Cookie( '_fte', current_customer_email, '36500', '/', '', '' );
          }
          params[x] = current_customer_email;
        
        }else{
          params[x] = _maq[i][1];
        }
      }
    }
  }
  //如果cookie中存在客户邮箱,那么从cookie中获取
  if(!params.login_email){
    if(Get_Cookie( '_fte' )){
      params.login_email = Get_Cookie( '_fte' )
    }
  }
  
    //拼接参数串,形成url,然后通过图片的方式传递数据
    var args = '';
    for(var i in params) {
    if(args != '') {
      args += '&';
    }
    args += i + '=' + encodeURIComponent(params[i]);
    }
     
    //通过Image对象请求后端脚本
    var img = new Image(1, 1);
    img.src = 'http://trace.tomtop.com/trace.php?' + args;
 })();

原理:js手机的数据,通过参数的方式拼成一个url  :http://trace.tomtop.com/trace.php? xxxxx ,然后把数据传递给trace.php

 

2. ip找到国家(穿插部分)

Geoip geoip-api-php 库包使用 – 通过ip 找到国家

 

3. php 存储(market.php)这里的geoip就是第二部分的通过ip找到国家

<?php
//exit;
//date_default_timezone_set('Asia/Shanghai');
# 时区
ini_set('date.timezone','UTC');
# ip 库
include("/www/web/market/common/lib/geoip-api-php-1.14/src/geoip.inc");

# log 测试函数
function logdd($info){
  if(is_array($info) || is_object($info)){
    $info = var_export($info,true);
  }
  //echo $info;exit;
  $logfile = './logs/my.log';
  $handle = fopen($logfile,"a+");/*根据需要更改这里的参数*/ 
  $contents = fwrite($handle,$info."\n"); 
  fclose($handle);
      
}


#得到IP地址。
function get_client_ip() {
  $ipaddress = '';
  if (getenv('HTTP_CLIENT_IP'))
    $ipaddress = getenv('HTTP_CLIENT_IP');
  else if(getenv('HTTP_X_FORWARDED_FOR'))
    $ipaddress = getenv('HTTP_X_FORWARDED_FOR');
  else if(getenv('HTTP_X_FORWARDED'))
    $ipaddress = getenv('HTTP_X_FORWARDED');
  else if(getenv('HTTP_FORWARDED_FOR'))
    $ipaddress = getenv('HTTP_FORWARDED_FOR');
  else if(getenv('HTTP_FORWARDED'))
     $ipaddress = getenv('HTTP_FORWARDED');
  else if(getenv('REMOTE_ADDR'))
    $ipaddress = getenv('REMOTE_ADDR');
  else
    $ipaddress = 'UNKNOWN';
  return $ipaddress;
}

//得到国家。通过ip 支持ipv6  已经测试。
function getCountryByIp($ip){
  $gi = geoip_open("/www/web/market/common/lib/geoip/GeoIP.dat", GEOIP_STANDARD);
  if(strstr($ip,":")){
    $country_code = geoip_country_code_by_addr_v6($gi,$ip);
    $country_name = geoip_country_name_by_addr_v6($gi,$ip);
  }else{
    $country_code = geoip_country_code_by_addr($gi,$ip);
    $country_name = geoip_country_name_by_addr($gi,$ip);
  }
  geoip_close($gi);
  return [
    "country_code" => $country_code,
    "country_name" => $country_name,
  ];
}

#得到递增id
/*
function increament($m,$db_name,$tablename){
  
  $ids = "ids";
  $db_name = "tracedb";
  $db = $m->selectDB($db_name);
  $col = $m->selectDB($db_name)->$ids;
  
  $query = array('name'=>'trace_2014_11_24');
  $update = array('?inc'=>array('id'=>1));
  $result = $db->command(
            array(
            "findandmodify" => "ids",
            "query" => $query,
            "update" => $update,
            )
          );

  return $result['value']['id'];
} 
*/

$delay_time = " -0 hours";	
$insertTimeStamp = strtotime(date('Y-m-d H:i:s').' '.$delay_time);
$insertDateTime = date('Y-m-d H:i:s',$insertTimeStamp);
$insertDate = date('Y-m-d',$insertTimeStamp);
$get 						= array();
$get['ip'] 					= get_client_ip();
#$get['server_datetime']	= date('Y-m-d H:i:s',strtotime('-12 hours'));    //+3 hours  延后12个小时,美国时间
$get['service_date_str']	= $insertDate;
$get['service_datetime'] 	=  new MongoDate($insertTimeStamp);   #北京时间
$get['service_timestamp'] 	=  (float)$insertTimeStamp;
foreach($_GET as $k=>$v){
  $get[$k] = $v;
}
  # ip6 example
  #$get['ip'] = "2001:0DB8:0:0:0:0:1428:0000";
$ip 					= $get['ip'];
$website_id 			= $get['website_id'];
$countInfo 				= getCountryByIp($ip);
$get['country_code'] 	= $countInfo['country_code'];
$get['country_name'] 	= $countInfo['country_name'];


#连接到mongodb
$m = new MongoClient('mongodb://localhost:27017');
$database_name 		= "tracedb";  
#trace_网站编号_年份_月_initial_data
$collection_name 	= "trace_".$website_id."_".date("Y_m",strtotime($delay_time))."_initial_data";
$db 		= $m->$database_name;
$collection = $db->$collection_name;
#得到递增id。
#$id = increament($m,$database_name,$collection_name);

#$get["_id"] = $id; 
#var_dump($get);
#订单信息
if($get['order']){
  $get['order'] = json_decode($get['order'],true);
  $get['order_status'] = 'fail';
}
#购物车信息。
if($get['cart']){
  $get['cart'] = json_decode($get['cart']);
}

#购物车信息。
if($get['search']){
  $get['search'] = json_decode($get['search']);
}


#插入数据到mongodb
if(!empty($get) && is_array($get)){
  $collection->insert($get);
  echo "Insert succsessfully";
}

   
   
   
   
   
   
   
   
   

这样就把数据保存到mongodb里面去了。

然后就可以通过mongodb的mapreduce进行统计分析数据了。

mongodb 导出csv文件

/usr/bin/mongoexport  --csv  -d erp -f _id,item_no,gross_default,profit,product_cost,order_gross_default,order_profit,order_product_cost,profit_difference,gross_difference,product_cost_difference -c tmp_erp_order_check_problem_profit -o  /backup/erp/tmp_erp_order_check_problem_profit-07-09.csv

/usr/bin/mongoexport  --csv  -d erp  -f _id,item_no,gross_default,profit,product_cost,order_gross_default,order_profit,order_product_cost,profit_difference,gross_difference,product_cost_difference  -c tmp_erp_order_check_problem_gross -o  /backup/erp/tmp_erp_order_check_problem_gross-07-09.csv

/usr/bin/mongoexport  --csv  -d erp  -f _id,item_no,gross_default,profit,product_cost,order_gross_default,order_profit,order_product_cost,profit_difference,gross_difference,product_cost_difference  -c tmp_erp_order_check_problem_product_cost -o  /backup/erp/tmp_erp_order_check_problem_product_cost-07-09.csv

上面是mongodb 表  导出 csv 的一个例子

通过配置的方式重写某个Yii2 文件 或第三方扩展文件

1.我需要重写某个Yii的类方法,譬如:yii\helpers\ArrayHelper

我需要新建一个类,继承,然后覆盖这个类的方法。
如果我的系统都成型了,然后我在调用这个类的地方,需要将

use yii\helpers\ArrayHelper

改成

use xxxxxx\yii\helpers\ArrayHelper

2.现在用classMap

Yii::$classMap['yii\helpers\ArrayHelper'] = '@xxxxxx/yii/helpers/ArrayHelper.php';

直接就行了,对yii的文件不需要改动,调用的地方也不用改动。

可能是我在做fecshop考虑重写的事情,看到这个,真的豁然开朗的感觉,
这样可以在不改动yii2文件,和不改动我的fecshop文件的前提下,重写任何文件了

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

下面是代码举例说明的详细步骤:

  1. 下面是我写的一个类,内容如下:
<?php
/**
 * FecShop file.
 *
 * @link http://www.fecshop.com/
 * @copyright Copyright (c) 2016 FecShop Software LLC
 * @license http://www.fecshop.com/license/
 */
namespace fecshop\app\appfront\helper\test;
use Yii;
use fec\helpers\CConfig;
use fec\controllers\FecController;
use yii\base\InvalidValueException;
/**
 * @author Terry Zhao <2358269014@qq.com>
 * @since 1.0
 */
class My
{
  
  public static function test(){
    echo 'this is my first test php file';
  }
  
}

2. 然后我在controller中对这个类的静态方法进行了调用:

<?php
/**
 * FecShop file.
 *
 * @link http://www.fecshop.com/
 * @copyright Copyright (c) 2016 FecShop Software LLC
 * @license http://www.fecshop.com/license/
 */
namespace fecshop\app\appfront\modules\Customer\controllers;
use Yii;
use fec\helpers\CModule;
use fec\helpers\CRequest;
use fecshop\app\appfront\modules\AppfrontController;
use fecshop\app\appfront\helper\test\My;
/**
 * @author Terry Zhao <2358269014@qq.com>
 * @since 1.0
 */
class AccountController extends AppfrontController
{
  
  public function actionLogin()
    {
    My::test();
    exit;
  }
}

然后我在很多地方对My::test进行了调用,然后我想对这个My类的test的内容进行重写,但是前提是My这个文件是库包文件,我不能直接进行修改,否则,以后的升级会出现问题,那么我需要用一个类继承这个My类,然后重写test()方法,然后在各个调用My::test()的地方修改use部分,改成新的类的namespaces,这种方式的坏处是修改量大,对于维护起来很费劲,下面介绍另外一种方法,通过在Yii::classMap中配置:

Yii::$classMap['yii\helpers\ArrayHelper'] = '@app/components/ArrayHelper.php';

官网部分的介绍为:

http://www.yiiframework.com/doc-2.0/guide-helper-overview.html#customizing-helper-classes

下面是代码步骤:

1.原来的类的内容为:

<?php
/**
 * FecShop file.
 *
 * @link http://www.fecshop.com/
 * @copyright Copyright (c) 2016 FecShop Software LLC
 * @license http://www.fecshop.com/license/
 */
namespace fecshop\app\appfront\helper\test;
use Yii;
use fec\helpers\CConfig;
use fec\controllers\FecController;
use yii\base\InvalidValueException;
/**
 * @author Terry Zhao <2358269014@qq.com>
 * @since 1.0
 */
class My
{
  
  public static function test(){
    echo 'this is my first test php file';
  }
  
}

2.我写一个新类: 文件路径为: appfront/helper/My.php ,我想让controller调用的类为下面的类

<?php
/**
 * FecShop file.
 *
 * @link http://www.fecshop.com/
 * @copyright Copyright (c) 2016 FecShop Software LLC
 * @license http://www.fecshop.com/license/
 */
namespace fecshop\app\appfront\helper\test;
use Yii;
use fec\helpers\CConfig;
use fec\controllers\FecController;
use yii\base\InvalidValueException;
/**
 * @author Terry Zhao <2358269014@qq.com>
 * @since 1.0
 */
class My{
  
  public static function test(){
    echo 'this is my appfront test php file';
  }
  
}

注意:namespace和上面的那个My类的要一样,而不是按照 appfront/helper/My.php 写成 namespace appfront\helper  ,这样会报错的。

3. 我添加Yii::classMap  数组的值的新的My类的文件路径

Yii::$classMap['fecshop\app\appfront\helper\test\My'] = ['@appfront/helper/My.php'];

然后调用后,发现调用的是新的My类。

4. 需要注意的是,新的类的名字必须和之前的类的名字一样,否则会出错,另外,namespace要一致,一样。

5. 我们希望通过配置文件的方式,这样比较方面,我们可以这样做。

5.1 在app/config/下面添加文件 YiiClassMap.php ,内容如下:

<?php
return [
  'fecshop\app\appfront\helper\test\My' => '@appfront/helper/My.php',   
  
];

在web/index.php的代码

$application = new yii\web\Application($config);   上面添加代码:

/**
 * yii class Map Custom
 * 
 */ 
$yiiClassMap = require(__DIR__ . '/../config/YiiClassMap.php');
if(is_array($yiiClassMap) && !empty($yiiClassMap)){
  foreach($yiiClassMap as $namespace => $filePath){
    Yii::$classMap[$namespace] = $filePath;
  }
}

这样,通过上面的配置文件,就可以把classMap执行了,以后如果添加classMap,直接在文件

app/config/YiiClassMap.php 文件里面的数组中添加一条数据就可以了。

您也可以把yii2的库包文件,yii2的某个扩展库包里面的几个文件,通过这种方式进行重写。这个是非常非常非常方便的,尤其对于你写了一个扩展,让大家用,你的扩展需要升级,因此别人不能直接动你的库包文件,不然升级后,修改的会被覆盖,通过这种方式就可以解决这个问题。

总之,这个功能是更好的进行文件重写。

 

对于Yii2的自动加载的原理,可以参看:http://www.digpage.com/autoload.html,这里不多写了。