自荐文章
现在提供天气预报服务的网站挺多的,一般常见的都是直接在自己网站上使用,有部分的网站提供了web service接口。
- 常见正则方式:常见引用天气预报的方法多是使用正则去解析指定网站的天气预报,使用这种方法有些弊端:1.人 家网站的HTML格式发生了变化,你的程序则需要跟着修改。2.本身解析的正则写起来就不太简单。3.每次解析都要去访问别人的网站,当别人网站发生异常 的时候可能会拖累你的程序。当然你可以从你的应用流程上解决掉一些问题。
- Web service接口:这个当然是首选了,一般提供web service接口的网站都会是自己的服务相对稳定一些。
如果你的网站只需要一个显示一个地区的天气预报的话,那么就直接用吧,如果需要显示多地区的话,那么你可能就需要建立一个自己的IP库了。那天看到 QQ提供了一些这样的服务,于是就简单研究了一下,找出几个有用的接口。其中最令我比较满意的就是这些接口是javascript实现的,可以很容易的做 到各种网站系统的兼容性,不过人家的编码格式是GB2312的~
我使用了Jquery来调用,所有的调用都是基于 http://minisite.qq.com/js/j.minisite.weather.js 研究的结果。
获取当前浏览器的所在地区和IP:
if(typeof IPData != "undefined") {
//YoyoSite.Cookie.set("current_ip", IPData[2]+','+IPData[3]);
alert(IPData);
}
});
获得当前的天气我简单的封装了一下,这里只说明使用方法(不过……,这个天气预报不太准):
<script language="javascript" src="http://www.greatmoo.com/untest/samples/weather/weather.js"></script>
<div id="weather_content"></div>
<script language="javascript">
weather.init("weather_content");
</script>
调用方法很简单,请主义示例中的 weather_content 这个关键字。
应用实例:http://www.greatmoo.com/untest/samples/weather/weather.php,别忘了对你的页面设置GB2312编码。
php能做的事情也不简单,而且由于php是解释执行的语言,所以用它来做简单的可执行文件还是很不错的。linux平台中做起来比较简单了,例如:
<?php
phpinfo();
?>
别忘记chmod 0777
但是在windows系统环境中只能使用批处理文件了,但是用php命令是无法执行批处理文件中多行的 php脚本的,需要用点技巧,look at here~
@goto :EOF
<?php
var_dump($argc);
var_dump($argv);
?>
请注意,我这里是假设已经把 php.exe 的目录加入到了环境变量的 PATH 中,把这几行代码保存为 phpshell.bat ,然后复制到C:\windows 下,然后就可以使用了,其中 <?php 到 ?> 里面可以写上你要做的事情,并且支持4个参数。
执行:C:\>phpshell test test2
结果
array(3) {
[0]=>
string(10) "aaaphp.bat"
[1]=>
string(4) "test"
[2]=>
string(5) "test2"
}
你应该注意到了,其实实现方法很简单,php命令可以执行文件的,这里只是把bat文件的文件名做为php命令的参数。
数据列表导出的功能很常见,有些是简单的复制粘贴,或者复杂的饼状条形图形,一般都是基于服务器端的操作。我这里是一个简单的html table数据导出功能,目前只些了个简单的模型,主要使用javascript和简单的php来实现。
注:在ie浏览器中其实是可以使用 document.execCommand() 来实现php的操作,为了兼容各种浏览器所以我直接是使用php来实现文件下载。
要实现的功能:如图将其导出到本地文件。
javascript代码
function saveTableElementToFile(id, fileType, fileName) {
if(typeof fileName == undefined || fileName == "") fileName = "nonamed";
if(typeof fileType == undefined || fileType == "") fileType = "csv";
var result = "";
if(fileType == "html") {
var html = document.getElementById(id).innerHTML;
html = html.replace(/table/gi, "table border='1' ");
result = html;
//document.write(html);
} else if(fileType == "csv") {
//使用jquery
var vhtml = "";
$("#"+id).find("table").each(function() {
$(this).find("tr").each(function() {
$(this).find("th").each(function() {
vhtml+= $.trim($(this).html())+",";
});
$(this).find("td").each(function() {
vhtml+= $.trim($(this).html())+",";
});
vhtml+= "\n";
});
});
vhtml = vhtml.replace(/,\n/g, "\n");
result = vhtml;
//document.write(vhtml);
}
var formHtml = "";
formHtml+= "<form name='saving_form' target='_blank' action='file_download.php' method='post'>";
formHtml+= "<input type='hidden' name='content' value='' />";
formHtml+= "<input type='hidden' name='file_type' value='' />";
formHtml+= "<input type='hidden' name='file_name' value='' />";
formHtml+= "</form>";
$("form[name=saving_form]").remove();
$("body").append(formHtml);
document.forms['saving_form'].elements['content'].value = result;
document.forms['saving_form'].elements['file_type'].value = fileType;
document.forms['saving_form'].elements['file_name'].value = fileName;
document.forms['saving_form'].submit();
//history.go(-1);
}
PHP代码
header("Content-Disposition: attachment; filename=".$_POST['file_name'].".".$_POST['file_type']);
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
echo iconv("utf-8", "gb2312", $_POST['content']);
详细例子可以查看 http://www.greatmoo.com/untest/samples/table2file.html
在做一个程序中我需要用到javascript来缓存一些数据,建立 ID 与数据的 hash 结构用来排序,然后我就封装了几个对一维数组的算法。
* 判断一个值是否存在于当前的数组之中
* 例如: var arr1 = [1,2,5,9];
* alert(arr1.inArray(2)); //true
* alert(arr1.inArray(3)); //false
*/
Array.prototype.inArray = function (value) {
for(var i = 0; i < this.length; i++) {
if(this[i] == value) return true;
}
return false;
}
/**
* 删除数组中的这个值
* 例如: var arr2 = [2,3,5,7,8];
* arr2.removeValue(5); // [2,3,7,8]
*/
Array.prototype.removeValue = function (value) {
var focus = new Array();
for(var i = 0; i < this.length; i++) {
if(this[i] == value) {
focus.push(i);
}
}
if(focus.length > 0) {
for(var k = focus.length-1; k >= 0; k--) this.splice(focus[k], 1);
}
return this;
}
/**
* 将数组中值为 当前指定值的向前一定一位
* 例如: var arr3 = [1,2,3,5];
* arr3.sortUpByValue(3); //结果: [1,3,2,5]
*/
Array.prototype.sortUpByValue = function (value) {
var key = null;
for(var i = 1; i < this.length; i++) {
if(this[i] == value) {
key = i;
}
}
if(key != null) {
var tmp = this[key];
this[key] = this[key-1];
this[key-1] = tmp;
}
return this;
}
/**
* 同 sortUpByValue ,将指定值向后移动一位
*/
Array.prototype.sortDownByValue = function (value) {
var key = null;
for(var i = 0; i < this.length-1; i++) {
if(this[i] == value) {
key = i;
}
}
if(key != null) {
var tmp = this[key];
this[key] = this[key+1];
this[key+1] = tmp;
}
return this;
}
实例:http://www.greatmoo.com/untest/samples/test_js_array.html
今天一朋友写了个小JS程序让我看一下(<java sricpt>on submit<fuck></sricpt>),其实他是想告诉我他会JS了。
我一看,那哪是JS程序啊,而且是带有脏字的,于是装作很神秘的样子给了他一段高深而简洁的程序,说这个程序拿出去别人一看就知道你是高手。
while(1) alert(1);
//如果你不懂JS的话去试一下啊,很好玩的
</script>
于是他很兴奋的拿到了代码,而且在公司肆意传播,最后发现是个死循环把我骂一顿,说公司有些高手没上当,要我写个高级一点的让别人看不出来的东西,于是就正经一点写了个好玩的东东。
function moveWin () {
window.resizeTo(Math.random()*500+1, Math.random()*500+1);
window.moveTo(Math.random()*1024+1, Math.random()*768+1);
}
setInterval("moveWin()", 100);
//有兴趣试一下,肯定无害
</script>
如果这种错误是javascript产生的话,一般都是javascript的不规范导致的。项目中使用ajax加载数据的操作,ajax操作有同步和异步方式,常规的都是异步,而我这里要用到同步请求,然后就出现了这种情况(firefox是没有这种情况的。)。
详细错误信息:
Internet Explorer 无法打开 Internet 站点
http://localhost/……
已终止操作
具体原因我也说不清楚,不过按照下面的方式就没问题了。也就是需要当页面加载结束之后再去做ajax数据请求。
//your ajax
}
我使用的是 jquery js插件,做法:
//ajax
});
需求是把数组按照树形结构排列,假设数据是在数据库中的。
最简单的思路或者说常规的思路就是递归算法了。递归算法是比较快的和准确的,但是有一个问题就是会比较浪费不必要的资源,递归算法执行的过程中会开启N个 函数入口,也就是函数需要一直保存状态等待起递归的运算结果。例如这个树形有 5层*60行,则在递归算法中浪费的运算至少60次,并且保持5个函数一直是运算中状态,不合理的是同样要做60+次的数据库查询,因为不管其有没有子类,算法执行过程中都需要去重复执行递归运算,事实上实际执行过程中不止这个数。
可以写个简单的例子来测试递归算法调用函数的次数。
array(
array(id=>1,pid=>0),
array(id=>2,pid=>0),
array(id=>3,pid=>2),
array(id=>4,pid=>0),
array(id=>5,pid=>3),
array(id=>6,pid=>1),
array(id=>7,pid=>1),
array(id=>8,pid=>6),
array(id=>9,pid=>7),
array(id=>10,pid=>9)
); */
$db = new MysqlDb();
$num = 0;
function treeArray($pid) {
global $db, $num;
$num++;
$data = $db -> getAll("SELECT * FROM test_a WHERE pid = ".$pid); //返回一个二维数组
$result = array();
foreach($data as $val) {
$val['child'] = treeArray($val['id']);
$result[] = $val;
}
return $result;
}
print_r(treeArray(0)); //树形的结果
var_dump($num); //11
然后我们系统越作越大了,数据库资源紧张了,我们要求在不改变数据库结构的同时尽可能的减少数据库的操作。那么这样做就需要我们有一算法来给你的数据排序了。
function treeArray() {
global $num, $db;
$data = $db -> getALl("SELECT * FROM test_a WHERE 1");
$result = array();
foreach($data as $val) {
$num++;
if($val['pid'] == 0) {
$val['child'] = getChild($val['id'], $data);
$result[] = $val;
}
}
return $result;
}
function getChild($pid, $data) {
global $num;
$result = array();
foreach($data as $val) {
$num++;
if($val['pid'] == $pid) {
$val['child'] = getChild($val['id'], $data);
$result[] = $val;
}
}
return $result;
}
print_r(treeArray());
var_dump($num); //110
好了,我们最起码实现了不用多次请求数据库了,不过在作数组遍历的时候我们做了很多次运算~然后我们的系统功能模块越来越多,其中树形结构数据这一块的调用也特别多,程序执行速度越来越不进人意了。我们则需要设计一个速度更快,消耗资源更少的算法。这里我用了php里的变量引用,其它语言里肯定也有这种引用方式,有些类似于C语言的指针。
global $db;
$data = $db -> getAll("SELECT * FROM test_a WHERE 1");
$result = array();
//定义索引数组,用于记录节点在目标数组的位置
$I = array();
foreach($data as $val) {
if($val['pid'] == 0) {
$i = count($result);
$result[$i] = $val;
$I[$val['id']] = & $result[$i];
} else {
$i = count($I[$val['pid']]['child']);
$I[$val['pid']]['child'][$i] = $val;
$I[$val['id']] = & $I[$val['pid']]['child'][$i];
}
}
return $result;
}
print_r(treeArray());
申明:算法不是我原创的,希望抛砖引玉出更好的算法。查看源代码:http://www.greatmoo.com/untest/samples/sort/
感觉程序设计语言本身其实要学的东西很少,真正要学的是算法和数据结构,准备采购《算法导论》。
php的count
php里的count函数一般是用来判断数组大小(行数),不过由于php变量的特殊性,这个函数也比较有意思,请看实例:
var_dump(count(0)); //int(1)
var_dump(count(1)); //int(1)
var_dump(count(false)); //int(1)
var_dump(count("")); //int(1)
var_dump(count("123456")); //int(1)
var_dump(count(null)); //int(0)
var_dump(count(array())); //int(0)
var_dump(count(array(1,2,3,4))); //int(4)
?>
得出的结论是count判断纯数组的时候肯定是正确的,当判断其它类型变量的时候除了"NULL"以外全部是“1”。
javascript的length
length则更智能一点。
javascript:alert('abcd'.length); //4
javascript:alert("".length); //0
javascript:alert(false.length); //undefined
javascript的变量类型也是比较奇怪的,所以它也有一个和php里一样的"===“运算符。
alert(0 == ""); //true
alert(0 == null); //false
alert("" == false); //true
因为有apt-get的存在,配置起来其实就相当于windows系统中安装一个QQ游戏一样。
安装
sudo apt-get install awstats系统会自动安装到/etc/awstats 目录下,事实上apt-get安装的程序一般都是在这个目录下面。
设置awstats解析apache日志
新建将要分析的站点(我这里要分析的站点是www.greatmoo.com,所以相应的名称都是这个)
编辑你的配置
这个文件里的每个参数都有详细的说明,可以根据你的需要自定义,不过有几个地方是默认是没有值或者不适合你用的,必须要修改的。值得一试的是里面有个geo的相关设置,不过好像没有好的免费geo数据库。
为了让awstats统计页面配合图片显示直观一点我们需要复制相关的文件到网站目录下或者建立一个链接,当然你也可以使用apache虚拟主机中的Alias别名设置,请查看apache的文档,这里不做介绍。
设置awstats将要用到的目录的权限(我这里的www-data用户是apache进程的用户)
建立计划任务,设置自动分析日志
查看结果
我的配置结果:http://www.greatmoo.com/cgi-bin/awstats.pl
七年前我开始学习的php网页制作,到现在还基本是在做php程序设计。不是说php程序员有什么不好,只是我突然发现自己很难去接受新的语言环境了。
开始学程序设计的时候学的是foxbase,当时都不知道什么是程序设计,和其相关的算法数据结构都没有任何概念。到卓达之后很快就开始C,接着就是PHP了,再接着学习了java。由于出学校比较早,java火候不够,就一直做php开发了,没想到的是一做就这么久了~
记得工作的头几年对学习新的语言有着非常高的热情,却一直没有认真的学过。一直到现在才发现自己越来越有点离不开目前的工作环境了。不仅仅是学习上的难度,更要命php这门技术几乎成为了我唯一糊口的手段了。简单来说这个转变过程是有一定成本的,如 学习的周期会有多长、在php领域自己算个熟手说话有一定的分量,而转型后的一段时间则是未知的、还有最直接的就是工资肯定会比现在少很多。
这种状况是很不好的一个状况,有两条路我可以选择的:1、继续我现在的路,缓慢的增长技术,直到一个接近极限的位置停滞。2、承担转变的风险,然后有一个告诉的发展。当然如果只是让我们选,一般都会选择第二条路,但是如果让你去做呢,你能做得到吗,能很坚决很快有效的去做?
事实上大部分的是结果都是在走第一条路,而且随着自己年龄的增长和家庭的组建,就越难以转变或者说转变的风险就越大。这个过程就是体制化了(institutionalized)。
《肖申克的救赎》是我最喜欢的两部片子之一,其中的一位男主人公谈过着个问题,事实上片子从头至尾也在讲这个过程的两种情况,一个是被体制化,一个是冲破体制化。片子里瑞德说“first you hate them ,then you get used to,enough time passes...you get so you depend on them 。That is instititutionalized(起初,你讨厌它,然后你逐渐的习惯它,足够的时间后你开始依赖他。这就是体制化)”。这是一部能让人心灵震撼的片子,里面有很多名词都能让人获得新生。
以下是摘抄部分:
体制化表现的是人性中脆弱的一部分。人都需要一种用以依托生命的信仰或者说生存方式,广义来讲,任何传统和信仰体系都带有体制化的印记——一种让你以其为思维、行动的参考标准。或者说,体制会在社会中是标尺的功能,提供的是一种价值参照体系,使得人在这一标准下,更有效的行动。
很明显,体制化在大多数情况下,都是一个有着负面形象的动词。Red口中的“体制化”针对的正是体制会所造成的可怕的(社会)现实。体制化在制造效率的同时,也抹杀了人的思想的自由和灵活性。当年复一年生活于充满规范的环境,每个人都会丧失一些本真的体验,合理或者不合理到最后都变成了一样的东西。
体制化一方面在巩固自己的价值体系,一方面使得人们越来越依赖于这套体系,从而使得体制化更象一个有着思维的硬壳。所有的行为和思想都要被禁锢在这个壳内,一旦越界,不仅要受到硬壳的碰伤,同时也会受到其他体制化的同类的攻击。(喝了泉水的疯子会认为正常人是疯子)所以体制会是一个非常坚固的结构。
在《肖申克的救赎》中,安迪能冲破这体制化的束缚而能获得自由,完全凭赖其心存希望和自由的精神。但在社会中,反抗一个已经根深蒂固的体系却是十分艰难的。固有的思维和陈腐的理念主宰着这个世界,没有人会问为什么,他只会按照已有的方式继续。任何对抗体制会的行为都将是一场惨烈的战斗,无论是苏格拉底,还是马丁·路德·金。
有一种说法叫从无序到有序,认为宇宙的规律都是一种从混沌状态趋向秩序的过程。我却不是很认同这个观点。在热力学中有一个量度系统内分子运动无序性的“熵”的概念——在孤立系统中所进行的自然过程总是沿着熵增大的方向进行。这个世界本来就应该是多样性的社会,并且应该充满更多的可能性,但人类的发展史却与之相反,努力要创造一个制度化的社会,或者可以说,人类的历史就是体制化的历史。中世纪的十字军东征、美苏为代表的两大意识形态阵营的的“冷战 ”无不如是。
就目前而言,全球化在弱势文化区域正慢慢流于美国化,这同样是试图用一种文化作为标准的体制化进程。相对而言,我更喜欢斯蒂文·凯尔曼(Steven Kelman,哈佛大学公共管理学教授)为之做的描述:全球化是指在民间加深了解,不同文化间互相欣赏、互相学习对方的文化价值观念。
