本文分析PHP代码在服务器端执行与JavaScript在浏览器端执行的机制差异。指出将PHP生成的时间直接赋值给JS变量会导致时间静态化。通过扩展Date原型并配合setInterval定时器,实现前端实时动态显示当前时间,解决网页加载后时间不更新的问题。
PHP与JS执行机制差异分析
首先分析以下代码片段。
错误代码示例
$(function(){
setInterval(function(){
var timer = '<?php echo date("Y-m-d H:i:s",time()) ?>';
$("#test").append(timer);
},500);
});
问题根源:静态时间赋值
这段代码存在逻辑缺陷,导致网页加载后显示的时间固定不变,无法实时更新。这涉及到PHP与JavaScript两种语言在加载和执行机制上的本质区别。
上述写法是错误的。因为PHP代码在服务器端输出HTML之前就已经被解释执行,浏览器最终接收到的只是PHP执行后的静态结果。
静态时间结果演示
$(function(){
setInterval(function(){
var timer = '2015-01-02 12:02:02';
$("#test").append(timer);
},500);
});
解决方案:前端实时格式化
因此,JavaScript变量timer获取的是一个固定的字符串值,导致每次定时器触发时都追加相同的静态时间。修正方案如下所示。
修正后的实时时钟代码
// 对Date的扩展,将 Date 转化为指定格式的String
// 月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符,
// 年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字)
// 例子:
// (new Date()).Format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423
// (new Date()).Format("yyyy-M-d h:m:s.S") ==> 2006-7-2 8:9:4.18
Date.prototype.Format = function (fmt) { //author: meizz
var o = {
"M+": this.getMonth() + 1, //月份
"d+": this.getDate(), //日
"h+": this.getHours(), //小时
"m+": this.getMinutes(), //分
"s+": this.getSeconds(), //秒
"q+": Math.floor((this.getMonth() + 3) / 3), //季度
"S": this.getMilliseconds() //毫秒
};
if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
for (var k in o)
if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
return fmt;
}
$(function(){
setInterval(function(){
var timer = new Date().Format("yyyy-MM-dd HH:mm:ss");
$("#test").append(timer);
},500);
});