查看php代码的性能——xhprof

今天是头脑风暴,想测试一下现在做得项目的执行效率。google了一下,发现了xhprof,试了一试,感觉真是个神器啊。在这里记录一下。

介绍

就是facebook放出的一个开源的,用来测试php代码性能的工具。在网上也搜到了Xdebug,但是都说特别耗资源。而xhprof是个轻量级的,而且用户体验也相当不错。那图看着,就是舒坦。

xhprof的安装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#下载xhprof
wget http://pecl.php.net/get/xhprof-0.9.2.tgz
#解压
tar zxf xhprof-0.9.2.tgz
cd xhprof-0.9.2

#把这两个目录复制到website目录,把后面的/var/www/xhprof更换成自己的目录
#ubuntu的web目录就是/var/www
cp -r xhprof_html xhprof_lib /var/www/xhprof/

cd extension
#如果这个命令不存在,按照提示安装php-dev
phpize

#这里是要配置一下,后面的<path to php-config>也要根据自己的系统情况来设定,
#可以用whereis php-config 命令来查找下那个目录,我的是/usr/bin/php-config
./configure --with-php-config=<path to php-config>
#下面是安装,如果出错了就用root权限执行
make
make install

配置xhprof

修改php.ini

1
2
3
4
5
6
7
8
9
10
[xhprof]
extension=xhprof.so
;
; directory used by default implementation of the iXHProfRuns
; interface (namely, the XHProfRuns_Default class) for storing
; XHProf runs.
;
xhprof.output_dir=<directory_for_storing_xhprof_runs>
;注:这里的<directory_for_storing_xhprof_runs>也要换成自己的目录,就是分析日志目录,自己建一个
;该目录是用来保存测试数据的,xhprof是先把测试数据保存到一个文件,然后在用一个程序打开并把数据显示出来

安装graphviz

实际上不安装这个也行,完成上面的步骤,重启下服务器就行了,但是为了看着舒坦嘛,xhprof会用graphviz生成出来一个图,让测试数据看起来更舒服。

1
2
3
4
5
6
7
#下载
wget http://www.graphviz.org/pub/graphviz/stable/SOURCES/graphviz-2.24.0.tar.gz
tar zxf graphviz-2.24.0.tar.gz
cd graphviz-2.24.0
./configure
make
make install

使用xhprof

注意:使用前你得重启apache服务,你可以用phpinfo()来查看一下xhprof安装成功没有。

示例代码:

注:代码中的路径需要根据自己情况修改一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?php
//开始xhprof的性能测试
xhprof_enable();

/**********************被测试的代码*****************************/
function haha()
{
    $sum = 0;
    for($i = 0;$i < 1000;$i++)
    {
        $sum += 1;
    }
    return $sum;
}

function hehe()
{
    $a = 0;
    for($j = 0;$j < 20;$j++)
    {
        $a += haha();
    }
    return $a;
}

echo hehe();

/************************测试代码完毕*******************************/
//测试结束了,把测试数据放到$data变量中
$data = xhprof_disable();

//把xhprof工具include进来
$xhprof_utils = realpath('/var/www/xhprof/xhprof_lib/utils');
include_once $xhprof_utils . "/xhprof_runs.php";
include_once $xhprof_utils . "/xhprof_lib.php";
//新建一个xhprofruns对象,
$xhprof_run = new XHProfRuns_Default();

//保存本次的测试数据,第一个参数是数据,第二个参数是保存文件的后缀名,
//这里返回值是本次测试的id,其实也就是本次测试数据保存的文件名字
$run_id = $xhprof_run->save_run($data,'hx');

//生成一个查看链接,
echo '<a target = "_blank" href = "http://localhost/xhprof/xhprof_html/index.php?run='.$run_id.'&source=hx">profile result</a>';

稍微解释一下把:
xhprof用xhprof_lib下的程序将测试数据把存到文件里,看那个include的路径,是安装的时候让你cp过去的。他会把文件保存到你php.ini里设置的路径下,上面也是你配置的。
之后生成的链接指向的也是xhprof自己的程序,也是安装时cp过去的,加了两个get参数,run为本次测试的id(也是文件名),source是保存文件的后缀。

运行结果展示

点击那个链接后效果如下图
xhprof-result
点击那个[View Full Callgraph],会是下面这个页面,这就是用graphviz生成出来的图。
xhprof-graph

其他

这里只是简单介绍了一下xhprof的使用,因为我只研究到这,默认的这样已经可以满足我的需求了,它使用时还有挺多设置的。更详细的可参考下的两个网址

英文文档:http://mirror.facebook.net/facebook/xhprof/doc.html
中文文档:http://www.162cm.com/p/xhprofdoc.html

PHP的session学习

session存在的意义,估计每个用做web开发的人都是了解的,就为了解决HTTP是个无状态协议所带来的问题,不多说了。这里主要想说的是服务端与客户端是如何利用session进行交互的。

session工作的大体流程

先看下面这幅流程图:

session-diagram

 

当用户第一次访问站点时,PHP会用session_start()函数为用户创建一个session ID,这就是针对这个用户的唯一标识,每一个访问的用户都会得到一个自己独有的session ID,这个session ID会存放在响应头里的cookie中,之后发送给客户端。这样客户端就会拥有一个该站点给他的session ID。

当用户第二次访问该站点时,浏览器会带着本地存放的cookie(里面存有上次得到的session ID)随着请求一起发送到服务器,服务端接到请求后会检测是否有session ID,如果有就会找到响应的session文件,把其中的信息读取出来;如果没有就跟第一次一样再创建个新的。

通常站点的退出功能,实际上就是调用一下session_destroy()函数(也有可能更复杂些),把该用户的session文件删除,再把用户的cookie清除。这样客户端和服务端就算没有联系了。

图中的红框部分就是一次完整的HTTP请求,因为HTTP是无状态的,所以一次请求完成后客户端和服务端就不再有任何关系了,谁也不认识谁。但由于一些需要(如保持登录状态等),必须让服务端和客户端保持联系,session ID就成了这种联系的媒介了。

客户端的工作

通过上面的分析我们可以知道session实际上是依赖与cookie的,当用户访问某一站点时,浏览器会根据用户访问的站点自动搜索可用的cookie,如果有可用的就随着请求一起发送到了服务端。每次接收到服务端的响应时又会更新本地的cookie信息。

当然也可以用GET方式来传递session ID,但不推荐用GET,这样不安全。

服务端的工作

由上面的流程图可以看到,服务端实际上是把产生的一些数据存放在了session文件中,该文件的名字就是”sess_”加上session ID,这些文件的存放位置就是phpinfo()查到的session.save_path值。

session-file

 

由上图我们可以很清楚的看到,服务端和客户端保存着同样的session ID信息,这就是两者保持联系的钥匙。

session的反面影响

有好处必然也有坏处,session带来的最主要问题就是对性能的影响,可以想象一下,对于一个千万用户级的web站点,如果每个用户都保存session文件,那每次用户访问光寻找相应的session文件就要耗掉不少系统资源的。所以这时就要对session的存储做一些自定义的设定了,如分目录或哈希等等。除了保存到session文件,也可以抛弃PHP自带的session功能,自己实现session,将session信息存放到数据库当中,这样做最好对数据库进行一下缓存的设置了,不然对上千万的数据进行太频繁的检索,也是蛮耗资源的。

session的清除

客户端和服务端的这种联系必然是需要有时间的规定的,所以需要定期清除session。这个问题就需要在两方面考虑了,一个是清除服务端session文件,一个是清除客户端的cookie信息,因为两者都各保存着一半的信息。

PHP GC进程可以扫描session存放目录清除session文件,但这个进程是特别耗资源的,所以PHP默认是1%的几率在一个sessioin启动时去清理一次过期的sesssion,所以并不是说一个用户session过期了,他对应的session文件就马上被清除,99%的几率是没被清除的。这就需要我们程序员自己动手了。可以在session信息中存放一个过期时间,值为用户最后一次访问的时间。当用户一访问,就用当前时间减去上次访问时间看是否超时,如果超时了就删除相应session文件,并设置cookie的Expires属性为负值,使其客户端的cookie信息也过期,这样浏览器就自动把它删掉了。

PHP的相关session常用函数

  • session_start():启动session,这个没什么说的了。根据session ID打开session文件,如果没有session ID就创建一个ID和对应的session文件
  • $_SESSION[]数组:存放用户信息的全局数组,session文件中除了存放$_SESSION中的数据实际也会存放其他的信息,如id等
  • session_unset():清空$_SESSION数组,它是把数组里的值清空了,而$_SESSION这个变量还是存在的,和unset($_SESSION)是完全不同的概念
  • session_commit():提交session数据并结束session,把$_SESSION数据写到文件里并结束session,实际上当一个页面执行结束后,php会自动执行与这个函数相同的操作。所以这个函数也很少能用上
  • session_destroy():注销session,这个就是关闭session并删除掉相应的session文件了。切断了客户端和服务端的联系。

参考资料

 

国外程序员推荐:每个程序员都应读的书[转]

“如果能时光倒流,回到过去,作为一个开发人员,你可以告诉自己在职业生涯初期应该读一本,你会选择哪本书呢?我希望这个书单列表内容丰富,可以涵盖很多东西。”

很多程序员响应,他们在推荐时也写下自己的评语。以前就有国内网友介绍这个程序员书单,不过都是推荐数 Top 10的书。其实除了前10本之外,推荐数前30左右的书籍都算经典,伯乐在线整理编译这个问答贴,同时摘译部分推荐人的评语。下面就按照各本书的推荐数排列。

 

1. 《代码大全 史蒂夫·迈克康奈尔

推荐数:1684

code complete 代码大全

“优秀的编程实践的百科全书,《代码大全》注重个人技术,其中所有东西加起来,就是我们本能所说的“编写整洁的代码”。这本书有50页在谈论代码布局。” —— Joel Spolsky

对于新手来说,这本书中的观念有点高阶了。到你准备阅读此书时,你应该已经知道并实践过书中99%的观念。– esac

 

2. 《程序员修炼之道

推荐数:1504

Pragmatic Programmer 程序员修炼之道

对于那些已经学习过编程机制的程序员来说,这是一本卓越的书。或许他们还是在校生,但对要自己做什么,还感觉不是很安全。就像草图和架构之间的差别。虽然你在学校课堂上学到的是画图,你也可以画的很漂亮,但如果你觉得你不太知道从哪儿下手,如果某人要你独自画一个P2P的音乐交换网络图,那这本书就适合你了。—— Joel

3. 《计算机程序的构造和解释

推荐数:916

Structure and Interpretation of Computer Programs 计算机程序的构造和解释

就个人而言,这本书目前为止对我影响醉倒的一本编程书。

代码大全》、《重构》和《设计模式》这些经典书会教给你高效的工作习惯和交易细节。其他像《人件集》、《计算机编程心理学》和《人月神话》这些书会深入软件开发的心理层面。其他书籍则处理算法。这些书都有自己所属的位置。

然而《计算机程序的构造和解释》与这些不同。这是一本会启发你的书,它会燃起你编写出色程序的热情;它还将教会你认识并欣赏美;它会让你有种敬畏,让你难以抑制地渴望学习更多的东西。其他书或许会让你成为一位更出色的程序员,但此书将一定会让你成为一名程序员。

同时,你将会学到其他东西,函数式编程(第三章)、惰性计算、元编程、虚拟机、解释器和编译器。

一些人认为此书不适合新手。个人认为,虽然我并不完全认同要有一些编程经验才能读此书,但我还是一定推荐给初学者。毕竟这本书是写给著名的6.001,是麻省理工学院的入门编程课程。此书或许需要多做努力(尤其你在做练习的时候,你也应当如此),但这个价是对得起这本书的。

你还不确信么?那就读读第一版的前言或序言。网上有免费的电子版。 - Antti Sykäri

 

4. 《C程序设计语言

推荐数:774

The C Programming Language C程序设计语言

这本书简洁易读,会教给你三件事:C 编程语言;如何像程序员一样思考;底层计算模型。(这对理解“底层”非常重要)—— Nathan

 

5. 《算法导论

推荐数:671

Introduction to algorithms 算法导论

代码大全》教你如何正确编程;《人月神话》教你如何正确管理;《设计模式》教你如何正确设计……

在我看来,代码只是一个工具,并非精髓。开发软件的主要部分是创建新算法或重新实现现有算法。其他部分则像重新组装乐高砖块或创建“管理”层。我依然梦想这样的工作,我的大部分时间(>50%)是在写算法,其他“管理”细节则留给其他人…… —— Ran Biron

 

6. 《重构:改善既有代码的设计

推荐数:617

Refactor 重构:改善既有代码的设计

我想我不得不推荐《重构》:改进现有代码的设计。—— Martin

我必须承认,我最喜欢的编程语录是出自这本书:任何一个傻瓜都能写出计算机能理解的程序,而优秀的程序员却能写出别人能读得懂的程序。—— Martin Fowler

 

7. 《设计模式

推荐数:617

Design Patterns 设计模式

就我而言,我认为四人帮编著的《设计模式》是一本极为有用的书。虽然此书并不像其他建议一样有关“元”编程,但它强调封装诸如模式一类的优秀编程技术,因而鼓励其他人提出新模式和反模式(antipatterns),并运用于编程对话中。—— Chris Jester-Young

 

8. 《人月神话

推荐数:588

The Mythical Man-Month 人月神话

 

9. 《计算机程序设计艺术

推荐数:542

The Art of Computer Programming 计算机程序设计艺术

这是高德纳倾注心血写的一本书。—— Peter Coulton

 

10. 《编译原理(龙书)

推荐数:462

Compilers: Principles, Techniques, and Tools 编译原理:原理、技术与工具

我很奇怪,居然没人提到龙书。(或许已有推荐,我没有看到)。我从没忘过此书的第一版封面。此书让我知道了编译器是多么地神奇绝妙。- DB

 

11. 《深入浅出设计模式

推荐数:445

我知道四人帮的《设计模式》是一本标准书,但倒不如先看看这部大部头,此书更为简易。一旦你了解了解了基本原则,可以去看四人帮的那本圣经了。- Calanus

 

12. 《哥德尔、艾舍尔、巴赫书:集异璧之大成》

推荐数:437

如果下昂真正深入阅读,我推荐道格拉斯·侯世达(Douglas Hofstadter)的《哥德尔、艾舍尔、巴赫书》。他极为深入研究了程序员每日都要面对的问题:递归、验证、证明和布尔代数。这是一本很出色的读物,难度不大,偶尔有挑战,一旦你要鏖战到底,将是非常值得的。 – Jonik

 

13. 《代码整洁之道

推荐数:329

虽然《代码整洁之道》和《代码大全》有很多共同之处,但它有更为简洁更为实际的清晰例子。 – Craig P. Motlin

 

14. 《Effective C++》和《More Effective C++

推荐数:297

在我职业生涯早期,Scott Meyer的《Effective C++》和后续的《More Effective C++》都对我的编程能力有着直接影响。正如当时的一位朋友所说,这些书缩短你培养编程技能的过程,而其他人可能要花费数年。

去年对我影响最大的一本书是《大教堂与市集》,该书教会我很有关开源开发过程如何运作,和如何处理我代码中的Bug。 – John Channing

 

15. 《编程珠玑

推荐数:282

尽管我不得不羞愧地承认,书中一半的东西我都没有理解,但我真的推荐《编程珠玑》,书中有些令人惊奇的东西。 – Matt Warren

 

16. 《修改代码的艺术by Michael Feathers

我认为没有任何一本书能向这本书一样影响了我的编程观点。它明确地告诉你如何处理其他人的代码,含蓄地教会你避免哪些(以及为什么要避免)。- Wolfbyte

同意。很多开发人员讨论用干净的石板来编写软件。但我想几乎所有开发人员的某些时候是在吃其他开发人员的狗食。– Bernard Dy

 

17. 《编码:隐匿在计算机软硬件背后的语言

我推荐Charles Petzold的《编码》。在这个充满工具和IDE的年代,很多复杂度已经从程序员那“抽取”走了,这本书一本开眼之作。 – hemil

 

18. 《禅与摩托车维修艺术 / Zen and the Art of Motorcycle Maintenance》

对我影响最大的那本书是 Robert Pirsig 的《禅与摩托车维修艺术》。不管你做什么事,总是要力求完美,彻底了解你手中的工具和任务,更为重要的是,要有乐趣(因为如果你做事有乐趣,一切将自发引向更好的结果)。 – akr

(编注:关于这本书,也可以看看阮一峰的读后感。)

 

19. 《Peopleware / 人件集:人性化的软件开发

Demarco 和 Lister 表明,软件开发中的首要问题是人,并非技术。他们的答案并不简单,只是令人难以置信的成功。第二版新增加了八章内容。 – Eduardo Molteni

 

20. 《Coders at Work / 编程人生

一本非常有影响力的书,可以从中学到一些业界顶级人士的经验,了解他们如何思考并工作。 – Jahanzeb Farooq

 

21. 《Surely You’re Joking, Mr. Feynman! / 别闹了,费曼先生!

虽然这本书可能有点偏题,但不管你信不信,这本书曾在计算机科学专业课程的阅读列表之上。一个优秀的角色模型,一本有关好奇心的优秀书籍。 – mike511

 

22. 《Effective Java 中文版》

此书第二版教你如何编写漂亮并高效的代码,虽然这是一本Java书,但其中有很多跨语言的理念。 – Marcio Aguiar

 

23. 《Patterns of Enterprise Application Architecture / 企业应用架构模式

很奇怪,还没人推荐 Martin Fowler 的《企业应用架构模式》- levi rosol

 

24. 《The Little Schemer》和《The Seasoned Schemer nmiranda

这两本是LISP的英文书,尚无中文版。美国东北大学网站上也有电子版。

 

25. 《交互设计之路英文名:《The Inmates Are Running The Asylum: Why High Tech Products Drive Us Crazy and How to Restore the Sanity》该书作者:Alan Cooper,人称Visual Basic之父,交互设计之父。

本书是基于众多商务案例,讲述如何创建更好的、高客户忠诚度的软件产品和基于软件的高科技产品的书。本书列举了很多真实可信的实际例子,说明目前在软件产品和基于软件的高科技产品中,普遍存在着“难用”的问题。作者认为,“难用”问题是由这些产品中存在着的高度“认知摩擦”引起的,而产生这个问题的根源在于现今软件开发过程中欠缺了一个为用户利益着想的前期“交互设计”阶段。“难用”的产品不仅损害了用户的利益,最终也将导致企业的失败。本书通过一些生动的实例,让人信服地讲述了由作者倡导的“目标导向”交互设计方法在解决“难用”问题方面的有效性,证实了只有改变现有观念,才能有效地在开发过程中引入交互设计,将产品的设计引向成功。

本书虽然是一本面向商务人员而编写的书,但也适合于所有参与软件产品和基于软件的高科技产品开发的专业人士,以及关心软件行业和高科技行业现状与发展的人士阅读。

他还有另一本中文版著作:《About Face 3 交互设计精髓

 

26. 《Why’s (Poignant) Guide to Ruby 》

如果你不是程序员,阅读此书可能会很有趣,但如果你已经是个程序员,可能会有点乏味。

 

27. Unix编程艺术

It is useful regardless operating system you use. – J.F. Sebastian
不管你使用什么操作系统,这本书都很有用。 – J.F. Sebastian

 

28. 《Practices of an Agile Developer / 高效程序员的45个习惯:敏捷开发修炼之道

45个习惯,分为7个方面:工作态度、学习、软件交付、反馈、编码、调试和协作。

每一个具体的习惯里,一开始提出一个谬论,然后展开分析,之后有正队性地提出正确的做法,并设身处地地讲出了正确做法给你个人的“切身感受”,最后列出几条注意事项,帮助你修正自己的做法(“平衡的艺术”)。

 

29. 《Test-Driven Development by Example. / 测试驱动开发

前面已经提到的很多书都启发了我,并影响了我,但这本书每位程序员都应该读。它向我展示了单元测试和TDD的重要性,并让我很快上手。 – Curro

我不关心你的代码有多好或优雅。如果你没有测试,你或许就如同没有编写代码。这本书得到的推荐数应该更高些。人们讨论编写用户喜欢的软件,或既设计出色并健壮的高效代码,但如果你的软件有一堆bug,谈论那些东西毫无意义。– Adam Gent

 

30. 《Don’t Make Me Think / 点石成金:访客至上的网页设计秘笈

取决于你所追求的目标。我喜欢《代码大全》是因纯编程,《点石成金》是一本有关UI设计的卓越书籍。 – Justin Standard

 

后语

除这个书单之外,曾经也有微博网友推荐《一些经典的计算机书籍》,大约在50本。

php抓取网络词典数据,实现在终端查询单词的功能

用php写了一个简单的脚本,在终端中用命令查询某单词的意思,脚本会到译典通页面上抓取翻译结果,过滤信息后将翻译内容返回打印到终端。没有抓google翻译的,因为google太慢了,一个单词得一分钟才能有返回结果。

以前写过php数据抓取的程序,为了省事儿,就直接写了;没有用python,一个是因为对python不是很熟,再个它本身不能用xpath解析XML,需要安装python-lxml模块,用标准库里的模块解析XML实在是费劲,最可恨的是没有找到像php官网那样特别详细的python标准库文档,所以就偷懒了一下。

php这个脚本是靠curl扩展抓取数据,然后用DOMDocument和DOMXPath扩展来过滤抓来的数据,没什么可说的,直接上代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#!/usr/bin/php
<?php

//禁止错误信息的输出,dom扩展会在运行时返回warning
error_reporting(0);

//设置头部信息,编码为utf8
header("Content-Type:text/html;charset=utf-8");

//设置变量用来遍历参数的
$i = 1;
while(isset($argv[$i])):

    $word = $argv[$i];

    //百度词库查询单词的url地址
    $url = "http://dict.baidu.com/s?wd=".$word."&f=3&dt=explain";

    //初始化curl
    $curl = curl_init();

    //对curl进行各种设置
    curl_setopt($curl,CURLOPT_URL,$url);
    curl_setopt($curl,CURLOPT_FOLLOWLOCATION,1);
    curl_setopt($curl,CURLOPT_RETURNTRANSFER,1);

    //执行curl进行抓取,返回数据结果
    $data = curl_exec($curl);

    if(!$data)
    {
        echo "数据抓取失败,请检查网络链接\n";
        exit(0);
    }

    curl_close($curl);

    //新建DOM对象,然后curl抓取来的数据建立dom对象
    $dom = new DOMDocument();
    $loaded = $dom->loadHTML($data);

    //如果加载成功
    if($loaded):

        //新建XPath对象,在dom对象中检索想要的信息
        $xpath = new DOMXPath($dom);
        $xpath_str = "//div[@class='explain'][1]/*";
        $list = $xpath->query($xpath_str);

        //用循环打印节选出来的内容
        if($i > 1)
            echo "-------------------------------------------------------------------\n";

        //编辑一个shell命令,用来改变输出的字体的颜色
        $shell = 'echo "\033[1;34;10m"';
        system($shell);
        echo $word.":";

        //再把颜色变回来
        $shell = 'echo "\033[0;0;0m"';
        system($shell);

        foreach($list as $explain):
            if($explain->nodeName == "span"):
                echo "\n".$explain->nodeValue."\n";
            elseif($explain->nodeName == "div"):
                echo "    ".$explain->nodeValue."\n";
            endif;
        endforeach;
    endif;
    echo "\n\n";
    $i++;
endwhile;

exit(0);

运行脚本,后面参数就是要翻译的单词,可以跟多个参数同时翻译多个单词。

我是讲文件起名为fy,然后移动到了/usr/local/bin/目录下(ubuntu系统);之后就可直接用fy命令翻译单词,不足的就是网络不好的话,翻译的可能会很慢。下面是一个截图

 

PS:更新一下,算是第二个版本吧。下面是更新内容和新的代码

更新内容:

  1. 改到了译典同网站上抓取单词释义。因为偶然发现百度词典页面上标注着翻译结果来自译典通,那我何必要经过百度呢。
  2. 精简了释义。之前的脚本,抓取的单词解释和例句没有分行直接一起显示,显着特别乱,这次把例句全部去掉,只留释义。
  3. 添加了本地词库,初始为空,每次查词现到本地词库获取,如果没有就到网络上抓取,然后将其存放到本地词库。这样主要是统计,词库会记录单词被查询的次数。而且对于重复的单词不必因网络延迟而等上很多秒了。没有彻底建个本地词库,感觉太费劲了,上百万的词库能用得上的单词撑死也就上千个。而且搜索起来也费劲,本身数据结构算法学的也不好。
  4. 最热词排名。如果后面跟的参数是一个数字n,就会列出查询次数前n多的单词。这样就能知道自己哪些单词总是看着眼熟还总是不知道什么意思了。

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
#!/usr/bin/php
<?php

$username = exec('echo $USER');
//字典文件名字
define('DICT','/home/'.$username.'/.fydict');

//打印出单词释义的函数,
//参数$explain:单词释义数组
//参数$word:单词
function print_explain($explain,$word)
{
    //编辑一个shell命令,用来改变输出的字体的颜色
    $shell = 'echo "\033[1;34;10m"';
    system($shell);
    echo $word.":";

    //再把颜色变回来
    $shell = 'echo "\033[0;0;0m"';
    system($shell);

    if(!is_array($explain))
    {
        echo "单词无释义,请检查拼写是否错误";
        return 0;
    }

    foreach($explain as $item):
        echo "  ".$item."\n";
    endforeach;
}

//把用xpath解析出来的domnodelist对象
//中的释义数据存放到数组中返回
function create_explain_array($list)
{
    $item = array();
    foreach($list as $explain):
        if($explain->getAttribute('class') == "default")
            $item[] = "   ".$explain->nodeValue;
        if($explain->getAttribute('class') == "t_red")
            $item[] = " ".$explain->nodeValue;
    endforeach;

    //如果dom中没有单词释义信息,返回false
    if(count($item) == 0)
        return false;
    return $item;
}
function print_list($num)
{
    if(!file_exists(DICT))
    {
        echo "错误:词库文件不存在,请手动建立名为\".fydict\"的文件放置在脚本文件所在目录\n";
        return false;
    }
    @$handle = fopen(DICT,'r');
    if(!$handle)
    {
        echo "权限不足,请把词库权限修改为644\n";
        return false;
    }

    //list数组存
    //[最热单词] => 查询次数
    $list = array();

    //遍历字典表的行数,也用来表示遍历了多少个单词了
    $line_number = 1;

    //遍历文件,选出次数最多的num个单词
    while(!feof($handle)):
        $local_line = fgets($handle);
        $local_word = explode('|',$local_line);

        //键值为单词名字,值为查询次数
        $list[$local_word[0]] = intval($local_word[1]);

        //没加入一个就排序一次
        arsort($list);

        //如果数组大小超过了规定的大小,那就把最后一位(最不热)去掉
        if($line_number >  $num)
            array_pop($list);
        $line_number++;
    endwhile;

    //如果读到词典结尾了也没有达到设定值
    //把最后一位弹出,因为读文件最后会读一个空
    if($line_number <= $num)
        array_pop($list);

    fclose($handle);

    //循环打印最热单词数组
    foreach($list as $k=>$v)
        echo str_pad($k,20)."   ".$v."\n";
    unset($list);
}
//设置变量用来遍历参数的
$i = 1;

while(isset($argv[$i])):

    if(is_numeric($argv[$i])):
        print_list(intval($argv[$i]));
        exit(0);
    endif;

    //判断单词找到的标志变量
    $finded = false;

    $word = $argv[$i];
    $i++;

#################先到本地词库中查找#############################

    //如果文件不存在,就创建一个
    if(!file_exists(DICT))
    {
        $shell = "touch ".DICT;
        system($shell);
        $shell = "chmod 644 ".DICT;
        system($shell);
    }
    //打开本地词库文件
    @$handle = fopen(DICT,'r');

    $local_line_number = 1;
    if(!$handle)
    {
        echo "无法打开字典文件\n请手动建立名为\".fydict\"的文件放置在脚本文件所在目录";
        exit(0);
    }

    while(!feof($handle)):
        $local_line = fgets($handle);

        //读取一行内容
        $local_word = explode('|',$local_line);
        if(strncasecmp($word,$local_word[0],count($word)) === 0):
            //打印单词释义,并更新字典文件中单词查询的次数
            print_explain(unserialize($local_word[2]),$word);
            $shell = 'sed -i "'.$local_line_number.','.$local_line_number.'s/|'.$local_word[1].'|/|'.++$local_word[1].'|/g" '.DICT;
            system($shell);

            //设置已查询到,退出
            $finded = true;
            break;
        endif;

        //行数加一
        $local_line_number++;
    endwhile;

    //关闭文件指针
    fclose($handle);

    //如果找到单词了,就继续找下一个单词
    if($finded)
        continue;

#######################以下是到网络字典中取词的代码#######################
    //译典通词库查询单词的url地址
    $url = "http://www.dreye.com.cn/ews/".$word."--01--.html";

    //curl
    $curl = curl_init();

    //对curl进行各种设置
    curl_setopt($curl,CURLOPT_URL,$url);
    curl_setopt($curl,CURLOPT_FOLLOWLOCATION,1);
    curl_setopt($curl,CURLOPT_RETURNTRANSFER,1);

    //执行curl进行抓取,返回数据结果
    $data = curl_exec($curl);

    //关闭CURL
    curl_close($curl);

    if(!$data)
    {
        echo "数据抓取失败,请检查网络链接\n";
        exit(0);
    }

    //新建DOM对象,然后curl抓取来的数据建立dom对象
    $dom = new DOMDocument();
    @ $loaded = $dom->loadHTML($data);

    //如果加载成功
    if($loaded):

        //新建XPath对象,在dom对象中检索想要的信息
        $xpath = new DOMXPath($dom);
        $xpath_str = "//div[@class='dict_cont']/div[@class='t_red'or @class='default']";
        $list = $xpath->query($xpath_str);

        #把筛选的结果信息存放到数组中并输出到屏幕
        $explain_array = create_explain_array($list);
        print_explain($explain_array,$word);

        #把释义数组打成字符串存放到字典中
        if($explain_array):
            $word_explain = serialize($explain_array);

            //以追加的方式打开文件
            $handle = fopen(DICT,'ab');
            //构造单词字典字符串
            $dict = $word."|1|".$word_explain."\n";
            //将单词写入到字典文件中
            fwrite($handle,$dict);
            fclose($handle);
        endif;

    endif;
    echo "\n\n";
endwhile;

exit(0);

把vim打造成简单IDE的python脚本

假期在家没事儿用python写了一个配置vim的脚本,免得以后重装系统后还要按照自己以前写的教程一步步的装插件和写配置文件。脚本只是把之前写过的一个教程《新手开始使用vim》里的各步骤集合了一下。

下载:vim.tar

安装:下载后解压,在终端里cd到解压后的vim目录,./install命令运行即可

说明:压缩包里有三个插件,分别是taglist,winmanager,autocomplete。另外还加上了一个php_funclist文件,里面有php语言函数库名称,实现了php的自动补全。建立了vimrc配置文件,进行了简单的设置。

winmanager快捷键:wm显示或隐藏winmanager窗口,tt光标移动到文件选择窗口,bb光标移动到taglist窗口

 

PS:对脚本稍微改写了一下,改成了一个单独安装vim插件的脚本。

下载:vimplugin.tar

说明:解压后里面有个vimplugin脚本,直接./vimplugin ***.zip运行,后面的***是vim插件压缩包路径。这个脚本只支持.zip格式的vim插件,因为在官网上下载的插件都是.zip格式的。

Next page