阳光地带
百度空间 | 百度首页 
 
文章列表
 
2009-10-27 00:51
好文章先收藏啦, http://www.linuxsir.org/bbs/printthread.php?t=266890

介绍

如何使用dlopen API动态地加载C++函数和类,是Unix C++程序员经常碰到的问题。事实上,情况偶尔有些复杂,需要一些解释。这正是写这篇mini HOWTO的缘由。
理解这篇文档的前提是对C/C++语言中dlopen API有基本的了解。这篇HOWTO的维护链接是 http://www.isotton.com/howtos/C++-dlopen-mini-HOWTO/

  版权和许可证
这篇文档《C++ dlopen mini HOWTO》版权为Aaron Isotton所有(copyrighted (c) 2002-2006),任何人在遵守自由软件基金会制定的GPLv2许可证条款前提下可以自由拷贝、分发和修改这份文档。

  不承诺
本文不对文中的任何内容作可靠性承诺。您必须为您自己使用文中任何概念、示例和信息承担风险,因为其中可能存在错误和不准确的地方,或许会损坏您的系统──尽管几乎不可能发生此类事故,但您还是小心行事──作者不会为此负任何责任。

  贡献者
在这篇文档中,我欣然致谢(按字母顺序):
◆ Joy Y Goodreau <joyg (at) us.ibm.com> 她的编辑工作.
◆ D. Stimitis <stimitis (at) idcomm.com> 指出一些formatting和name mangling的问题, 还指出extern “C”的一些微妙之处。

  反馈
欢迎对本文档的反馈信息!请把您的补充、评论和批评发送到这个邮件地址:<aaron@isotton.com>。

  术语
dlopen API
关于dlclose、dlerror、dlopen和dlsym函数的描述可以在 dlopen(3) man手册页查到。
请注意,我们使用“dlopen”时,指的是dlopen函数,而使用“dlopen API”则是指整个API集合。
------------------------------------------------
问题所在
有时你想在运行时加载一个库(并使用其中的函数),这在你为你的程序写一些插件或模块架构的时候经常发生。
在C语言中,加载一个库轻而易举(调用dlopen、dlsym和dlclose就够了),但对C++来说,情况稍微复杂。动态加载一个C++库的困 难一部分是因为C++的name mangling(译者注:也有人把它翻译为“名字毁坏”,我觉得还是不翻译好),另一部分是因为dlopen API是用C语言实现的,因而没有提供一个合适的方式来装载类。
在解释如何装载C++库之前,最好再详细了解一下name mangling。我推荐您了解一下它,即使您对它不感兴趣。因为这有助于您理解问题是如何产生的,如何才能解决它们。

  Name Mangling
在每个C++程序(或库、目标文件)中,所有非静态(non-static)函数在二进制文件中都是以“符号(symbol)”形式出现的。这些符号都是唯一的字符串,从而把各个函数在程序、库、目标文件中区分开来。
在C中,符号名正是函数名:strcpy函数的符号名就是“strcpy”,等等。这可能是因为两个非静态函数的名字一定各不相同的缘故。
而C++允许重载(不同的函数有相同的名字但不同的参数),并且有很多C所没有的特性──比如类、成员函数、异常说明──几乎不可能直接用函数名作符 号名。为了解决这个问题,C++采用了所谓的name mangling。它把函数名和一些信息(如参数数量和大小)杂糅在一起,改造成奇形怪状,只有编译器才懂的符号名。例如,被mangle后的foo可能 看起来像foo@4%6^,或者,符号名里头甚至不包括“foo”。
其中一个问题是,C++标准(目前是[ISO14882])并没有定义名字必须如何被mangle,所以每个编译器都按自己的方式来进行name mangling。有些编译器甚至在不同版本间更换mangling算法(尤其是g++ 2.x和3.x)。即使您搞清楚了您的编译器到底怎么进行mangling的,从而可以用dlsym调用函数了,但可能仅仅限于您手头的这个编译器而已, 而无法在下一版编译器下工作。

  类
使用dlopen API的另一个问题是,它只支持加载函数。但在C++中,您可能要用到库中的一个类,而这需要创建该类的一个实例,这不容易做到。

解决方案

extern "C"
C++有个特定的关键字用来声明采用C binding的函数:extern "C" 。 用 extern "C"声明的函数将使用函数名作符号名,就像C函数一样。因此,只有非成员函数才能被声明为extern "C",并且不能被重载。尽管限制多多,extern "C"函数还是非常有用,因为它们可以象C函数一样被dlopen动态加载。冠以extern "C"限定符后,并不意味着函数中无法使用C++代码了,相反,它仍然是一个完全的C++函数,可以使用任何C++特性和各种类型的参数。

加载函数
在C++中,函数用dlsym加载,就像C中一样。不过,该函数要用extern "C"限定符声明以防止其符号名被mangle。

。。。
 
2009-09-20 23:33
今天和mm去看了卡地亚珍宝艺术展,太帅气了,法国人的手工真是精细,先上PP
























 
2009-08-21 14:31
在网上google,baidu了半天,居然没有找到相关的资料,最后没办法,去看了C的inet_aton函数的源码,最后一句 if (addr) addr->s_addr = htonl(val); ,在php里面实现htonl搞定,

htonl 将主机的无符号长整形数转换成网络字节顺序。
unpack("N",pack("L",$a)) 的效果和htonl相同
L unsigned long (always 32 bit, machine byte order)
N unsigned long (always 32 bit, big endian byte order)

Big-Endian 和 Little-Endian 字节排序
字节排序
含义
Big-Endian
一个Word中的高位的Byte放在内存中这个Word区域的低地址处。
Little-Endian
一个Word中的低位的Byte放在内存中这个Word区域的低地址处。
必须注意的是:表中一个Word的长度是16位,一个Byte的长度是8位。如果一个数超过一个Word的长度,必须先按Word分成若干部分,然后每一部分(即每个Word内部)按Big-Endian或Little-Endian的不同操作来处理字节。

所以,Big-Endian就是网络字节顺序

function inet_aton($ip){
$a = ip2long($ip);
$b = unpack("N",pack("L",$a));
return $b[1];
}
 
2009-06-07 23:51

“80后者,初从文,未及义务教育之免费,不逮高等学校之分配,适值扩招,过五关,斩六将,硕博相继,数年乃成,负债十万。觅生计,十年无休,披星 戴月,秉烛达旦,蓄十万。楼市暴涨,不足购房,遂投股市,翌年缩至万余,抑郁成疾。医保曰,不符大病之条例,拒赔。”这段描述80后的文字,调侃的背后有 一种深深的无奈。如果说这些无奈可以以自嘲的方式分享,而下面的这些寂寞却与谁说……

  1、独自在街道上游荡,看着街道上熙熙攘攘的人群,那些欢笑着的脸孔,那些都是不属于你的,你只是一个过客,什么也带不走,什么也留不下 ,再怎样的热闹,再怎样的繁华,却越发衬托你的形单影只 ,在人群中,你默然抬起头,却找不到一张熟悉的面孔……

      
2、一个人蜷缩在床上,无法入睡,脑子里想着莫名其妙的问题,黑暗犹如一张巨大的蛛网把你包裹在内,厚厚的棉被里,你感觉 好冷 ,从枕头下掏出手机,却发现你不知道该打给谁,于是,无奈的又塞回枕头中 ,你把头缩进被子里,轻轻的抱住自己的膝盖,像一个孩子把自己抱紧一点,那么,就不会冷了吧……

      
3、你恨一些人,一些事,甚至恨着这个世界 ,你总是在想,为什么是你 ,为什么承受一切痛苦的都必须是你 ,你只想做一个普普通通的小孩子,开心过完自己的童年,读书,找工作,恋爱……可是,这么普通的一切,对于你,却如此的难……你感觉背后似乎有一双眼睛, 带着讽刺的笑意看着你,然后,摇摇头,走开了……

      
4、面对着电脑发呆,身边的咖啡已经渐渐发凉,耳机里绵延出悠扬的音乐声,此时,已是凌晨,你也不知道是什么时候变成这样 的,像是一个穴居动物一般,躲在自己的窝里不想出来,什么时候,开始害怕外面的阳光,讨厌出门,面对着门外的那些人,你觉得他们甚至没有你那台冰冷的电脑 亲切,有时,虚拟世界,确实要比现实世界美丽……


5、你靠在窗边,透过蒙蒙细雨,静静的看着这个陌生的城市,你 不知道要在这里停留多久,你不知道你会遇见什么样的人,不也不知道你会留下怎样的回忆……点一支烟,烟雾缭绕中,你静静的咪上眼,享受这一刻的寂静,过去 的一切就让他这样过去吧,从今开始,你要学会认识陌生的人,做陌生的事,过陌生的生活……独在异乡为异客……


6、你习惯一个人在学校的走道上手插口袋漫步徜徉,没有目标,没有终点,你只是想这样一步一步的走下去,走到自己筋疲力尽为止,你学会在这种只属于一个人 的时间里,独自思考着解开一些问题,无论你的结论是对是错,都已经不重要了……你看着那热闹的操场,嘴角,轻轻上扬着一丝微笑,夕阳下,你的影子拉的好 长……


7、你在梦里看到她/他的离开,哭泣着从梦里醒来,看着空荡的房间,你静静的走到洗脸台前,看着镜子里,自己苍白而憔悴的脸,你一瞬间泪流满面……


8、你清晨起床,家中空无一人,你给自己泡了一杯牛奶,呵着暖暖的热气坐在阳台上的沙发里,随手翻开着旁边厚厚的书籍,冬日的阳光懒散而温暖的照在你身上 周围寂静而安详,不知不觉中,你再次睡着,轻声打着呼噜,如同一只懒猫。


9、你一直沉醉在回忆里,不愿意醒来,你想起以前和朋友在一起的场面,便会微微发笑,你想起以前的一些窘事,便会微微脸红,你想起以前的一些无奈,便会轻声长叹,你想起了她,便会死死的咬住下唇,你害怕……你会哭出声来……


10、你在酒吧里点一支啤酒,听着震耳欲聋的音乐,看着舞池里扭动着的人群,你漫无表情,冰冷的啤酒从食道一直凉到胃里,你轻声的呻吟…… 然后,随着眩目的灯光,脚轻轻的打着拍子,巴台上,你的背影像是一尊石像……


11、学会不再哭泣,学会不再透露自己的感情,他们说你冷血,你却只是在那里微笑,你知道,没有必要试图让别人了解你,知我者为我分忧,不知我者谓我何 求,眼泪解决不了任何问题,只会带来吵闹,很多的事情,我们可以感动,却不能流泪,因为一旦放任自己的感情,怕会让自己泣不成声。


12、参加一场聚会,喝很多酒,却一直没有醉倒,眯着一双眼睛看这个世界,光怪而陆离,告诉自己,你喜欢这种感觉,独自去洗脸台,泼了点冷水在脸上,然后看着镜子一个人傻笑,醉后……世界好美……


13、默默的喜欢上她/他,却不敢玷污这份感情,一直将它默默珍藏,无论她多么的骄横,无论她多么的不讲道理,无论她让你气上多少次,你都一直在让着 她,你明白你现在给不了她什么,你明白现实比爱情残酷,你明白,等你能够给她想要的东西时,你才配去爱她……最后,当你鼓起勇气去找她,去寻觅每一个她可 能在的角落,想跟她说明白一切时,却发现她的身边,已经有了一个能够让她幸福的人不爱她的理由有很多,爱她的理由……已经不存在了……

小评:80后们,最缺的就是沟通,因为怕伤害也怕被伤害。

总是把自己裹在密不通风的外套里。

也许,只有某一缕阳光能够救赎这本该属于我们的世界~

 
2009-05-24 11:19

作者 Stefan Tilkov 译者 苑永凯

不知你是否意识到,围绕着什么才是实现异构的应用到应用通信的“正确”方式,一场争论正进行的如火如荼:虽然当前主流的方式明显地集中在基于 SOAP、WSDL和WS-*规范的Web Services领域,但也有少数人用细小但洪亮的声音主张说更好的方式是REST,表述性状态转移(REpresentational State Transfer)的简称。在本文中,我不会涉及争论的话题,而是尝试对REST和RESTful HTTP应用集成做实用性的介绍。以我的经验,有些话题一旦触及就会引来众多的讨论,当涉及到这方面话题的时候,我会深入详细地阐述。

REST关键原则

大部分对REST的介绍是以其正式的定义和背景作为开场的。但这儿且先按下不表,我先提出一个简单扼要的定义:REST定义了应该如何正确地使用 (这和大多数人的实际使用方式有很大不同)Web标准,例如HTTP和URI。如果你在设计应用程序时能坚持REST原则,那就预示着你将会得到一个使用 了优质Web架构(这将让你受益)的系统。总之,五条关键原则列举如下:

  • 为所有“事物”定义ID
  • 将所有事物链接在一起
  • 使用标准方法
  • 资源多重表述
  • 无状态通信

下面让我们进一步审视这些原则。

为所有“事物”定义ID

在这里我使用了“事物”来代替更正式准确的术语“资源”,因为一条如此简单的原则,不应该被淹没在术语当中。思考一下人们构建的系统,通常会找到一 系列值得被标识的关键抽象。每个事物都应该是可标识的,都应该拥有一个明显的ID——在Web中,代表ID的统一概念是:URI。URI构成了一个全局命 名空间,使用URI标识你的关键资源意味着它们获得了一个唯一、全局的ID。

对事物使用一致的命名规则(naming scheme)最主要的好处就是你不需要提出自己的规则——而是依靠某个已被定义,在全球范围中几乎完美运行,并且能被绝大多数人所理解的规则。想一下你 构建的上一个应用(假设它不是采用RESTful方式构建的)中的任意一个高级对象(high-level object),那就很有可能看到许多从使用唯一标识中受益的用例。比如,如果你的应用中包含一个对顾客的抽象,那么我可以相当肯定,用户会希望将一个指 向某个顾客的链接,能通过电子邮件发送到同事那里,或者加入到浏览器的书签中,甚至写到纸上。更透彻地讲:如果在一个类似于Amazon.com的在线商 城中,没有用唯一的ID(一个URI)标识它的每一件商品,可想而知这将是多么可怕的业务决策。

当面对这个原则时,许多人惊讶于这是否意味着需要直接向外界暴露数据库记录(或者数据库记录ID)——自从多年以来面向对象的实践告诫我们,要将持 久化的信息作为实现细节隐藏起来之后,哪怕是刚有点想法都常会使人惊恐。但是这条原则与隐藏实现细节两者之间并没有任何冲突:通常,值得被URI标识的事 物——资源——要比数据库记录抽象的多。例如,一个定单资源可以由定单项、地址以及许多其它方面(可能不希望作为单独标识的资源暴露出来)组成。标识所有 值得标识的事物,领会这个观念可以进一步引导你创造出在传统的应用程序设计中不常见的资源:一个流程或者流程步骤、一次销售、一次谈判、一份报价请求—— 这都是应该被标识的事物的示例。同样,这也会导致创建比非RESTful设计更多的持久化实体。

下面是一些你可能想到的URI的例子:

http://example.com/customers/1234
http://example.com/orders/2007/10/776654
http://example.com/products/4554
http://example.com/processes/salary-increase-234

正如我选择了创建便于阅读的URI——这是个有用的观点,尽管不是RESTful设计所必须的——应该能十分容易地推测出URI的含义:它们明显地标识着单一“数据项”。但是再往下看:

http://example.com/orders/2007/11
http://example.com/products?color=green

首先,这两个URI看起来与之前的稍有不同——毕竟,它们不是对一件事物的标识,而是对一类事物集合的标识(假定第一个URI标识了所有在2007年11月份提交的定单,第二个则是绿颜色产品的集合)。但是这些集合自身也是事物(资源),也应该被标识。

注意,使用唯一、全局统一的命名规则的好处,既适用于浏览器中的Web应用,也适用于机对机(machine-to-machine,m2m)通信。

来对第一个原则做下总结:使用URI标识所有值得标识的事物,特别是应用中提供的所有“高级”资源,无论这些资源代表单一数据项、数据项集合、虚拟亦或实际的对象还是计算结果等。

将所有事物链接在一起

接下来要讨论的原则有一个有点令人害怕的正式描述:“超媒体被当作应用状态引擎(Hypermedia as the engine of application state)”,有时简写为HATEOAS。(严格地说,这不是我说的。)这个描述的核心是超媒体概念,换句话说:是链接的思想。链接是我们在HTML中常见的概念,但是它的用处绝不局限于此(用于人们网络浏览)。考虑一下下面这个虚构的XML片段:

 
23


如果你观察文档中product和customer的链接,就可以很容易地想象到,应用程序(已经检索过文档)如何“跟随”链接检索更多的信息。当然,如果使用一个遵守专用命名规范的简单“id”属性作为链接,也是可行的——但是仅限于应用环境之内。使用URI表示链接的优雅之处在于,链接可以指向由不同应用、不同服务器甚至位于另一个大陆上的不同公司提供的资源——因为URI命名规范是全球标准,构成Web的所有资源都可以互联互通。

超媒体原则还有一个更重要的方面——应用“状态”。简而言之,实际上服务器端(如果你愿意,也可以叫服务提供者)为客户端(服务消费者)提供一组链 接,使客户端能通过链接将应用从一个状态改变为另一个状态。稍后我们会在另一篇文章中探究这个方面的影响;目前,只需要记住:链接是构成动态应用的非常有 效的方式。

对此原则总结如下:任何可能的情况下,使用链接指引可以被标识的事物(资源)。也正是超链接造就了现在的Web。

使用标准方法

在前两个原则的讨论中暗含着一个假设:接收URI的应用程序可以通过URI明确地一些有意义的事情。如果你在公共汽车上看到一个URI,你可以将它输入浏览器的地址栏中并回车——但是你的浏览器如何知道需要对这个URI做些什么呢?

它知道如何去处理URI的原因在于所有的资源都支持同样的接口,一套同样的方法(只要你乐意,也可以称为操作)集合。在HTTP中这被叫做动词 (verb),除了两个大家熟知的(GET和POST)之外,标准方法集合中还包含PUT、DELETE、HEAD和OPTIONS。这些方法的含义连同 行为许诺都一起定义在HTTP规范之中。如果你是一名OO开发人员,就可以想象到RESTful HTTP方案中的所有资源都继承自类似于这样的一个类(采用类Java、C#的伪语法描述,请注意关键的方法):

class Resource {
Resource(URI u);
Response get();
Response post(Request r);
Response put(Request r);
Response delete();
}

由于所有资源使用了同样的接口,你可以依此使用GET方法检索一个表述(representation)——也 就是对资源的描述。因为规范中定义了GET的语义,所以可以肯定当你调用它的时候不需要对后果负责——这就是为什么可以“安全”地调用此方法。GET方法 支持非常高效、成熟的缓存,所以在很多情况下,你甚至不需要向服务器发送请求。还可以肯定的是,GET方法具有幂等性[译 注:指多个相同请求返回相同的结果]——如果你发送了一个GET请求没有得到结果,你可能不知道原因是请求未能到达目的地,还是响应在反馈的途中丢失了。 幂等性保证了你可以简单地再发送一次请求解决问题。幂等性同样适用于PUT(基本的含义是“更新资源数据,如果资源不存在的话,则根据此URI创建一个新 的资源”)和DELETE(你完全可以一遍又一遍地操作它,直到得出结论——删除不存在的东西没有任何问题)方法。POST方法,通常表示“创建一个新资 源”,也能被用于调用任过程,因而它既不安全也不具有幂等性。

如果你采用RESTful的方式暴露应用功能(如果你乐意,也可以称为服务功能),那这条原则和它的约束同样也适用于你。如果你已经习惯于另外的设计方式,则很难去接受这条原则——毕竟,你很可能认为你的应用包含了超出这些操作表达范围的逻辑。请允许我花费一些时间来让你相信不存在这样的情况。

来看下面这个简单的采购方案例子:

Sample Scenario

可以看到,例子中定义了两个服务程序(没有包含任何实现细节)。这些服务程序的接口都是为了完成任务(正是我们讨论的 OrderManagement和CustomerManagement服务)而定制的。如果客户端程序试图使用这些服务,那它必须针对这些特定接口进行 编码——不可能在这些接口定义之前,使用客户程序去有目的地和接口协作。这些接口定义了服务程序的应用协议(application protocol)。

在RESTful HTTP方式中,你将通过组成HTTP应用协议的通用接口访问服务程序。你可能会想出像这样的方式:

Sample Scenario, done RESTfully

可以看到,服务程序中的特定操作被映射成为标准的HTTP方法——为了消除歧义,我创建了一组全新的资源。“这是骗人的把戏”,我听见你叫嚷着。 不,这不是欺骗。标识一个顾客的URI上的GET方法正好相当于getCustomerDetails操作。有人用三角形形象化地说明了这一点:

Knobs one can turn

把三个顶点想象为你可以调节的按钮。可以看到在第一种方法中,你拥有许多操作,许多种类的数据以及固定数量的“实例”(本质上和你拥有的服务程序数 量一致)。在第二种方法中,你拥有固定数量的操作,许多种类的数据和许多调用固定方法的对象。它的意义在于,证明了通过这两种方式,你基本上可以表示任何 你喜欢的事情。

为什么使用标准方法如此重要?从根本上说,它使你的应用成为Web的一部分——应用程序为Web变成Internet上最成功的应用所做的贡献,与 它添加到Web中的资源数量成比例。采用RESTful方式,一个应用可能会向Web中添加数以百万计的客户URI;如果采用CORBA技术并维持应用的 原有设计方式,那它的贡献大抵只是一个“端点(endpoint)”——就好比一个非常小的门,仅仅允许有钥匙的人进入其中的资源域。

统一接口也使得所有理解HTTP应用协议的组件能与你的应用交互。通用客户程序(generic client)就是从中受益的组件的例子,例如curl、wget、代理、缓存、HTTP服务器、网关还有Google、Yahoo!、MSN等等。

总结如下:为使客户端程序能与你的资源相互协作,资源应该正确地实现默认的应用协议(HTTP),也就是使用标准的GET、PUT、POST和DELETE方法。

资源多重表述

到目前为止我们一直忽略了一个稍微复杂的问题:客户程序如何知道该怎样处理检索到的数据,比如作为GET或者POST请求的结果?原因是,HTTP 采取的方式是允许数据处理和操作调用之间关系分离的。换句话说,如果客户程序知道如何处理一种特定的数据格式,那就可以与所有提供这种表述格式的资源交 互。让我们再用一个例子来阐明这个观点。利用HTTP内容协商(content negotiation),客户程序可以请求一种特定格式的表述:

GET /customers/1234 HTTP/1.1
Host: example.com
Accept: application/vnd.mycompany.customer+xml

请求的结果可能是一些由公司专有的XML格式表述的客户信息。假设客户程序发送另外一个不同的请求,就如下面这样:

GET /customers/1234 HTTP/1.1
Host: example.com
Accept: text/x-vcard

结果则可能是VCard格式的客户地址。(在这里我没有展示响应的内容,在其HTTP Content-type头中应该包含着关于数据类型的元数据。)这说明为什么理想的情况下,资源表述应该采用标准格式——如果客户程序对HTTP应用协 议和一组数据格式都有所“了解”,那么它就可以用一种有意义的方式与世界上任意一个RESTful HTTP应用交互。 不幸的是,我们不可能拿到所有东西的标准格式,但是,或许我们可以想到在公司或者一些合作伙伴中使用标准格式来营造一个小环境。当然以上情况不仅适用于从 服务器端到客户端的数据,反之既然——倘若从客户端传来的数据符合应用协议,那么服务器端就可以使用特定的格式处理数据,而不去关心客户端的类型。

在实践中,资源多重表述还有着其它重要的好处:如果你为你的资源提供HTML和XML两种表述方式,那这些资源不仅可以被你的应用所用,还可以被任意标准Web浏览器所用——也就是说,你的应用信息可以被所有会使用Web的人获取到。

资源多重表述还有另外一种使用方式:你可以将应用的Web UI纳入到Web API中——毕竟,API的设计通常是由UI可以提供的功能驱动的,而UI也是通过API执行动作的。将这两个任务合二为一带来了令人惊讶的好处,这使得 使用者和调用程序都能得到更好的Web接口。

总结:针对不同的需求提供资源多重表述。

无状态通信

无状态通信是我要讲到的最后一个原则。首先,需要着重强调的是,虽然REST包含无状态性(statelessness)的观念,但这并不是说暴露功能的应用不能有状态——
事 实上,在大部分情况下这会导致整个做法没有任何用处。REST要求状态要么被放入资源状态中,要么保存在客户端上。或者换句话说,服务器端不能保持除了单 次请求之外的,任何与其通信的客户端的通信状态。这样做的最直接的理由就是可伸缩性—— 如果服务器需要保持客户端状态,那么大量的客户端交互会严重影响服务器的内存可用空间(footprint)。(注意,要做到无状态通信往往需要需要一些 重新设计——不能简单地将一些session状态绑缚在URI上,然后就宣称这个应用是RESTful。)

但除此以外,其它方面可能显得更为重要:无状态约束使服务器的变化对客户端是不可见的,因为在两次连续的请求中,客户端并不依赖于同一台服务器。一 个客户端从某台服务器上收到一份包含链接的文档,当它要做一些处理时,这台服务器宕掉了,可能是硬盘坏掉而被拿去修理,可能是软件需要升级重启——如果这 个客户端访问了从这台服务器接收的链接,它不会察觉到后台的服务器已经改变了。

理论上的REST

我承认:以上我所说的REST不是真正的REST,而且我可能有点过多地热衷于简单化。但因为我想有一个与众不同的开场,所以没有在一开始就介绍其正式的定义和背景。现在就让我们稍微简要地介绍一下这方面的内容。

首先,先前我并没有明确地区分HTTP、RESTful HTTP和REST。要理解这些不同方面之间的关系,我们要先来看看REST的历史。

Roy T. Fielding在他的博士学位论文(实际上你应该访问这个链接——至少对于一篇学术论文来说,它是相当易读的。此论文已被翻译成中文) 中定义了术语REST。Roy曾是许多基本Web协议的主要设计者,其中包括HTTP和URIs,并且他在论文中对这些协议提出了很多想法。(这篇论文被 誉为“REST圣经”,这是恰当的——毕竟,是作者发明了这个术语,所以在定义上,他写的任何内容都被认为是权威的。)在论文中,Roy首先定义一种方法 论来谈论架构风格——高级、抽象的模式,来表达架构方法背后的核心理念。每一个架构风格由一系列的约束(constraints)定义形成。架构风格的例子包括“没有风格”(根本没有任何约束)、管道和过滤器(pipe and filter)、客户端/服务器、分布式对象以及——你猜到它了——REST。

如果对你来说这些听起来都太抽象了,那就对了——REST在本质上是一个可以被许多不同技术实现的高层次的风格,而且可以被实例化——通过为它的抽 象特性赋上不同的值。比如,REST中包含资源和统一接口的概念——也就是说,所有资源都应该对这些相同的方法作出反应。但是REST并没有说明是哪些方 法,或者有多少方法。

REST风格的一个“化身”便是HTTP(以及一套相关的一套标准,比如URI),或者稍微抽象一些:Web架构自身。接着上面的例子,HTTP使 用HTTP动词作为REST统一接口的“实例”。由于Fielding是在Web已经(或者至少是大部分)“完善”了之后才定义的REST风格,有人可能 会争论两者是不是100%的匹配。但是无论如何,整体上来说Web、HTTP和URI仅仅是REST风格的一个主要实现。不过,由于Roy Fielding即是REST论文的作者,又对Web架构设计有过深远的影响,两者相似也在情理之中。

最后,我在前面一次又一次地使用着术语“RESTful HTTP”,原因很简单:许多使用HTTP的应用因为一些理由并没有遵循REST原则,有人会说使用HTTP而不遵循REST原则就等同于滥用HTTP。 当然这听起来有点狂热——事实上违反REST约束的原因通常是,仅仅因为每个约束带来的设计权衡可能不适合于一些特殊情况。但通常,违背REST约束的原 因可归咎于对其好处认知的缺乏。来看一个明显的反面案例:使用HTTP GET调用类似于删除对象的操作,这违反了REST的安全约束和一般性常识(客户程序不应为此负责,服务器端开发人员大概不是有意而为之)。但在随后的文 章中,我会提及更多这样或那样的对HTTP的滥用。

总结

本文试图对REST(Web架构)背后的概念提供快速的介绍。RESTful HTTP暴露功能的方式与RPC、分布式对象以及Web Services是不相同的;要真正理解这些不同是需要一些心态的转变。不管你构建的应用是仅仅想暴露Web UI还是想把API变成Web的一份子,了解下REST的原则还是有好处的。

Stefan Tilkov是InfoQ SOA社区的首席编辑,并且是位于德国和瑞士的innoQ公司的共同创始人、首席顾问和REST狂热分子首领。

查看英文原文A Brief Introduction to REST
 
2009-05-16 01:41
晚上研究了一小会,发现wget spider模式不太稳健,有的server屏蔽了header方法,在这个时候,只好用socket去连接服务器获取啦,
嘿嘿,file_get_contents居然支持,真是爽呀,
强大无比的curl中Range参数居然没用,有些失望~~~

/**
* @author: kevinchenkai[at]gmail.com
*/
function getResponseHeader($url){
    $aContext = array(
        'http' => array(
            'User-Agent' => 'Baiduspider+(+http://www.baidu.com/search/spider.htm)',
            'Accept-Encoding' => 'gzip,deflate',
            'Referer' => $url,
        ),
    );
    $cxContext = stream_context_create($aContext);
    $sFile = file_get_contents($url, False, $cxContext,0,0); // 不获取任何的数据
    return implode("\n",$http_response_header);
}

function wgetResponseHeader($url){
    $tmp = "/tmp/" . md5($url . date("YmdHis"));
    $cmd = "wget --spider --server-response --user-agent='Baiduspider+(+http://www.baidu.com/search/spider.htm)' -o {$tmp} {$url}";
    exec($cmd);
    $cnt = file_get_contents($tmp);
    unlink($tmp);
    return $cnt;
}

$url = "http://www.sina.com.cn";
$url = "http://hi.baidu.com/ismayday/rss";
echo wgetResponseHeader($url);
echo getResponseHeader($url);
 
2009-05-12 10:11

InnoDB做为MySQL目前最广泛的事务存储引擎,很多地方的设计和Oracle都是共通的。对于Oracle DBA来说,学习的时候可以多和Oracle的一些特性进行类比,当然也要明白二者之间的区别。

innodb_additional_mem_pool_size

用于缓存InnoDB数据字典及其他内部结构的内存池大小,类似于Oracle的library cache。这不是一个强制参数,可以被突破。

innodb_buffer_pool_size

内存缓冲池大小,用于缓存表和索引数据等。类似于Oracle的buffer cache,如果可能,尽可能的设置大一点。

innodb_log_buffer_size

日志缓冲区大小,类似于Oracle的log buffer

innodb_log_file_size

日志文件大小。默认会创建2个5M大小的名为ib_logfile0和ib_logfile1的文件。日志文件的数目由参数innodb_log_files_in_group指定。存放位置由innodb_log_group_home_dir指定。

innodb_data_file_path

指定InnoDB表空间数据文件名,大小以及其他属性。所有文件的加起来不能少于10M。多个数据文件之间以逗号分割,属性之间以冒号分割。默认创 建一个大小10MB名为ibdata1的可自动扩展的数据文件,一般在生产环境中都需要根据实际情况指定,由于往表空间中添加数据文件需要停机,尽量在规 划的时候做好准备,如果可以的话最好开启最后一个数据文件的自动增长属性。数据文件的个数在规划的时候还需要考虑另外一个innodb_open_files参数。

innodb_file_per_table

取值为ON或者OFF。是否为每个table使用单独的数据文件保存。如果系统中表的个数不多,并且没有超大表,使用该参数可以使得各个表之间的维护相对独立,有一定的好处。

innodb_autoextend_increment

当自动扩展表空间被填满之时,每次扩展空间的大小,默认值是8(单位MB)。该参数可以动态修改:

mysql> set global innodb_autoextend_increment=10;
Query OK, 0 rows affected (0.01 sec)

innodb_status_file

定期将show inndb status的结果输出保存到文件中,建议开启以便分析性能。

下面是windows上一个MySQL默认的参数查询结果:

mysql> show variables like ‘Innodb%’;
+———————————+————————+
| Variable_name | Value |
+———————————+————————+
| innodb_additional_mem_pool_size | 2097152 |
| innodb_autoextend_increment | 8 |
| innodb_buffer_pool_awe_mem_mb | 0 |
| innodb_buffer_pool_size | 8388608 |
| innodb_checksums | ON |
| innodb_commit_concurrency | 0 |
| innodb_concurrency_tickets | 500 |
| innodb_data_file_path | ibdata1:10M:autoextend |
| innodb_data_home_dir | |
| innodb_doublewrite | ON |
| innodb_fast_shutdown | 1 |
| innodb_file_io_threads | 4 |
| innodb_file_per_table | OFF |
| innodb_flush_log_at_trx_commit | 1 |
| innodb_flush_method | |
| innodb_force_recovery | 0 |
| innodb_lock_wait_timeout | 50 |
| innodb_locks_unsafe_for_binlog | OFF |
| innodb_log_arch_dir | |
| innodb_log_archive | OFF |
| innodb_log_buffer_size | 1048576 |
| innodb_log_file_size | 10485760 |
| innodb_log_files_in_group | 2 |
| innodb_log_group_home_dir | .\ |
| innodb_max_dirty_pages_pct | 90 |
| innodb_max_purge_lag | 0 |
| innodb_mirrored_log_groups | 1 |
| innodb_open_files | 300 |
| innodb_rollback_on_timeout | OFF |
| innodb_support_xa | ON |
| innodb_sync_spin_loops | 20 |
| innodb_table_locks | ON |
| innodb_thread_concurrency | 8 |
| innodb_thread_sleep_delay | 10000 |
+———————————+————————+

更多InnoDB参数,请参考官方文档

 
2009-05-12 10:08

#BEGIN CONFIG INFO
#DESCR: 4GB RAM, 只使用InnoDB, ACID, 少量的连接, 队列负载大
#TYPE: SYSTEM
#END CONFIG INFO

#
# 此mysql配置文件例子针对4G内存
# 主要使用INNODB
#处理复杂队列并且连接数量较少的mysql服务器
#
# 将此文件复制到/etc/my.cnf 作为全局设置,
# mysql-data-dir/my.cnf 作为服务器指定设置
# (@localstatedir@ for this installation) 或者放入
# ~/.my.cnf 作为用户设置.
#
# 在此配置文件中, 你可以使用所有程序支持的长选项.
# 如果想获悉程序支持的所有选项
# 请在程序后加上”–help”参数运行程序.
#
# 关于独立选项更多的细节信息可以在手册内找到
#

#
# 以下选项会被MySQL客户端应用读取.
# 注意只有MySQL附带的客户端应用程序保证可以读取这段内容.
# 如果你想你自己的MySQL应用程序获取这些值
# 需要在MySQL客户端库初始化的时候指定这些选项

#
[client]
#password = [your_password]
port = @MYSQL_TCP_PORT@
socket = @MYSQL_UNIX_ADDR@

# *** 应用定制选项 ***

#
# MySQL 服务端
#
[mysqld]

# 一般配置选项
port = @MYSQL_TCP_PORT@
socket = @MYSQL_UNIX_ADDR@

# back_log 是操作系统在监听队列中所能保持的连接数,
# 队列保存了在MySQL连接管理器线程处理之前的连接.
# 如果你有非常高的连接率并且出现”connection refused” 报错,
# 你就应该增加此处的值.
# 检查你的操作系统文档来获取这个变量的最大值.
# 如果将back_log设定到比你操作系统限制更高的值,将会没有效果
back_log = 50

# 不在TCP/IP端口上进行监听.
# 如果所有的进程都是在同一台服务器连接到本地的mysqld,
# 这样设置将是增强安全的方法
# 所有mysqld的连接都是通过Unix sockets 或者命名管道进行的.
# 注意在windows下如果没有打开命名管道选项而只是用此项
# (通过 “enable-named-pipe” 选项) 将会导致mysql服务没有任何作用!
#skip-networking

# MySQL 服务所允许的同时会话数的上限
# 其中一个连接将被SUPER权限保留作为管理员登录.
# 即便已经达到了连接数的上限.
max_connections = 100

# 每个客户端连接最大的错误允许数量,如果达到了此限制.
# 这个客户端将会被MySQL服务阻止直到执行了”FLUSH HOSTS” 或者服务重启
# 非法的密码以及其他在链接时的错误会增加此值.
# 查看 “Aborted_connects” 状态来获取全局计数器.
max_connect_errors = 10

# 所有线程所打开表的数量.
# 增加此值就增加了mysqld所需要的文件描述符的数量
# 这样你需要确认在[mysqld_safe]中 “open-files-limit” 变量设置打开文件数量允许至少4096
table_cache = 2048

# 允许外部文件级别的锁. 打开文件锁会对性能造成负面影响
# 所以只有在你在同样的文件上运行多个数据库实例时才使用此选项(注意仍会有其他约束!)
# 或者你在文件层面上使用了其他一些软件依赖来锁定MyISAM表
#external-locking

# 服务所能处理的请求包的最大大小以及服务所能处理的最大的请求大小(当与大的BLOB字段一起工作时相当必要)
# 每个连接独立的大小.大小动态增加
max_allowed_packet = 16M

# 在一个事务中binlog为了记录SQL状态所持有的cache大小
# 如果你经常使用大的,多声明的事务,你可以增加此值来获取更大的性能.
# 所有从事务来的状态都将被缓冲在binlog缓冲中然后在提交后一次性写入到binlog中
# 如果事务比此值大, 会使用磁盘上的临时文件来替代.
# 此缓冲在每个连接的事务第一次更新状态时被创建
binlog_cache_size = 1M

# 独立的内存表所允许的最大容量.
# 此选项为了防止意外创建一个超大的内存表导致永尽所有的内存资源.
max_heap_table_size = 64M

# 排序缓冲被用来处理类似ORDER BY以及GROUP BY队列所引起的排序
# 如果排序后的数据无法放入排序缓冲,
# 一个用来替代的基于磁盘的合并分类会被使用
# 查看 “Sort_merge_passes” 状态变量.
# 在排序发生时由每个线程分配
sort_buffer_size = 8M

# 此缓冲被使用来优化全联合(full JOINs 不带索引的联合).
# 类似的联合在极大多数情况下有非常糟糕的性能表现,
# 但是将此值设大能够减轻性能影响.
# 通过 “Select_full_join” 状态变量查看全联合的数量
# 当全联合发生时,在每个线程中分配
join_buffer_size = 8M

# 我们在cache中保留多少线程用于重用
# 当一个客户端断开连接后,如果cache中的线程还少于thread_cache_size,
# 则客户端线程被放入cache中.
# 这可以在你需要大量新连接的时候极大的减少线程创建的开销
# (一般来说如果你有好的线程模型的话,这不会有明显的性能提升.)
thread_cache_size = 8

# 此允许应用程序给予线程系统一个提示在同一时间给予渴望被运行的线程的数量.
# 此值只对于支持 thread_concurrency() 函数的系统有意义( 例如Sun Solaris).
# 你可可以尝试使用 [CPU数量]*(2..4) 来作为thread_concurrency的值
thread_concurrency = 8

# 查询缓冲常被用来缓冲 SELECT 的结果并且在下一次同样查询的时候不再执行直接返回结果.
# 打开查询缓冲可以极大的提高服务器速度, 如果你有大量的相同的查询并且很少修改表.
# 查看 “Qcache_lowmem_prunes” 状态变量来检查是否当前值对于你的负载来说是否足够高.
# 注意: 在你表经常变化的情况下或者如果你的查询原文每次都不同,
# 查询缓冲也许引起性能下降而不是性能提升.
query_cache_size = 64M

# 只有小于此设定值的结果才会被缓冲
# 此设置用来保护查询缓冲,防止一个极大的结果集将其他所有的查询结果都覆盖.
query_cache_limit = 2M

# 被全文检索索引的最小的字长.
# 你也许希望减少它,如果你需要搜索更短字的时候.
# 注意在你修改此值之后,
# 你需要重建你的 FULLTEXT 索引
ft_min_word_len = 4

# 如果你的系统支持 memlock() 函数,你也许希望打开此选项用以让运行中的mysql在在内存高度紧张的时候,数据在内存中保持锁定并且防止可能被swapping out
# 此选项对于性能有益
#memlock

# 当创建新表时作为默认使用的表类型,
# 如果在创建表示没有特别执行表类型,将会使用此值
default_table_type = MYISAM

# 线程使用的堆大小. 此容量的内存在每次连接时被预留.
# MySQL 本身常不会需要超过64K的内存
# 如果你使用你自己的需要大量堆的UDF函数
# 或者你的操作系统对于某些操作需要更多的堆,
# 你也许需要将其设置的更高一点.
thread_stack = 192K

# 设定默认的事务隔离级别.可用的级别如下:
# READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, SERIALIZABLE
transaction_isolation = REPEATABLE-READ

# 内部(内存中)临时表的最大大小
# 如果一个表增长到比此值更大,将会自动转换为基于磁盘的表.
# 此限制是针对单个表的,而不是总和.
tmp_table_size = 64M

# 打开二进制日志功能.
# 在复制(replication)配置中,作为MASTER主服务器必须打开此项
# 如果你需要从你最后的备份中做基于时间点的恢复,你也同样需要二进制日志.
log-bin=mysql-bin

# 如果你在使用链式从服务器结构的复制模式 (A->B->C),
# 你需要在服务器B上打开此项.
# 此选项打开在从线程上重做过的更新的日志,
# 并将其写入从服务器的二进制日志.
#log_slave_updates

# 打开全查询日志. 所有的由服务器接收到的查询 (甚至对于一个错误语法的查询)
# 都会被记录下来. 这对于调试非常有用, 在生产环境中常常关闭此项.
#log

# 将警告打印输出到错误log文件. 如果你对于MySQL有任何问题
# 你应该打开警告log并且仔细审查错误日志,查出可能的原因.
#log_warnings

# 记录慢速查询. 慢速查询是指消耗了比 “long_query_time” 定义的更多时间的查询.
# 如果 log_long_format 被打开,那些没有使用索引的查询也会被记录.
# 如果你经常增加新查询到已有的系统内的话. 一般来说这是一个好主意,
log_slow_queries

# 所有的使用了比这个时间(以秒为单位)更多的查询会被认为是慢速查询.
# 不要在这里使用”1″, 否则会导致所有的查询,甚至非常快的查询页被记录下来(由于MySQL 目前时间的精确度只能达到秒的级别).
long_query_time = 2

# 在慢速日志中记录更多的信息.
# 一般此项最好打开.
# 打开此项会记录使得那些没有使用索引的查询也被作为到慢速查询附加到慢速日志里
log_long_format

# 此目录被MySQL用来保存临时文件.例如,
# 它被用来处理基于磁盘的大型排序,和内部排序一样.
# 以及简单的临时表.
# 如果你不创建非常大的临时文件,将其放置到 swapfs/tmpfs 文件系统上也许比较好
# 另一种选择是你也可以将其放置在独立的磁盘上.
# 你可以使用”;”来放置多个路径
# 他们会按照roud-robin方法被轮询使用.
#tmpdir = /tmp

# *** 复制有关的设置

# 唯一的服务辨识号,数值位于 1 到 2^32-1之间.
# 此值在master和slave上都需要设置.
# 如果 “master-host” 没有被设置,则默认为1, 但是如果忽略此选项,MySQL不会作为master生效.
server-id = 1

# 复制的Slave (去掉master段的注释来使其生效)
#
# 为了配置此主机作为复制的slave服务器,你可以选择两种方法:
#
# 1) 使用 CHANGE MASTER TO 命令 (在我们的手册中有完整描述) -
# 语法如下:
#
# CHANGE MASTER TO MASTER_HOST=, MASTER_PORT= ,
# MASTER_USER=, MASTER_PASSWORD= ;
#
# 你需要替换掉 , , 等被尖括号包围的字段以及使用master的端口号替换 (默认3306).
#
# 例子:
#
# CHANGE MASTER TO MASTER_HOST=’125.564.12.1′, MASTER_PORT=3306,
# MASTER_USER=’joe’, MASTER_PASSWORD=’secret’;
#
# 或者
#
# 2) 设置以下的变量. 不论如何, 在你选择这种方法的情况下, 然后第一次启动复制(甚至不成功的情况下,
# 例如如果你输入错密码在master-password字段并且slave无法连接),
# slave会创建一个 master.info 文件,并且之后任何对于包含在此文件内的参数的变化都会被忽略
# 并且由 master.info 文件内的内容覆盖, 除非你关闭slave服务, 删除 master.info 并且重启slave 服务.
# 由于这个原因,你也许不想碰一下的配置(注释掉的) 并且使用 CHANGE MASTER TO (查看上面) 来代替
#
# 所需要的唯一id号位于 2 和 2^32 - 1之间
# (并且和master不同)
# 如果master-host被设置了.则默认值是2
# 但是如果省略,则不会生效
#server-id = 2
#
# 复制结构中的master - 必须
#master-host =
#
# 当连接到master上时slave所用来认证的用户名 - 必须
#master-user =
#
# 当连接到master上时slave所用来认证的密码 - 必须
#master-password = #
# master监听的端口.
# 可选 - 默认是3306
#master-port =

# 使得slave只读.只有用户拥有SUPER权限和在上面的slave线程能够修改数据.
# 你可以使用此项去保证没有应用程序会意外的修改slave而不是master上的数据
#read_only

#*** MyISAM 相关选项

# 关键词缓冲的大小, 一般用来缓冲MyISAM表的索引块.
# 不要将其设置大于你可用内存的30%,
# 因为一部分内存同样被OS用来缓冲行数据
# 甚至在你并不使用MyISAM 表的情况下, 你也需要仍旧设置起 8-64M 内存由于它同样会被内部临时磁盘表使用.
key_buffer_size = 32M

# 用来做MyISAM表全表扫描的缓冲大小.
# 当全表扫描需要时,在对应线程中分配.
read_buffer_size = 2M

# 当在排序之后,从一个已经排序好的序列中读取行时,行数据将从这个缓冲中读取来防止磁盘寻道.
# 如果你增高此值,可以提高很多ORDER BY的性能.
# 当需要时由每个线程分配
read_rnd_buffer_size = 16M

# MyISAM 使用特殊的类似树的cache来使得突发插入
# (这些插入是,INSERT … SELECT, INSERT … VALUES (…), (…), …, 以及 LOAD DATA
# INFILE) 更快. 此变量限制每个进程中缓冲树的字节数.
# 设置为 0 会关闭此优化.
# 为了最优化不要将此值设置大于 “key_buffer_size”.
# 当突发插入被检测到时此缓冲将被分配.
bulk_insert_buffer_size = 64M

# 此缓冲当MySQL需要在 REPAIR, OPTIMIZE, ALTER 以及 LOAD DATA INFILE 到一个空表中引起重建索引时被分配.
# 这在每个线程中被分配.所以在设置大值时需要小心.
myisam_sort_buffer_size = 128M

# MySQL重建索引时所允许的最大临时文件的大小 (当 REPAIR, ALTER TABLE 或者 LOAD DATA INFILE).
# 如果文件大小比此值更大,索引会通过键值缓冲创建(更慢)
myisam_max_sort_file_size = 10G

# 如果被用来更快的索引创建索引所使用临时文件大于制定的值,那就使用键值缓冲方法.
# 这主要用来强制在大表中长字串键去使用慢速的键值缓冲方法来创建索引.
myisam_max_extra_sort_file_size = 10G

# 如果一个表拥有超过一个索引, MyISAM 可以通过并行排序使用超过一个线程去修复他们.
# 这对于拥有多个CPU以及大量内存情况的用户,是一个很好的选择.
myisam_repair_threads = 1

# 自动检查和修复没有适当关闭的 MyISAM 表.
myisam_recover

# 默认关闭 Federated
skip-federated

# *** BDB 相关选项 ***

# 如果你运行的MySQL服务有BDB支持但是你不准备使用的时候使用此选项. 这会节省内存并且可能加速一些事.
skip-bdb

# *** INNODB 相关选项 ***

# 如果你的MySQL服务包含InnoDB支持但是并不打算使用的话,
# 使用此选项会节省内存以及磁盘空间,并且加速某些部分
#skip-innodb

# 附加的内存池被InnoDB用来保存 metadata 信息
# 如果InnoDB为此目的需要更多的内存,它会开始从OS这里申请内存.
# 由于这个操作在大多数现代操作系统上已经足够快, 你一般不需要修改此值.
# SHOW INNODB STATUS 命令会显示当先使用的数量.
innodb_additional_mem_pool_size = 16M

# InnoDB使用一个缓冲池来保存索引和原始数据, 不像 MyISAM.
# 这里你设置越大,你在存取表里面数据时所需要的磁盘I/O越少.
# 在一个独立使用的数据库服务器上,你可以设置这个变量到服务器物理内存大小的80%
# 不要设置过大,否则,由于物理内存的竞争可能导致操作系统的换页颠簸.
# 注意在32位系统上你每个进程可能被限制在 2-3.5G 用户层面内存限制,
# 所以不要设置的太高.
innodb_buffer_pool_size = 2G

# InnoDB 将数据保存在一个或者多个数据文件中成为表空间.
# 如果你只有单个逻辑驱动保存你的数据,一个单个的自增文件就足够好了.
# 其他情况下.每个设备一个文件一般都是个好的选择.
# 你也可以配置InnoDB来使用裸盘分区 - 请参考手册来获取更多相关内容
innodb_data_file_path = ibdata1:10M:autoextend

# 设置此选项如果你希望InnoDB表空间文件被保存在其他分区.
# 默认保存在MySQL的datadir中.
#innodb_data_home_dir =

# 用来同步IO操作的IO线程的数量. This value is
# 此值在Unix下被硬编码为4,但是在Windows磁盘I/O可能在一个大数值下表现的更好.
innodb_file_io_threads = 4

# 如果你发现InnoDB表空间损坏, 设置此值为一个非零值可能帮助你导出你的表.
# 从1开始并且增加此值知道你能够成功的导出表.
#innodb_force_recovery=1

# 在InnoDb核心内的允许线程数量.
# 最优值依赖于应用程序,硬件以及操作系统的调度方式.
# 过高的值可能导致线程的互斥颠簸.
innodb_thread_concurrency = 16

# 如果设置为1 ,InnoDB会在每次提交后刷新(fsync)事务日志到磁盘上,
# 这提供了完整的ACID行为.
# 如果你愿意对事务安全折衷, 并且你正在运行一个小的食物, 你可以设置此值到0或者2来减少由事务日志引起的磁盘I/O
# 0代表日志只大约每秒写入日志文件并且日志文件刷新到磁盘.
# 2代表日志写入日志文件在每次提交后,但是日志文件只有大约每秒才会刷新到磁盘上.
innodb_flush_log_at_trx_commit = 1

# 加速InnoDB的关闭. 这会阻止InnoDB在关闭时做全清除以及插入缓冲合并.
# 这可能极大增加关机时间, 但是取而代之的是InnoDB可能在下次启动时做这些操作.
#innodb_fast_shutdown

# 用来缓冲日志数据的缓冲区的大小.
# 当此值快满时, InnoDB将必须刷新数据到磁盘上.
# 由于基本上每秒都会刷新一次,所以没有必要将此值设置的太大(甚至对于长事务而言)

innodb_log_buffer_size = 8M

# 在日志组中每个日志文件的大小.
# 你应该设置日志文件总合大小到你缓冲池大小的25%~100%
# 来避免在日志文件覆写上不必要的缓冲池刷新行为.
# 不论如何, 请注意一个大的日志文件大小会增加恢复进程所需要的时间.
innodb_log_file_size = 256M

# 在日志组中的文件总数.
# 通常来说2~3是比较好的.
innodb_log_files_in_group = 3

# InnoDB的日志文件所在位置. 默认是MySQL的datadir.
# 你可以将其指定到一个独立的硬盘上或者一个RAID1卷上来提高其性能
#innodb_log_group_home_dir

# 在InnoDB缓冲池中最大允许的脏页面的比例.
# 如果达到限额, InnoDB会开始刷新他们防止他们妨碍到干净数据页面.
# 这是一个软限制,不被保证绝对执行.
innodb_max_dirty_pages_pct = 90

# InnoDB用来刷新日志的方法.
# 表空间总是使用双重写入刷新方法
# 默认值是 “fdatasync”, 另一个是 “O_DSYNC”.
#innodb_flush_method=O_DSYNC

# 在被回滚前,一个InnoDB的事务应该等待一个锁被批准多久.
# InnoDB在其拥有的锁表中自动检测事务死锁并且回滚事务.
# 如果你使用 LOCK TABLES 指令, 或者在同样事务中使用除了InnoDB以外的其他事务安全的存储引擎
# 那么一个死锁可能发生而InnoDB无法注意到.
# 这种情况下这个timeout值对于解决这种问题就非常有帮助.
innodb_lock_wait_timeout = 120

[mysqldump]
# 不要在将内存中的整个结果写入磁盘之前缓存. 在导出非常巨大的表时需要此项
quick

max_allowed_packet = 16M

[mysql]
no-auto-rehash

# 仅仅允许使用键值的 UPDATEs 和 DELETEs .
#safe-updates

[isamchk]
key_buffer = 512M
sort_buffer_size = 512M
read_buffer = 8M
write_buffer = 8M

[myisamchk]
key_buffer = 512M
sort_buffer_size = 512M
read_buffer = 8M
write_buffer = 8M

[mysqlhotcopy]
interactive-timeout

[mysqld_safe]
# 增加每个进程的可打开文件数量.
# 警告: 确认你已经将全系统限制设定的足够高!
# 打开大量表需要将此值设高
open-files-limit = 8192

 
2009-05-11 01:33

杭州,什么人的天堂?


其实,整个事件已经不是一起车祸那么简单了,如果说争论的焦点是对肇事人的处理上,不如说是整个社会想看看这个国家对待这件事的态度。
先来看看这个事件里的各种利益集团:
谭卓——草根出身,用了一条最普通的方法脱离的贫困:考大学,上大学。知识阶级的代表范例,也可以说是社会精英阶级。
胡斌——富家子弟,说实话,胡斌构不成一个利益集团,只能算是个寄生阶级。
声援谭卓的人——这部分人的组成很复杂:
第一类,谭卓的亲友,感情因素是他们不断声讨的主要动力。
第二类,社会正义力量,他们可能是普通的杭州市民,他们可能是千里之外的普通网友,他们可能很多人在这起车祸以前根本就认识谭卓,只是出于对社会公平,道德良知的考量。
第三类,广大的社会精英阶层,这部分人和谭卓拥有相同的社会出身,他们大多也是出身寒门,通过自身努力跻身知识阶层行列,但暂时还没有到达中产阶级的水平,他们考的是最好的大学,上的是最高精尖的专业,是推动这个社会进步的最重要力量,只是他们目前收入肯定没有他们的老板高。

保护胡斌的人——这部分人的组成就很单纯了:
第一类,胡斌的父母,没有解释,亲情使然。胡斌的父母非常有钱,属于整个社会中,社会财富的享受阶级,他们自身并没有什么文化(通过对子女的教育就可以看出来),但是因为各种各样的原因却享受着现成的财富,属于既得利益者。
第二类,胡斌父母发动的人,这部分人就不明说了,有那三家按着新闻不发的媒体们,有那个说“只有70码”的交警们,还有那些隐藏在事情背后的人,等待着一个合适的“价格”才会出手的人。
双方在5月7号以后就一直在交手,声援谭卓的人一直在用一种最简单,也是最无奈的办法对国家机器施加着压力——无声的抗议,用杭州文二西路的蜡烛 抗议,用天涯上一个个愤怒的字眼在抗议,其实手握正义的人们一直在等待着,看看这个标榜公平,公正的国家机器到底会怎么处理这件事。
保护胡斌的人的动作就远比声援谭卓的人要来的直接和有效率了,他们首先压抑媒体力量,他们深深地懂得舆论的可怕,舆论可以把本来就很愤怒的人群一 下点燃,所以,他们马上利用自己手上的资源封锁了杭州的三家媒体(这种媒体基本上也就失去了社会舆论的功能,一张受控制的嘴),其次,利用人脉,让交警们 做出最有利于胡斌的发言,不要小看这一步,一个看上去很官方的借口也许就能救了一条命。其他的事情我们就看不到了,我们的身份让我们接触不到跟高层的东 西,但我们可以猜的出来那是什么……
读到这里你应该了解到我要写什么了,大家对这起“简单的车祸”的愤怒实际上就是全社会对社会财富享受阶级的愤怒,也就是对“有钱人”的愤怒。
说实话,这不是简单的“仇富心理”,而是对有钱人的不满。
第一、 对他们财富来源的愤怒
我不知道胡斌父母的财富是怎么获得,此处我不做评价,但你能说山西小煤窑的矿主的财富来的光彩;但你能说温州炒房团投机倒把来的财富光彩;但你能说三鹿奶粉用三聚氰胺勾兑来的财富光彩,但你能说上市公司用虚假报表套来的财富来的光彩……
他们是“有钱人”,但是,他们是侵占了我们的东西,甚至靠伤害了我们才获得了财富,这样的一群人,反而在我们面前耀武扬威,反而在我们家门口的文二路上飙 车时,我们愤怒了。文西二路是我们上班下班走的路,是我们的孩子上课放学走的路。“有钱人”,为什么连我们路也要占。
第二、 对他们的行为愤怒
从来都是“有钱人”欺负“穷人”,没有“穷人”欺负“有钱人”的,5000年了,中国人的“有钱人”欺负“穷人”欺负惯了,你要是被欺负了5000年,能不恨吗?
第三、 社会精英阶层开始对“有钱人”愤怒
这个事情现在并不是一个简单的社会公平问题了,草根出身的谭卓用了最直接办法脱离了贫穷,渐渐往社会精英阶层走的过程中,死了,被“有钱人”撞死了,且还 有“白死”的危险,这样无情的事实让其他还处在贫穷中,为了进入社会精英阶层而考大学的人们怎么面对?这些人寒了心,这个国家还有希望吗?
这让那些已经进入社会精英阶层的人怎么看?他们受过高等教育,有着稳定的收入,并且是社会的中坚力量(有钱的人,并不是最推动社会发展的人,也并 不是社会里最必不可少的人),最重要的是,随着时代的进步,这些人对民主与公平的渴望会愈发的强烈,他们对社会的既得利益者也会越来越不满。很简单,我为 这个社会做出了最重要的贡献,而我却得不到最丰厚的回报,甚至连“死亡”都得不到尊重。这怎么能接受?
真正是哪些人推动这个国家进步?是谭卓还是胡斌的有钱父母?
请国家机器一定要秉公处理胡斌撞人事件,不能让社会精英阶层寒了心,这些人一旦寒心就会离开这个国家,一旦他们对这个国家产生压抑感,他们就会出国,一旦他们出国,这个国家就没有了进步的可能,这才是最危险的。
一个谭卓走了,不能让其他的谭卓们的心寒了!
北大和清华的留学回国率一直不高,仅仅就是外国的物质条件好吗?
本身就留不住最好的人才,何必再往外推呢?
 
2009-05-11 00:35

——任正非4月24日在华为运作与交付体系奋斗表彰大会上的讲话

深淘滩,低作堰,是李冰父子二千多年前,留给我们的深刻管理理念。同时代的巴比伦空中花园、罗马水渠、澡堂,已荡然无存。而都江堰仍然在灌溉造福于成都平原。为什么?

李冰留下“深淘滩,低作堰”的治堰准则,是都江堰长生不衰的主要“诀窍”。其中蕴含的智慧和道理,远远超出了治水本身。

华为公司若想长存,这些准则也是适用于我们的。深淘滩,就是不断地挖掘内部潜力,降低运作成 本,为客户提供更有价值的服务。客户决不肯为你的光鲜以及高额的福利,多付出一分钱的。我们的任何渴望,除了用努力工作获得外,别指望天上掉馅饼。公司短 期的不理智的福利政策,就是饮鸩止渴。低作堰,就是节制自己的贪欲,自己留存的利润低一些,多一些让利给客户,以及善待上游供应商。将来的竞争就是一条产 业链与一条产业链的竞争。从上游到下游的产业链的整体强健,就是华为生存之本。物竞天择,适者生存。

中国企业的大差距:不能完全职业化

我们从一个小公司脱胎而来,小公司的习气还残留在我们身上。我们的员工也受二十年来公司早期的习惯势力的影响,自己的思维与操作上还不能完全职业化。这些都是我们管理优化的阻力。

什么是职业化?就是在同一时间、同样的条件,做同样的事的成本更低,这就是职业化。但市场竞 争,对手优化了,你不优化,留给你的就是死亡。思科在创新上的能力,爱立信在内部管理上的水平,我们现在还是远远赶不上的。我们要缩短这些差距,必须持续 的改良我们的管理,不缩短差距客户就会抛离我们。

我们面对金融危机,要有管理改进的迫切性,但也要沉着冷静,减少盲目性。我们不能因短期救急或短期受益,而做长期后悔的事。不能一边救今天的火,一边埋明天的雷。管理改革要继续坚持从实用的目的出发,达到适用目的的原则。

在管理改进中,要继续坚持遵循“七反对”的原则。“坚决反对完美主义,坚决反对繁琐哲学、坚决反对盲目的创新,坚决反对没有全局效益提升的局部优化,坚决反对没有全局观的干部主导变革,坚决反对没有业务实践经验的人参加变革,坚决反对没有充分论证的流程进行实用”。

我们不要忌讳我们的病灶,要敢于改革一切不适应及时、准确、优质、低成本实现端到端服务的东 西。公司的运作虽然这些年已从粗放的运作,有了较大的进步。但面对未来市场发展趋缓,要更多的从管理进步中要效益。我们从来就不主张较大幅度的变革,而主 张不断的改良,我们现在仍然要耐得住性子,谋定而后动。

“投标,合同签订,交付,开票,回款”是贯穿公司运作的主业务流,承载着公司主要的物流和资 金流。针对这个主业务流的流程化组织建设和管理系统的建设,是我们长期的任务。由于我们从小公司走来,相比业界的西方公司,我们一直处于较低水平,运作与 交付上的交叉、不衔接、重复低效、全流程不顺畅现象还较为严重。DSO、ITO较业界同行还有较大差距,库存和资金周转的改善和E2E的成本降低有很大的 改进空间,是公司运作上深淘滩、低作堰的主战场,另一个业务流IPD是设计中构筑成本优势的主战场。

“灰色管理”是我们的生命之树

西方的职业化,是从一百多年的市场变革中总结出来的,它这样做最有效率。穿上西装,打上领 带,并非是为了好看。我们学习它,并非是完全僵化的照搬,难道穿上中山装就不行?我们二十年来,有自己成功的东西,我们要善于总结出来,我们为什么成功, 以后怎样持续成功,再将这些管理哲学的理念,用西方的方法规范,使之标准化、基线化,有利于广为传播与掌握并善用之,培养各级干部,适应工作。只有这样我 们才不是一个僵化的西方样板,而是一个有活的灵魂的管理有效的企业。看西方在中国的企业成功的不多,就是照搬了西方的管理,而水土不服。一个企业活的灵 魂,就是坚持因地制宜实事求是。这两条要领的表示,就是不断提升效率。

我们从杂乱的行政管制中走过来,依靠功能组织进行管理的方法虽然在弱化,但以流程化管理的内 涵,还不够丰富。流程的上、下游还没有有效“拉通”,基于流程化工作对象的管理体系还不很完善。组织行为还不能达到可重复、可预期、可持续化的可值得信赖 的程度。人们还习惯在看官大官小的指令,来确定搬道岔。以前还出现过可笑的工号文化。

工作组是从行政管制走向流程管制的一种过渡形式,它对打破部门墙有一定好处,但它对破坏流程 化建设有更大的坏处。而我们工作组满天飞,流程化组织变成了一个资源池,这样下去我们能建设成现代化管理体系吗?一般而言,工作组人数逐步减少的地方,流 程化的建设与运作就比较成熟。

我们要清醒的认识到,面对未来的风险,我们只能用规则的确定来对付结果的不确定。只有这样我 们才能随心所欲,不逾矩。才能在发展中获得自由。任何事物都有对立统一的两面,管理上的灰色,是我们生命之树。我们要深刻的理解、开放、妥协、灰度。深刻 理解深淘滩,低作堰带给我们的启迪。智慧的光辉,将千秋万代永不熄灭。

我们要继续发扬艰苦朴素的工作作风,英勇奋斗的牺牲精神,敢于自我批评,勇于改正自己的不足,天将降大任于斯人也。

 
2009-05-11 00:34

         1、堵车或等灯的时候别跟的太近,除非有人想加塞,至少要留出可以一把掰出去的距离,以防前车故障,自己也被加在中间。这是一个老司机告诉我的,当年他在3环就这样陪着前车呆了半个小时。

  2、排队时,为了防止别人加塞,在加塞来车一侧,多留半个车身。比如你在左转道排队,经常有人从直行道过来加塞,你尽量用右轮压着左转道的右边线开,给自己向左迂回留出余地,再跟紧前车,加塞的很难得逞。

  3、正常行驶时,前车突然并线给你让路,绝对没好事,咱们现在的司机还没这个觉悟,千万别给油超车,最好马上松油预备刹车,同时迅速观察两侧后视镜,判断出如果要并线往哪边并,八成前面有情况。

  4、当你从后视镜里看别的车有点费劲的时候,也就是你该开灯的时候了,不是为了看清道路,而是为了让别人看见你,尤其是白天下雨的时候!如果你愿意,时速超过100的时候也应该开灯,反正我是这么做的。

  5、加油的时候别加满了,40升的油箱加个35就行了,估计跑的公里数差不多,在航空领域这个现象叫“油耗油”,别白浪费钱,还污染环境。

  6、停车的时候,尽量将你的车头朝外,一个是走的时候方便,另外一个重要的功能就是防盗,虽然这不是灵丹妙药,但是如果我是贼,只有偷一辆车的机会时,我偷车头朝里的。

  7、开车并线的原则是,不要让后车踩刹车,这也是你作为行人过马路的原则,如果你让他为了避让你而踩刹车的话,他就有可能踩到油门上!

  8、过路口的时候一定一定要减速,不管他是不是绿灯,至少不能再加油了,尤其是没有交通灯的路口,在咱们国家,很多人是不珍惜生命的,别跟他们较劲!

  9、即便你是新手,也不要在高速公路上开的很慢,在4环5环上也一样,我经常走5环,经常看到很多大车为了超过一辆只有40公里/小时的轿车时 而强行并线,险象环生!大货车从起步到开起来非常的吃力,所以货车司机很不爱踩刹车,他宁愿并线超车也不原减速到3档再花10分钟加到5档。

  10、以我看来开车最危险的敌人不是开快车,而是分神!开快车的时候往往聚精会神,如果没有突发事件,一般不会出事,我不是在鼓吹开快车,10 次事故9次快,一旦出事就有生命危险的,最好是中速行驶!但我2年来几次吓出汗来的时候,都是在我走神的时候发生的,记得一次手机响了,我低头想看一下谁 的电话,等看清楚了打开接听时,一抬头,前车火红的刹车灯是如此的刺眼,最近的一次了,千万别走神!

  11、在人车混行的道路上,尽量离路边的自行车和行人远点,向路的中间靠,如果你没把握,不要紧别害怕,因为对面的来车会躲你,而行人和自行车是背对你的,不但不能躲你,说不定还会向你晃动,得给他们留出余地!

12、晚上行车的时候,不要用远光晃前方的行人和自行车,他们不懂的,不会给你让路的,你这么做只能使对面的车辆花了眼,不入直接的鸣笛。我经常能看到很多司机徒劳的用灯晃着行人,结果就是招来对面车辆刺眼的远光。

  13、下雨之后,走在你不熟悉的路段时,见到积水的坑,一定要减速,因为你不知道它有多深,最好是尾随一辆车,有一次我就是在路边停了一下,让后面的一辆超了过去给趟路的,并不耽误时间。

  14、如果在高速公路上遇到水洼,尽量躲开,千万别想看到水花四溅的壮观。如果躲不开,就尽量2个前轮一起压水,尽管高速上的水洼一般不会很深,但如果一边的轮子压上,会瞬时失去抓地力,如果速度很快,就会横甩出去,甚至翻车。

  15、如果你的车上坐了3个人以上,就别开的太快了,一是咱们的车排量小,人多了车就没劲了,提速会打很大的折扣,最重要的是咱们的刹车会变的比较迟钝,距离会明显的加长,刹车的时机和力度都要比平时来的早和狠。

  16、大家经常遇到赶灯的时候,如果你前面还有一辆车,那就算了,谁知道他会不会发什么神经停在线上,这样的事太多了,别跟的太近了,如果你是第一辆,那就别犹豫的过去,别加了半天的速,最后心虚了,一脚停在那里,后面来个追尾,虽然不是你责任,可是多别扭啊!

  17、停车超过3个小时后,再起步,一定要热车,无论春夏秋冬,这里的热车不是指水温,而是热你的润滑系统,至于水温,可以边开边热。

  18、停车后,车里别放什么东西,别以为不放钱包,电脑包就行了,就是半条烟,也可能搭上你的档风玻璃!

  19、有几个不能超车的原则要注意,拐弯的时候不能超,前方有路口的时候不能超,红灯变绿灯起步时,在没有完全通过路口时不要超,如果你想快点,就稍微往前探点,把路口的所有情况都看到,这时可以超。

  20、遇到大公共靠边进站,千万别高兴,以为它给你让了路,一定要减速,经常会有人从公共的前头跑出来,你可以通过观察大公共的车底有没有行人的腿脚或影子来判断。

  21、我经常开快车,违章被拍过数次了,基本上都是走紧急停车带或压导流带,但没有一次超速的记录,主要是因为我在过桥和铁架子的时候一定要减 速,一般超速的摄象头都装在立交桥,过街天桥或横跨马路的铁架上,而且一般都在行驶方向的背面,你可以通过观察对面车道上有没有探头,判断自己这里有没 有,但不是绝对的,想再保险一点,就走最外侧的车道,80%安装探头的也只是在内侧的快行道。

 
2009-04-29 14:12

魔术常量

1。__LINE__
返回文件中的当前行号。

2。__FILE__
返回文件的完整路径和文件名。如果用在包含文件中,则返回包含文件名。自 PHP 4.0.2 起,__FILE__ 总是包含一个绝对路径,而在此之前的版本有时会包含一个相对路径。

3。__FUNCTION__
返回函数名称(PHP 4.3.0 新加)。自 PHP 5 起本常量返回该函数被定义时的名字(区分大小写)。在 PHP 4 中该值总是小写字母的。

4。__CLASS__
返回类的名称(PHP 4.3.0 新加)。自 PHP 5 起本常量返回该类被定义时的名字(区分大小写)。在 PHP 4 中该值总是小写字母的。

5。__METHOD__
返回类的方法名(PHP 5.0.0 新加)。返回该方法被定义时的名字(区分大小写)。

魔术函数

1。__construct()
实例化对象时被调用,
当__construct和以类名为函数名的函数同时存在时,__construct将被调用,另一个不被调用。

2。__destruct()
当删除一个对象或对象操作终止时被调用。

3。__call()
对象调用某个方法,
若方法存在,则直接调用;
若不存在,则会去调用__call函数。

4。__get()
读取一个对象的属性时,
若属性存在,则直接返回属性值;
若不存在,则会调用__get函数。

5。__set()
设置一个对象的属性时,
若属性存在,则直接赋值;
若不存在,则会调用__set函数。

6。__toString()
打印一个对象的时被调用。如echo $obj;或print $obj;

7。__clone()
克隆对象时被调用。如:$t=new Test();$t1=clone $t;

8。__sleep()
serialize之前被调用。若对象比较大,想删减一点东东再序列化,可考虑一下此函数。

9。__wakeup()
unserialize时被调用,做些对象的初始化工作。

10。__isset()
检测一个对象的属性是否存在时被调用。如:isset($c->name)。

11。__unset()
unset一个对象的属性时被调用。如:unset($c->name)。

12。__set_state()
调用var_export时,被调用。用__set_state的返回值做为var_export的返回值。

13。__autoload()
实例化一个对象时,如果对应的类不存在,则该方法被调用。

 
2009-04-29 14:07
什么是 abstract class
PHP 5 引入抽象类和方法。抽象类不能被实例化。任何类只要包含有抽象方法(即使只有一个抽象方法)就必须也被定义为抽象。定义为抽象的方法只需要简单的声明而不用实现。
从抽象类继承的时候,所有父类中标记为抽象方法的声明都必须在子类中定义;此外,这些方法还必须用相同的(或更弱的)访问控制。比如,如果抽象方法定义为保护(protected),函数实现必须被定义为protected或者public

抽象类例子:
abstract class AbstractClass
{
// Force Extending class to define this method
abstract protected function getValue();
abstract protected function prefixValue($prefix);

// Common method
public function printOut() {
print $this->getValue() . "\n";
}
}

class ConcreteClass1 extends AbstractClass
{
protected function getValue() {
return "ConcreteClass1";
}

public function prefixValue($prefix) {
return "{$prefix}ConcreteClass1";
}
}

class ConcreteClass2 extends AbstractClass
{
public function getValue() {
return "ConcreteClass2";
}

public function prefixValue($prefix) {
return "{$prefix}ConcreteClass2";
}
}

$class1 = new ConcreteClass1;
$class1->printOut();
echo $class1->prefixValue('FOO_') ."\n";

$class2 = new ConcreteClass2;
$class2->printOut();
echo $class2->prefixValue('FOO_') ."\n";



什么是 interface
Object Interface 对象接口允许你创建这种代码,一个类必须实现的指定方法,而又不必定义这些方法如何处理。接口使用interface关键字定义,和标准类定义一样,但是任何方法都没有内容。接口内所有的方法声明都必须为公开(public),这是接口的本质(呵呵,所谓接口嘛,就是用于交互的)。
实现
要实现一个接口,使用 implements 操作符。接口中的所有方法都必须在一个类中实现;不这么做会导致一个致命错误(fatal error)。 如果想要的话,使用逗号分隔每个接口,一个类可以实现多个接口。
注意:一个类不能实现两个有同样函数名的接口,因为这导致这个函数的含义模糊。

接口的例子:
// Declare the interface 'iTemplate'
interface iTemplate
{
public function setVariable($name, $var);
public function getHtml($template);
}

// Implement the interface
// This will work
class Template implements iTemplate
{
private $vars = array();

public function setVariable($name, $var)
{
$this->vars[$name] = $var;
}

public function getHtml($template)
{
foreach($this->vars as $name => $value) {
$template = str_replace('{' . $name . '}', $value, $template);
}

return $template;
}
}

// This will not work
// Fatal error: Class BadTemplate contains 1 abstract methods
// and must therefore be declared abstract (iTemplate::getHtml)
class BadTemplate implements iTemplate
{
private $vars = array();

public function setVariable($name, $var)
{
$this->vars[$name] = $var;
}
}


实现多个接口:
class MyClass implements anInterface, anotherInterface {
//...
}


如果想要继承一个类并实现一个接口,先使用“extends”然后“implements”:
class MyChildClass extends MyParentClass implements MyInterface
{
// definition
}



interface 和 abstract class 的区别
PHP 5 中类没有多重继承,但可以实现多个接口。这应该是接口的主要用途。这点和Java类似,和C++不同。应该是学java,对多重继承的一种解决方式吧。

代码形式上来说,接口只是一个声明,其方法没有任何实现代码;抽象类的方法既可以没有实现代码,也可以拥有实现代码。
 
2009-04-26 10:42
使用python处理xmlrpc太简单了,又一次感受到了python的力量!
下面以使用python调用wordpress提供的xmlrpc方法为例简单介绍一下:

1) how to call xmlrpc method in python
>>> import xmlrpclib
>>> from pprint import pprint
>>> server = xmlrpclib.ServerProxy("http://localhost/wordpress/xmlrpc.php")
>>> pprint(server.system.listMethods() )

['system.multicall',
'system.listMethods',
'system.getCapabilities',
'demo.addTwoNumbers',
'demo.sayHello',
'pingback.extensions.getPingbacks',
'pingback.ping',
'mt.publishPost'......]

>>> blogs = server.metaWeblog.getRecentPosts('','admin','passwd',5)
>>> pprint(blogs)
>>> print(blogs[2]['permaLink'])

http://localhost/wordpress/?p=135

2)how to setup a xmlrpc server in python

import calendar, SimpleXMLRPCServer
#The server object
class Calendar:
def getMonth(self, year, month):
return calendar.month(year, month)

def getYear(self, year):
return calendar.calendar(year)
calendar_object = Calendar()
server = SimpleXMLRPCServer.SimpleXMLRPCServer(("localhost", 8888))
server.register_instance(calendar_object)
#Go into the main listener loop
print "Listening on port 8888"
server.serve_forever()

3)write a client to test server above
import xmlrpclib
server = xmlrpclib.ServerProxy("http://localhost:8888")
month = server.getMonth( 2002, 8 )
print month

August 2002
Mo Tu We Th Fr Sa Su
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

PS:
pprint means pretty print. A cool tool too.

Reference:
1 http://docs.python.org/lib/module-xmlrpclib.html
2 http://www-128.ibm.com/developerworks/library/ws-pyth10.html
3 http://groovy.codehaus.org/XMLRPC

http://zeaster.blogspot.com/2007/01/xmlrpc-for-python.html
 
2009-03-22 16:25
由于GBK编码的字节数不定长,所以直接替换会造成错误,比如"病、"符合全角空格,会被替换掉。
所以在替换前,先转码成utf8编码即可。下面两个方法是网上广为流传的函数,但是只支持utf8编码,稍微改进了一下,使得在gbk编码下同样好使,如果没有mbstring扩展,用iconv函数代替

// 方法1: 字节strtr掉所有的全角字符
function make_semiangle($str,$Encode="GBK"){
    if($Encode!='UTF8')$str=mb_convert_encoding($str,'UTF-8',$Encode);
    $arr = array(
       '0' => '0', '1' => '1', '2' => '2', '3' => '3', '4' => '4',
        '5' => '5', '6' => '6', '7' => '7', '8' => '8', '9' => '9',
        'A' => 'A', 'B' => 'B', 'C' => 'C', 'D' => 'D', 'E' => 'E',
        'F' => 'F', 'G' => 'G', 'H' => 'H', 'I' => 'I', 'J' => 'J',
        'K' => 'K', 'L' => 'L', 'M' => 'M', 'N' => 'N', 'O' => 'O',
        'P' => 'P', 'Q' => 'Q', 'R' => 'R', 'S' => 'S', 'T' => 'T',
        'U' => 'U', 'V' => 'V', 'W' => 'W', 'X' => 'X', 'Y' => 'Y',
        'Z' => 'Z', 'a' => 'a', 'b' => 'b', 'c' => 'c', 'd' => 'd',
        'e' => 'e', 'f' => 'f', 'g' => 'g', 'h' => 'h', 'i' => 'i',
        'j' => 'j', 'k' => 'k', 'l' => 'l', 'm' => 'm', 'n' => 'n',
        'o' => 'o', 'p' => 'p', 'q' => 'q', 'r' => 'r', 's' => 's',
        't' => 't', 'u' => 'u', 'v' => 'v', 'w' => 'w', 'x' => 'x',
        'y' => 'y', 'z' => 'z',
        '(' => '(', ')' => ')', '〔' => '[', '〕' => ']', '【' => '[',
        '%' => '%', '+' => '+', '—' => '-', '-' => '-', '~' => '~',
        ':' => ':', '。' => '.', '、' => ',', ',' => ',',
        ';' => ';', '?' => '?', '!' => '!', '…' => '-', '‖' => '|',
    '”' => '"', '’' => '`', '‘' => '`', '|' => '|', '〃' => '"',
    ' ' => ' '
    );
   
    //把需要转换的内容转码
    if($Encode!='UTF8'){
        $rp = implode("\t",array_keys($arr));
        $vp = implode("\t",array_values($arr));
        $tmp = $rp . "\n" . $vp;
        $tmp = mb_convert_encoding($tmp,'UTF-8',$Encode);
        list($rp,$vp) = explode("\n",$tmp);
        $rarr = explode("\t",$rp);
        $varr = explode("\t",$vp);
       
        $hash = array();
        foreach($rarr as $k=>$v){
            $hash[$v] = $varr[$k];
        }
        $arr = $hash;
    }
   
    $str = strtr($str, $arr);
    return ($Encode=='UTF8'?$str:mb_convert_encoding($str,$Encode,'UTF-8'));
}

//方法2: utf8编码下全角符号的范围是65280-65375,12288,全角和半角之间相差65248,空格除外
function SBC2DBC($str,$Encode='GBK'){
    if($Encode!='UTF8')$str=mb_convert_encoding($str,'UTF-8',$Encode);
    $ret='';
    for($i=0;$s1=$str[$i],$i<strlen($str);$i++){
        if(($c=ord($s1))&0x80){
            $s2=$str[++$i];
            $s3=$str[++$i];
            $c=(($c&0xF)<<12)|((ord($s2)&0x3F)<<6)|(ord($s3)&0x3F);
            if($c==12288){
                $ret.=' ';
            }elseif($c>65280&&$c<65375){
                $c-=65248;
                $ret.=chr($c);
            }else{
                $ret.=$s1.$s2.$s3;
            }
        }else{
            $ret.=$str[$i];
        }
    }
    return ($Encode=='UTF8'?$ret:mb_convert_encoding($ret,$Encode,'UTF-8'));
}

// test case

$str = "病、 !。,;";

$ret = SBC2DBC($str);
echo $ret . "\n";

$ret = make_semiangle($str);
echo $ret . "\n";
 
     
 
 
个人档案
 
 kevinchenkai
男, 25岁
加为好友
 
   
 
最新照片
 
   
 
订阅我的空间
 
已有人次访问本空间
 
订阅RSS  什么是RSS?

您也想拥有这样的空间?请点此申请。
     
 
最近访客
 
 

zqufeifei

fuliang_jlu

likepay

alex_wang58

ying雄410315

二默行者

ybbqy

niezxiang
     


©2009 Baidu