PHP实现站点pv,uv统计(一)
具体步骤分为数据采集脚本,数据收取服务,数据分析脚本,数据存储服务采集脚本一般有两种形式,一种是简单的页面插入一个图片进行请求,一种是复杂的动态生成js标签,引入一段js(这时采集服务器会网往客户端写cookie),js采集浏览器数据与cookie,然后发送请求。
数据收取服务一般为web服务,可以是apache,nginx,或者swoole,这里主要看采集的压力,适当做负载均衡,可以爱脚本端做,也可以在服务端做,注意客户端ip的穿透。
脚本分析可以使用任何脚本,例如php,python。
数据存储分为两部,一个是采集数据的存储,一个是分析之后的数据的存储,一般来讲原始数据是需呀保留的,所以原始数据采集可以使用文本保存在单机,或者使用redis等可固话的存储容器保存。
选用不同的形式对扩展以后的服务有一定的影响,暂且不谈,在pv/uv只有几百万的站点,或者几千万的站点web服务压力基本不大,每天的原始数据存储会有几百M。
细节上可以使用不同的技术,例如加入memcached缓存,使用多进程多线程等
我使用的方案是使用nginx做采集web服务器,使用js脚本采集数据,采集的数据按五分钟分500个文件存储避免文本的冲突,然后php五分钟定期处理数据,统计结果记入redis保存。
js采集脚本如下:
(function () {
var c = {
id: '{$sid}',
dm: [
{$dm}
],
nv: {$nv},
vdur: {$vdur},
age: {$age},
rec: {$rec},
uid: {$uid},
cf : {$cf}
};
var l = !0,
m = null,
n = !1;
var p = function () {
function a(a) {
/["\\\x00-\x1f]/.test(a) && (a = a.replace(/["\\\x00-\x1f]/g, function (a) {
var b = d;
if (b) return b;
b = a.charCodeAt();
return '\\u00' + Math.floor(b / 16) .toString(16) + (b % 16) .toString(16)
}));
return '"' + a + '"'
}
function b(a) {
return 10 > a ? '0' + a : a
}
var d = {
'': '\\b',
'\t': '\\t',
'\n': '\\n',
'\f': '\\f',
'\r': '\\r',
'"': '\\"',
'\\': '\\\\'
};
return function (d) {
switch (typeof d) {
case 'undefined':
return 'undefined';
case 'number':
return isFinite(d) ? String(d): 'null';
case 'string':
return a(d);
case 'boolean':
return String(d);
default:
if (d === m) return 'null';
if (d instanceof Array) {
var f = [
'['
],
h = d.length,
k,
g,
u;
for (g = 0; g < h; g++) switch (u = d, typeof u) {
case 'undefined':
case 'function':
case 'unknown':
break;
default:
k && f.push(','),
f.push(p(u)),
k = 1
}
f.push(']');
return f.join('')
}
if (d instanceof Date) return '"' + d.getFullYear() + '-' + b(d.getMonth() + 1) + '-' + b(d.getDate()) + 'T' + b(d.getHours()) + ':' + b(d.getMinutes()) + ':' + b(d.getSeconds()) + '"';
k = [
'{'
];
for (h in d) if (Object.prototype.hasOwnProperty.call(d, h)) switch (g = d, typeof g) {
case 'undefined':
case 'unknown':
case 'function':
break;
default:
f && k.push(','),
f = 1,
k.push(p(h) + ':' + p(g))
}
k.push('}');
return k.join('')
}
}
}();
function q(a, b) {
var d = a.match(RegExp('(^|&|\\?|#)(' + b + ')=([^&#]*)(&|$|#)', ''));
return d ? d : m
}
function v(a) {
return (a = (a = a.match(/^(https?:\/\/)?([^\/\?#]*)/)) ? a.replace(/.*@/, ''): m) ? a.replace(/:\d+$/, ''): a
};
function w(a, b) {
if (window.sessionStorage) try {
window.sessionStorage.setItem(a, b)
} catch (d) {
}
}
function x(a) {
return window.sessionStorage ? window.sessionStorage.getItem(a): m
};
function y(a, b, d) {
var e;
d.f && (e = new Date, e.setTime(e.getTime() + d.f));
document.cookie = a + '=' + b + (d.domain ? '; domain=' + d.domain : '') + (d.path ? '; path=' + d.path : '') + (e ? '; expires=' + e.toGMTString(): '') + (d.r ? '; secure' : '')
};
function z(a, b) {
var d = new Image,
e = 'mini_yp_log_' + Math.floor(2147483648 * Math.random()) .toString(36);
window = d;
d.onload = d.onerror = d.onabort = function () {
d.onload = d.onerror = d.onabort = m;
d = window = m;
b && b(a)
};
d.src = a
};
var A;
function D() {
if (!A) try {
A = document.createElement('input'),
A.type = 'hidden',
A.style.display = 'none',
A.addBehavior('#default#userData'),
document.getElementsByTagName('head') .appendChild(A)
} catch (a) {
return n
}
return l
}
function E(a, b, d) {
var e = new Date;
e.setTime(e.getTime() + d || 31536000000);
try {
window.localStorage ? (b = e.getTime() + '|' + b, window.localStorage.setItem(a, b)): D() && (A.expires = e.toUTCString(), A.load(document.location.hostname), A.setAttribute(a, b), A.save(document.location.hostname))
} catch (f) {
}
}
function H(a) {
if (window.localStorage) {
if (a = window.localStorage.getItem(a)) {
var b = a.indexOf('|'),
d = a.substring(0, b) - 0;
if (d && d > (new Date) .getTime()) return a.substring(b + 1)
}
} else if (D()) try {
return A.load(document.location.hostname),
A.getAttribute(a)
} catch (e) {
}
return m
};
function I(a, b, d) {
a.attachEvent ? a.attachEvent('on' + b, function (b) {
d.call(a, b)
}): a.addEventListener && a.addEventListener(b, d, n)
};
function N(a, b) {
return '' === {
}.toString.call(a)
};
function Z(a, b) {
a = '.' + a.replace(/:\d+/, '');
b = '.' + b.replace(/:\d+/, '');
var d = a.indexOf(b);
return - 1 < d && d + b.length == a.length
}
function wa(a, b) {
a = a.replace(/^https?:\/\//, '');
return 0 == a.indexOf(b)
}
function Y(a) {
for (var b = 0; b < c.dm.length; b++) if ( - 1 < c.dm.indexOf('/')) {
if (wa(a, c.dm)) return l
} else {
var d = v(a);
if (d && Z(d, c.dm)) return l
}
return n
}
function ra(a) {
for (var b = [
], d = 0, e = R.length; d < e; d++) {
var f = R,
h = a.a;
'undefined' != typeof h && '' !== h && b.push(f + '=' + encodeURIComponent(h))
}
d = a.a.et;
(0 === d || 90 === d) && a.a.rt && b.push('rt=' + encodeURIComponent(a.a.rt));
return b.join('&')
}
function na() {
var a = 'Yp_cv_' + c.id;
try {
if (y(a, '', {
domain: la(),
path: ma(),
f: - 1
}), window.sessionStorage && window.sessionStorage.removeItem(a), window.localStorage) window.localStorage.removeItem(a);
else if (D()) try {
A.load(document.location.hostname),
A.removeAttribute(a),
A.save(document.location.hostname)
} catch (b) {
}
} catch (d) {
}
}
function ma() {
for (var a = 0, b = c.dm.length; a < b; a++) {
var d = c.dm;
if ( - 1 < d.indexOf('/') && wa(document.location.href, d)) return d.replace(/^[^\/]+(\/.*)/, '$1') + '/'
}
return '/'
}
function la() {
for (var a = document.location.hostname, b = 0, d = c.dm.length; b < d; b++) if (Z(a, c.dm)) return c.dm.replace(/(:\d+)?[\/\?#].*/, '');
return a
}
function pa() {
var a = x('Yp_unsent_' + c.id);
if (a) for (var a = a.split(','), b = 0, d = a.length; b < d; b++) z(Q + '//' + decodeURIComponent(a) .replace(/^https?:\/\//, ''), function (a) {
X(a)
})
}
function X(a) {
var b = x('Yp_unsent_' + c.id) || '';
b && ((b = b.replace(RegExp(encodeURIComponent(a.replace(/^https?:\/\//, '')) .replace(/([\*\(\)])/g, '\\$1') + '(%26u%3D[^,]*)?,?', 'g'), '') .replace(/,$/, '')) ? w('Yp_unsent_' + c.id, b): window.sessionStorage && window.sessionStorage.removeItem('Yp_unsent_' + c.id))
}
function qa(a, b) {
var d = x('Yp_unsent_' + c.id) || '',
e = a.a.u ? '' : '&u=' + encodeURIComponent(document.location.href),
d = encodeURIComponent(b.replace(/^https?:\/\//, '') + e) + (d ? ',' + d : '');
w('Yp_unsent_' + c.id, d)
}
(function () {
function a() {
if (!a.b) {
a.b = l;
for (var b = 0, d = e.length; b < d; b++) e()
}
}
function b() {
try {
document.documentElement.doScroll('left')
} catch (d) {
setTimeout(b, 1);
return
}
a()
}
var d = n,
e = [
],
f;
document.addEventListener ? f = function () {
document.removeEventListener('DOMContentLoaded', f, n);
a()
}
: document.attachEvent && (f = function () {
'complete' === document.readyState && (document.detachEvent('onreadystatechange', f), a())
});
(function () {
if (!d) if (d = l, 'complete' === document.readyState) a.b = l;
else if (document.addEventListener) document.addEventListener('DOMContentLoaded', f, n),
window.addEventListener('load', a, n);
else if (document.attachEvent) {
document.attachEvent('onreadystatechange', f);
window.attachEvent('onload', a);
var e = n;
try {
e = window.frameElement == m
} catch (k) {
}
document.documentElement.doScroll && e && b()
}
}) ();
return function (b) {
a.b ? b(): e.push(b)
}
}) () .b = n;
function ta() {
this.d = this.j = (new Date) .getTime();
this.i = 0;
'object' == typeof document.onfocusin ? (I(document, 'focusin', $(this)), I(document, 'focusout', $(this))): (I(window, 'focus', $(this)), I(window, 'blur', $(this)))
}
function $(a) {
return function (b) {
if (!(b.target && b.target != window)) {
if ('blur' == b.type || 'focusout' == b.type) a.i += (new Date) .getTime() - a.d;
a.d = (new Date) .getTime()
}
}
}
function sa(a) {
return function () {
a.a.nv = 0;
a.a.st = 4;
a.a.et = 3;
a.a.ep = (new Date) .getTime() - a.e.j + ',' + ((new Date) .getTime() - a.e.d + a.e.i);
W(a)
}
}
function W(a) {
a.a.rnd = Math.round(2147483647 * Math.random());
a.a.api = a.a.api || a.c ? a.a.api + '_' + a.c : '';
var b = Q + '//{$callurl}?' + ra(a);
a.a.api = 0;
a.c = 0;
qa(a, b);
z(b, function (a) {
X(a)
})
}
var aa = navigator.cookieEnabled,
ba = navigator.javaEnabled(),
ha = navigator.language || navigator.browserLanguage || navigator.systemLanguage || navigator.userLanguage || '',
ia = (window.screen.width || 0) + 'x' + (window.screen.height || 0),
ja = window.screen.colorDepth || 0;
var O = 0,
P = Math.round( + new Date / 1000),
Q = 'https:' == document.location.protocol ? 'https:' : 'http:',
//参数数组
//cc : 是否支持写数据到浏览器(cookie,sessionStorage,localStorage,userData)
//ck : 是否支持cookie
//cl : 浏览器颜色位数
//ds : 浏览器分辨率
//ep : 事件描述
//et : 事件类型,默认是0为一般统计,3为关闭事件
//fl : flash版本
//ja : 是否支持java
//ln : 浏览器语言
//lt : 30天内的最后一次首次访问的时间,首次访问为空
//nv : 是否开启一次新访问,可以理解为uv,但是不是独立访客
//rnd: 随机数
//si : 统计id,站点标示
//st : 外域来源为3,本域为1,4
//su : 来源url
//v: 当前脚本版本
//cv : 用户自定义数据
//lv : 当月新访问<4 为2 ,=4 为3, =0 为1,可以理解为客户新访问频次
//api: 未知,与事件相关
//tt : 站点title
//u: 站点url
//cf : m点 1,站点0
//uid : 会员id
//pt : 平台
//ocu : 操作系统
//ua : 浏览器类型
R = 'cc ck cl ds ep et fl ja ln lt nv rnd si st su v cv lv api tt u gt cf uid pt ocu ua'.split(' ');
function V() {
if ('undefined' == typeof window['_yphm_loaded_' + c.id]) {
window['_yphm_loaded_' + c.id] = l;
var a = this;
a.a = {
};
a.q = [
];
a.p = {
push: function () {
a.k.apply(a, arguments)
}
};
a.c = 0;
a.h = n;
ka(a)
}
}
V.prototype = {
getData: function (a) {
try {
var b = RegExp('(^| )' + a + '=([^;]*)(;|$)') .exec(document.cookie);
return (b ? b : m) || x(a) || H(a)
} catch (d) {
}
},
setData: function (a, b, d) {
try {
y(a, b, {
domain: la(),
path: ma(),
f: d
}),
d ? E(a, b, d): w(a, b)
} catch (e) {
}
},
k: function (a) {
if (N(a, 'Array')) {
var b = function (a) {
return a.replace ? a.replace(/'/g, '\'0') .replace(/\*/g, '\'1') .replace(/!/g, '\'2'): a
},
d = function (a) {
for (var b in a) if ({
}.hasOwnProperty.call(a, b)) {
var e = a;
N(e, 'Object') || N(e, 'Array') ? d(e): a = String(e)
}
};
switch (a) {
case '_trackPageview':
if (1 <
a.length && a.charAt && '/' == a.charAt(0)) {
this.a.api |= 4;
this.a.et = 0;
this.a.ep = '';
this.h ? (this.a.nv = 0, this.a.st = 4): this.h = l;
var b = this.a.u,
e = this.a.su;
this.a.u = Q + '//' + document.location.host + a;
this.a.su = document.location.href;
W(this);
this.a.u = b;
this.a.su = e
}
break;
case '_trackEvent':
2 < a.length && (this.a.api |= 8, this.a.nv = 0, this.a.st = 4, this.a.et = 4, this.a.ep = b(a) + '*' + b(a) + (a ? '*' + b(a): '') + (a ? '*' + b(a): ''), W(this));
break;
case '_setCustomVar':
if (4 > a.length) break;
var e = a,
f = a || 3;
if (0 <
e && 6 > e && 0 < f && 4 > f) {
this.c++;
for (var h = (this.a.cv || '*') .split('!'), k = h.length; k < e - 1; k++) h.push('*');
h = f + '*' + b(a) + '*' + b(a);
this.a.cv = h.join('!');
a = this.a.cv.replace(/[^1](\*[^!]*){2}/g, '*') .replace(/((^|!)\*)+$/g, '');
'' !== a ? this.setData('Yp_cv_' + c.id, encodeURIComponent(a), c.age): na()
}
break;
case '_trackOrder':
a = a;
N(a, 'Object') && (d(a), this.a.api |= 16, this.a.nv = 0, this.a.st = 4, this.a.et = 94, this.a.ep = p(a), W(this));
break;
case '_trackMobConv':
if (a = {
webim: 1,
tel: 2,
map: 3,
sms: 4,
callback: 5,
share: 6
}
[
a
]) this.a.api |=
32,
this.a.et = 93,
this.a.ep = a,
W(this);
break;
case '_trackRTPageview':
a = a;
N(a, 'Object') && (d(a), a = p(a), 512 >= encodeURIComponent(a) .length && (this.a.api |= 64, this.a.rt = a));
break;
case '_trackRTEvent':
a = a,
N(a, 'Object') && (d(a), a = p(a), 1024 >= encodeURIComponent(a) .length && (b = this.a.rt, this.a.api |= 128, this.a.et = 90, this.a.rt = a, W(this), this.a.rt = b))
}
}
}
};
function ka(a) {
try {
var b,
d,
e,
f,
h,
k,
g;
O = a.getData('Yp_lpvt_' + c.id) || 0;
13 == O.length && (O = Math.round(O / 1000));
if (document.referrer) {
var u = n;
if (Y(document.referrer) && Y(document.location.href)) u = l;
else var oa = v(document.referrer),
u = Z(oa || '', document.location.hostname);
d = u ? P - O > c.vdur ? 1 : 4 : 3
} else d = P - O > c.vdur ? 1 : 4;
b = 4 != d ? 1 : 0;
if (k = a.getData('Yp_lvt_' + c.id)) {
g = k.split(',');
for (var F = g.length - 1; 0 <= F; F--) 13 == g.length && (g = '' + Math.round(g / 1000));
for (; 2592000 < P - g; ) g.shift();
h = 4 > g.length ? 2 : 3;
for (1 === b && g.push(P); 4 <
g.length; ) g.shift();
k = g.join(',');
f = g
} else k = P,
f = '',
h = 1;
a.setData('Yp_lvt_' + c.id, k, c.age);
a.setData('Yp_lpvt_' + c.id, P);
e = P == a.getData('Yp_lpvt_' + c.id) ? '1' : '0';
if (0 == c.nv && Y(document.location.href) && ('' == document.referrer || Y(document.referrer))) b = 0,
d = 4;
a.a.nv = b;
a.a.st = d;
a.a.cc = e;
a.a.lt = f;
a.a.lv = h;
a.a.si = c.id;
a.a.uid = c.uid;
a.a.cf = c.cf;
a.a.su = document.referrer;
a.a.u= document.location.href;
a.a.pt = navigator.platform;
var ua = navigator.userAgent.toLowerCase();
var s;
if(s = ua.match(/msie ([\d.]+)/)) a.a.ua = 'IE' + s;
else if(s = ua.match(/firefox\/([\d.]+)/)) a.a.ua = 'Firefox' + s;
else if(s = ua.match(/chrome\/([\d.]+)/))a.a.ua = 'Chrome' + s;
else if(s = ua.match(/opera.([\d.]+)/))a.a.ua = 'Opera' + s;
else if(s = ua.match(/version\/([\d.]+).*safari/)) a.a.ua = 'Safari' + s;
else a.a.ua = 'unknown';
a.a.ocu = navigator.oscpu;
a.a.ds = ia;
a.a.cl = ja + '-bit';
a.a.ln = ha;
a.a.ja = ba ? 1 : 0;
a.a.ck = aa ? 1 : 0;
var J = a.a;
b = '';
if (navigator.plugins && navigator.mimeTypes.length) {
var B =
navigator.plugins['Shockwave Flash'];
B && B.description && (b = B.description.replace(/^.*\s+(\S+)\s+\S+$/, '$1'))
} else if (window.ActiveXObject) try {
var ca = new ActiveXObject('ShockwaveFlash.ShockwaveFlash');
ca && (b = ca.GetVariable('$version')) && (b = b.replace(/^.*\s+(\d+),(\d+).*$/, '$1.$2'))
} catch (ya) {
}
J.fl = b;
a.a.v = '1.0.0';
a.a.cv = decodeURIComponent(a.getData('Yp_cv_' + c.id) || '');
(a.a.tt = document.title || '')
//屏蔽不是新uv不记录tt
//1 == a.a.nv && (a.a.tt = document.title || '');
//暂时不清楚,18touch里没有看到这个参数
a.a.api = 0;
//var G = document.location.href;
//a.a.cm = q(G, 'hmmd') || '';
0 == a.a.nv ? pa(): X('.*');
if (c.rec) a.a.nv ? (a.g = encodeURIComponent(document.referrer), window.sessionStorage ? w('Yp_from_' + c.id, a.g): E('Yp_from_' + c.id, a.g, 86400000)): a.g = (window.sessionStorage ? x('Yp_from_' + c.id):
H('Yp_from_' + c.id)) || '';
a.e = new ta;
//I(window, 'beforeunload', sa(a));
var t = window._hmt;
if (t && t.length) for (r = 0; r < t.length; r++) {
var C = t;
switch (C) {
case '_setAccount':
1 < C.length && /^{32}$/.test(C) && (a.a.api |= 1, window._yphm_account = C);
break;
case '_setAutoPageview':
if (1 < C.length) {
var U = C;
if (n === U || l === U) a.a.api |= 2,
window._yphm_autoPageview = U
}
}
}
if ('undefined' === typeof window._yphm_account || window._yphm_account === c.id) {
window._yphm_account = c.id;
var M = window._hmt;
if (M &&
M.length) for (var t = 0, xa = M.length; t < xa; t++) a.k(M);
window._hmt = a.p
}
if ('undefined' === typeof window._yphm_autoPageview || window._yphm_autoPageview === l)
a.h = l,a.a.et = 0,a.a.ep = '',W(a)
} catch (ga) {
a = [
],
a.push('si=' + c.id),
a.push('n=' + encodeURIComponent(ga.name)),
a.push('m=' + encodeURIComponent(ga.message)),
a.push('r=' + encodeURIComponent(document.referrer)),
z(Q + '//{$callurl}?' + a.join('&'))
}
}
new V;
}) ();
脚本的函数说明如下:
//定义p方法,将传入的参数转换为字符串形式
//定义q方法,从字符串a里找出含有字符串b的值,如果没有则为null,貌似是从url请求参数里获取值
//定义v方法,取url中协议后的第一个/之前的内容并将端口号去掉,例如http://www.18touch.com:999/ 过滤之后得到www.18touch.com
//定义w方法,在html5的属性sessionStorage里存放window.sessionStorage=b;,百度统计存放的是访问时间,估计用于计算回话时间
//定义x方法,在html5的属性sessionStorage里取出w方法定义的key为a的值,不支持这个属性返回null
//定义y方法,设置cookie,a=b,cookie的属性在d对象里面
//定义z方法,请求a地址,并做记录,在请求完成,出错,拒绝之后,重置。如果定义了回调b方法,则执行b(a);
//定义D方法,全局变量A为空则执行将A变成一个userdata对象,用于ie浏览器储存数据,报错返回false;全局变量A不为空返回true;
//定义E方法,如果支持window.localStorage,则保持window.localStorage=now+d|b,如果不支持再看是否支持userdata,如果支持,在域名下使用userdata存储a=b,过期时间为now+d
//定义H方法,如果没有过期的话取出从E方法存储的key为a的值,否则返回null。
//定义I方法,在a元素上绑定事件b,处理函数为d
//定义N方法,判读a的类型是否为b
//定义V方法,启动统计功能
//定义V原型方法,
//定义pa方法,从sessionStorage里取Hm_unsent_字符串,按,分隔,依次调用z方法发送请求,并调用回调函数X
//定义X方法,用作请求后的回调,去掉sessionStorage里的Hm_unsent_字符串里的请求url,如果Hm_unsent_为空,删除Hm_unsent_
//定义qa方法,在sessionStorage里的key:Hm_unsent_后添加url b,如果a.a.u存在,后面还要添加&u=当前url的后缀
//定义W方法,调用qa往sessionStorage的Hm_unsent_里存储url:hm.baidu.com/hm.gif,调用z方法发送请求,并执行回调X
//定义sa方法,返回一个初始化a.a数组,并执行触发请求的方法,在window.beforeunload触发,关闭页面时触发
//定义ka方法,执行信息收集与消息发送,以及事件监听
//定义ra方法,组装R请求的字符串,数据从a.a数组里面获取
//定义na方法,从cookie,sessionStorage,localStorage,usedata删除Hm_cv_
//定义ma方法,如果当前href在以域名配置数组里的开头,返回/以及之后的部分
//定义la方法,取当前域名,如果域名数组里有当前域名结尾的,返回域名数组里的配置项,否则返回当前域名
//定义Y方法,判断url a的域是否在域数组里
//定义wa方法,判断字符串b是否是url a的开头
//定义Z方法,判断去除端口号之后的url b,是否是 url a的结尾部分
//定义ta方法,绑定window的focusin,focusout事件,需要浏览器支持a.j为加载后的时间
//定义$方法,检测window的focus与blur事件,计算a.d为最后操作时间,a.i为操作累计时间
WEB服务段的输出这段脚本的php为:
error_reporting(0);
date_default_timezone_set("PRC");
$environment = get_cfg_var('app_flow_develop') ? get_cfg_var('app_flow_develop') : 3;
define('BASEPATH',dirname(dirname(__FILE__)));
switch($environment){
case 1 :
require BASEPATH . DIRECTORY_SEPARATOR . 'conf' . DIRECTORY_SEPARATOR . 'config.product.php';
break;
case 2 :
require BASEPATH . DIRECTORY_SEPARATOR . 'conf' . DIRECTORY_SEPARATOR . 'config.product.php';
break;
default:
require BASEPATH . DIRECTORY_SEPARATOR . 'conf' . DIRECTORY_SEPARATOR . 'config.develop.php';
break;
}
$sid = addslashes($_GET['sid']);
$uid = isset($_GET['uid'])? addslashes($_GET['uid']) : null;
$cf= isset($_GET['cf'])? addslashes($_GET['cf']) : null;
if(array_key_exists($sid,$config)){
//检查账户,没有就写一个
if(!isset($_COOKIE['YPTJACCOUNT'])){
setcookie('YPTJACCOUNT',$sid,time () + 3600 * 24 * 365 * 5 ,"/" ,$tjdomain);
}
//检查UV标识,没有就种一个
if(!isset($_COOKIE['YPTJUUID'])){
$now = time ();
$pretime = strtotime('tomorrow') - $now;
setcookie('YPTJUUID',uniqid(true),$now + $pretime ,"/" ,$tjdomain);
}
//有会员则覆盖js配置
if($uid){
$config[$sid]['uid'] = $uid;
}
//判断网站还是m站
if($cf){
switch($cf){
case 1 : $config[$sid]['cf'] = 1;break;
default: $config[$sid]['cf'] = 0;break;
}
}
//判断js缓存
$lastmodifytime = filemtime(BASEPATH . DIRECTORY_SEPARATOR . 'js' . DIRECTORY_SEPARATOR .'yptj.js');
if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
$browserCachedCopyTimestamp = strtotime(preg_replace('/;.*$/', '', $_SERVER['HTTP_IF_MODIFIED_SINCE']));
//if($browserCachedCopyTimestamp >= $lastmodifytime){
if($browserCachedCopyTimestamp + $interval > time()){
header("http/1.1 304 Not Modified");
exit;
}
}
//header ("Last-Modified: " . gmdate ('r', $lastmodifytime));
//header ("Expires: " . gmdate ("r", ($lastmodifytime + $interval)));
header ("Last-Modified: " . gmdate ('r', time()));
header ("Expires: " . gmdate ("r", (time() + $interval)));
header ("Cache-Control: max-age={$interval}");
$js = file_get_contents(BASEPATH . DIRECTORY_SEPARATOR . 'js' . DIRECTORY_SEPARATOR .'yptj.js');
$js = str_replace($replace_a,$config[$sid],$js);
echo $js;
exit;
}else{
exit;
}
web页面插入的动态脚本为:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>超好玩</title>
</head>
<body>
hello,index
<script type="text/javascript">
//0c998ee80e953443caf0cf6b5ba7b5db
var _yphmProtocol = (("https:" == document.location.protocol) ? "https://" : "http://");
document.write(unescape('%3Cscript src="' + _yphmProtocol + 'hm.tj.com/h.js%3F0c998ee80e953443caf0cf6b5ba7b5db" type="text/javascript"%3E%3C/script%3E'));
</script>
</body>
</html>
配置文件为
//接收地址
$tjdomain = 'hm.tj.com';
//统计账号配置信息
$config = array(
'0c998ee80e953443caf0cf6b5ba7b5db'=>array(
'0c998ee80e953443caf0cf6b5ba7b5db',
"{$tjdomain}/hm.php",
"'18touch.com'",
-1,
1800000,
31536000000,
0,
0,
0
),
);
//js文件过期时间
$interval = 60 * 60 * 24 * 7; // 1 week
//置换数组
$replace_a = array(
'{$sid}',
'{$callurl}',
'{$dm}',
'{$nv}',
'{$vdur}',
'{$age}',
'{$rec}',
'{$uid}',
'{$cf}'
);
//日志数据的记录目录
$LOG_BASE = BASEPATH . DIRECTORY_SEPARATOR . "data";
//redis数据库配置
$REDIS_IP = '127.0.0.1';
$REDIS_PORT = 6379;
页:
[1]