Saturday, November 22, 2008

find jobs

做HR专职招聘也有好几年了,最近感觉这个话题越来越热,因此也开一帖,从HR的角度谈些有关招聘面试的问题,也尽自己的能力给有这方面需要的版友们些建议,回答大家的问题,抛砖引玉,与大家交流。

第一个问题,面试中你的角色 

  招聘方和应聘方始终是一对矛盾,这毫无疑问,但这两者又何尝不是合作关系呢?试想有哪个做招聘的不希望又快又准得给自己的公司找到合适的人选,又有哪个应聘者不希望能尽快通过面试获得工作机会完成自己职业生涯的又一次跃进呢?所以,作为应聘者的我们千万不要从一开始就觉得HR是站在你的对立面的,如果你站错了队伍,你的面试基本上也就结束了。因为你将竭尽所能得去回避自身存在的、你认为可能会对工作有所影响的问题,而不是将自己的能力展现出来,所以在面试中最重要的工作是表现,而不是回避(To Show not to cover!)
 

  绝大多数应聘者在面试之前会做准备,看很多面试经验,我也看(HR也不傻,当然琢磨对方会怎么对付面试,呵呵)。这些所谓面经中有一条很重要的就是要你去弥补自己的短处,其实这是一个很大的误区。举例来说,我面试的很多应届毕业生跟我大谈自己的工作经验,甚至在哪家打字复印店打过字都说得像个项目管理工程;反过来,那些大专中专毕业,工作两三年,面试始终喜欢说自己自考本科在读,夜大在上,很快就要拿到**大学**文凭……实际上,这些基本上都是无用功,想想吧,公司为什么让你来面试?如果我需要一个有工作经验的,看了你应届毕业生的简历,我要你来面试干什么?我要找个学历高的,这年头,本科生硕士生满天飞,我约你来面试那肯定是我时间多的没地方打发了!

  
  所以,面试中最重要的就是表现你的优势,而不是弥补你的弱点,因为公司用人,只用人的长处,不是找三好学生,不是样样都优秀才算人才!

  
第二个问题,展现什么样的能力
 

  今天说在招聘面试时最需要展现什么样的能力,HR专业的说法非常复杂,什么能力模型、素质结构、职业倾向……同行之间讨论一下没问题,真拿到实际工作中,别说应聘者头晕脑涨,有时候连招人若渴的部门经理们都觉得不耐烦。

  1、展现你不可被培训的能力

  道理很简单,能力、素质分两种,可以培训的和难以培训的,你自己就完全可以判断。  

  测试:英语口语、能吃苦耐劳、诚实、善良、沟通能力,了解公司产品知识,公司所在行业熟悉程度、计算机能力、财务知识、工作主动性、协调能力、分析能力……试试看,区分一下,是不是很容易? 

 你是用人单位,你会把注意力主要放在哪儿呢?当然是不容易培训的能力!

  公司有培训部门,要做的事情就是针对员工有所欠缺的地方进行雕琢,所以,不要怕自己在可以培训的方面有缺点(比如对公司产品知识不了解等)。而更多的是要抓住自己所应聘职位所需要的难以被培训的能力。  

  2、展现你不可被替代的能力
 
  作为招聘者,我每天都在做选择题,在众多应聘者之间筛选出符合甚或是超出我们期望的那一个,而我每天看到的绝大多数简历都可以说是千人一面。最典型的是毕业生,英语四级(六级)、计算机二级(三级)、成绩优良(排名3/50)、连续n年获得奖学金、参加**学生组织、在**公司做过几个月的实习工作。这样的简历要多少有多少,换句话说,只要公司想招,随时有长龙排在门口,你成功的机会微乎其微。

  换个角度看着问题,为什么基层员工好找,部门经理、技术专家难招呢?原因在于替代性,你越容易被替代,你的价值也就越低,这就是法则。所以无论是简历还是面试,你得把自己独特的不可替代的能力表现出来,别告诉我没有,这不可能,不然你凭什么来应聘?

第三个问题,面试成功的要诀,你的预期=我的表现

  面试,英文叫做Interview,我认为含义完全不同。面试,当面进行考试,根据你的成绩客观给出评定,考出多少分是多少分,其目的是择优而用;interview翻译过来应该是面谈,会面,是一个沟通的过程,interviewer向应聘者就公司的业务状况,所能提供的职位详情进行传达,而 candidates向对方介绍自己的履历、能力、经验等各方面信息,从而让对方认识自己,进而了解自己。其目的是双方的契合,不是择高分而用,而是提供一个机会,让双方都能找到最适合自己的合作伙伴。 

  具体来说,interview之前,企业一定会对自己想招一个什么样的人来做这个职位分析,也就是HR理论中的所谓岗位分析(Job Description)。这个分析来源很广泛,由部门经理对这个职位的需求,有前任工作者给公司就这个职位留下的主观映像,甚至有客户对该职位人员的客观评价等不一而足。  

  所以,interview的结果没有所谓优秀、一般、差,只有suit or not suit。希望大家知道企业方的面试官(我们姑且沿用面试这一通行说法吧,不然有人该埋怨我说话夹杂英文了),在面试之前是带着期望来的!什么样的期望呢?简而言之,比前任更适合!如果前任做得不好,希望招到一个更好的,如果前任做得很好跳槽了,则希望招到一个更适合(稳定)的。 

  那么怎么才能做到让自己更适合公司的期望呢?

  1、研究对方的招聘广告,一般对方会在广告中写出职位的工作内容,任职要求。对比一下自己,如果对方写了大专以上学历,你是个硕士,就别去瞎起哄,耽误大家时间嘛这不是?如果对方写了三年以上工作经验,对方当然就不会想去从大学毕业生开始培养一个新手,基本条件都不合适,让你去面试,不是对方闲得实在无聊就是对方HR是个新来的菜鸟。

  2、面试中注意把握对方的心态,说俗点儿,听话听音,对方一国企,做财务,问你英语水平怎么样,就得多个心眼儿,工作用不着啊,就别天花乱坠的吹一通,没准儿你的前任就是英语好跳槽去了外企!这样上当的不能说不多,反正我常碰到。

  3、突出重点,我常碰到这样的应聘者,通常毕业一两年,会议室坐下,二话不说,从包里翻出一大堆本本,有多大桌他就能给你铺满了,英语的、会计的、贸易的、报关的、计算机的、营销的、管理的、公关的……看得我眼花,只有你想不到,没有他拿不出,介绍完了,我弱弱的问一句您应聘什么职位?答曰:"我觉得你们公司很好,外企,大品牌,心向往之不是一两年了,只要能进来,什么职位我还真不在乎!"我看他做我们总经理挺合适的……
 

第四个问题、面试中HR们的心态和对策

  我们不妨从HR招聘者的职责描述说起,简而言之,为企业寻找合适的人才。当然有许多限制:

  1、时间,招聘周期按照职位高低从两周到三个月不等,平均为一个月

  2、成本,招聘过程会发生很多成本支出,只要不是糊涂到花多少钱不在乎的地步企业一定非常关心自己招人花费几何

  3、招聘效果,也是最重要的,你找来的人是否能够在公司里做得好,做得久,公司个人各得其所,双赢为赢嘛 

  而这些限制本质上是矛盾的,又想招到最合适的人,又要快,又要省钱,压力当然巨大。所以,其实HR在看似怡然自得坐在面试桌另一边的时候,一般心里都处在这样的矛盾挣扎之中,一方面,心中期望自己对面坐的就是那个最佳人选,另一方面,又担心由于自己一时不慎,没看破对方小小的应试伎俩,被人结结实实的忽悠一把。

  这就是HR面试中的心态,针对这种状况的应对措施似乎我不该多谈,表现要不要好?当然要,而且在专业领域内要在众多面试者中首屈一指,但是面试经验我劝各位还是少看些比较好,你想,如果你碰到一个经验不十分丰富的HR,他所准备的问题你都有了比他还精准的答案,HR会得出什么样的结论呢?

  1、这人面试经验丰富,时刻准备跳槽,稳定性值得怀疑

  2、这人性格特点看不透,有待进一步观察,看看有没有更合适的人选吧 

  所以,回到最初的地方,面试的过程是展示,而不是去掩饰,你遮盖了一些东西,HR就会认为你有更多东西没有表现出来,进而对你整个表现的可信性产生怀疑,得不偿失啊!再说句到底的话,凭借面试经验是有可能糊弄一些半路出家的HR,可是你找到了工作事情就结束了吗?做起来发现这工作不适合你怎么办?发现工作对你的要求超出或明显地与你的能力不协调怎么办呢?最终结果还是要放弃,不如在面试时真诚沟通,让HR看透你点儿其实对你有帮助!

第五个问题,做一块过硬的敲门砖----简历

  制作简历,这一步看似简单,其实也是有些窍门的 

  三不写二多写一少写 

  大家猜一下,HR简历筛选时,阅读你的简历会用多长时间呢?十分钟?那是我一共就这一份简历,五分钟?一般候选人在面试前他的简历会被这样研究。一分钟?那是这封简历写得挺逗。正确答案,不会超过三十秒!这是我的自身经验,同行们的意见可能更少! 

  这么短的时间能阅读多大篇幅呢?注意我没说阅读多少字,最多两页A4。学校教育害死人呐,学生们的简历毫无例外的第一页是"求职信"。内容基本雷同,大体是大学生涯、母校光辉……除了校友和菜鸟,其他人是不会看的。你怎么才能让HR被你的简历吸引呢?切记,三不写二多写一少写! 

  不写未成年经历,做简历不是写生平,公司选人不是政府选国家干部。一般我们对你小时候的事情兴趣不大,小学、中学就读学校之类,没人会看。很多人觉得好像写了也无关痛痒,其实不然,这样的经历一般都出现在简历开头部分,看了一段这个,会严重影响HR看下去的意志力,那就亏大了!

  与工作本身不紧密相关的工作、学习经历不写,运气好,HR视而不见,运气不好,他们就会考虑,这个人能力挺杂啊,放我这儿不能人尽其才,来了也会跑! 

  不写自我评价和真正意义上的兴趣爱好,自己都评价完了,HR还评价什么呢?菜鸟会觉得你傲气,有经验的则不看,写了只有坏处没好处。如果你写的是与工作相关的兴趣爱好,(比如应聘采购地说喜欢逛街购物,应聘财务的说自己酷爱数钱之类,开玩笑啊,学生朋友可别当真),那没问题,如果你写的是我爱唱卡拉 OK、泡吧跳舞、打球打牌,我看算了吧。

  直接相关的工作经历要多写,你最能吸引公司的关键能力就是这条,能不多写吗?我看得很多简历都有很好的,甚至是我公司直接竞争对手公司工作经验,但非常可惜,就一句话"从****到****在****公司任职****,证明人***",你自己都认为你在这公司这几年的工作经验毫无亮点可说,怎么吸引别人呢?

  成功案例数据要多写,记住一句话,事实永远比空谈有说服力,什么样的事实呢?成功案例。其实根本不用你从头到尾地把整个案例背景、困难、压力、你的措施、执行、结果都写出来,你只要提纲携领地把事件描述一下就可以了。如果能多写出两三个成功案例,你这个人的能力还不跃然纸上?尤为重要的是数据,这是最有说服力的,比如,我要应聘一家公司的招聘经理我一定会列出数据,我多少年专职招聘经验,阅读**简历,组织过**次面试,招聘到经理级员工**,主管级**,其中**是通过**途径招到的,等等这样的数字,很快就会让你的描述可信度大幅上升。什么?你记不得了?Faint! 你不会根据自己的情况估算一下?唉

  参加的项目要少写,我看过不少这样的简历,作了**年销售,经验丰富,业绩优良,参加广交会,做成**项目,为企业创利几百万元……人才啊!赶紧回头看看薪资要求,RMB2500/month! 这人不是忽悠我吧,就算百分之一的奖金也有好几万呐!于是菜鸟说,骗人,扔!其实我知道,他确实是去参加了广交会,也正经八百的坐在了他们企业的摊位前面(旁边坐着项目负责人),生意谈下来了,说不定他还为了这笔生意拼了一回酒,闹了个现场直播呢!于是这也就成了他的经验,堂而皇之的写在了简历上。多大的误会!实在想写,您就提一句得了,记得说清楚了是参加  

第六个问题,投递简历,电话初识,你的第一印象 

  好了,现在我们有了一份合格吸引人的简历了,很多朋友开始满世界搜寻招聘信息,然后只要是符合自己专业或兴趣的二话不说就给他来一份,这样的简历投递方式有效吗?

  答案是否定的!投简历的过程非常容易被忽略,认为这其实是非常细小的问题。其实不然,这是整个应聘过程中你给公司的第一印象!心理学知识告诉我们,初见简历就像我们在生活中认识一个人,第一次见面留下的印象很大程度上决定着你是否愿意跟他交谈,而你投简历最直接的目的就是希望获得面试机会,你说这是不是重要?

  我在工作中平均每周收到几百封简历,真可谓无奇不有,说几个常见的例子吧。 

  有不少简历居然是cc给我的!什么意思呢?我给别人投简历,应聘任家单位的职位,听说你这儿也要招人?你也看看吧,如果那家公司我谈不拢,我们可以再聊聊。还能有比这更糟糕的第一印象吗?反正我注意到很多HR都是直接click delete……就想考大学第二志愿没人要一样,找工作,一般人家也不喜欢第二志愿的!所以,一封邮件只发一封简历ok?

  比cc好一点儿,有很多简历一眼看过去就知道不是给我一家公司的,e-mail内容整个儿一瓶红花油,哪儿都能抹。可能大家从网上找来这样的格式一看,不错,新鲜,找工作的信是这样写的啊!用了!可是,可怜可怜我们HR吧,你看了是新鲜,我们看了都要吐了,04年的时候,我记得网上出了个挺有名的求职信,你就看吧,应聘简历里面千篇一律,使用率高达33.33%,05年毕业生流行写诗,一时之间,学生诗歌蜂拥而至,有些还真是文采颇佳,读之怡情也就算了;有些打油诗,逗个乐子,还能忍受;狗皮不通的顺口溜也来凑热闹!晕啊,这又是什么样的第一印象呢?

  所以你的简历不能是应聘大军里的一个小兵,没人会注意大海里的一滴水的!要针对对方的招聘信息适当修改简历再寄出去。内容方面前文写过了,毋庸赘述,e-mail里面至少写上,短短两句话,如:近日通过**渠道,了解到贵公司正在招聘**职位,窃以为本人工作经历、专业特长颇为相合,特冒昧应聘**职位云云……别看这两句话简单,立刻你就甩掉了一大批人,那些只知道重复点发送键的人,你是认真考虑了公司职位要求和自身条件才投简历的!

另一种第一印象是电话约见,一般会由HR的人来做,内容大体上就是我们看了你的简历,认为你的基本条件是符合我们职位要求的,希望你能在某日来公司参加面试……看似简单,但其实应聘者的表现也还是有高低参差之别的。 

  接电话的技巧,不好的印象类型有三种:前倨后恭、不知所云、太过依赖。 

  前倨后恭,中华礼仪之邦,向来是以理为先的,可是偏偏倒了现代,似乎崇礼之风日下,表现在电话这个看不见对方的场合里尤为过分。英文接电话用 hello也就是你好,跟日常朋友见面打招呼的言语一样;再看我们,居然创造性的发明了个"喂",这其实非常不礼貌,你想,谁在路上跟别人打招呼直接喊声"喂"的啊?更有甚者,这一声"喂"的语气有多种含义表达(感谢祖先发明的四声),可以表示应答、疑问,这还说得过去,还可以表示质问、挑衅、不耐烦,这给人的第一印象就不能再坏了!有点啰嗦,实际情况是这样的

  "喂!"

  我:"你好,是***吗?"

  答:"是啊,你谁啊?"

  我:"我是**公司的,你是不是给我们公司投了简历?我们觉得你条件不错想请你来面试。"

  答:"噢,是的是的,不好意思,不好意思,在开会(上课,吃饭,车上,等等借口不计其数)。"

买房建议

1.资料搜索; `7 N: s- _2 C* i5 e
买房前一定要进行大量的资料搜索,对房屋的一些基本知识需要掌握,比如什么是LIM, 什么是CCC等(很多中介包括洋人对此也不一定精通),还要对自己所中意的区进行调查,有些时候需要周末晚上多次去所中意房子前蹲点,以确定是否安全和安静(周末晚上有些区常常有人赛车,也许你看的房子离可赛车的路段比较远,但晚上很安静,声音传得很远,所以蹲点是很必要的), 另外,如果你不确定此区是否安全,去警察局调一下当地犯罪率档案是很有帮助的。还有最好有一个以上的区备选。
* K: j1 Q$ p( n4 R0 a2.关于中介
* i; X7 U) k4 L个人推荐不要绑定中介,最好是看见哪个房子不错就去找那个房子的中介或直接去房子的openhome,这样可以增加房子的选择范围和自身便利(当然,这中间不包括有语言障碍的朋友)。中介只是买卖双方的纽带,一旦你自己资料搜集的足够,你就知道要找什么房子,要看什么问题,要提什么问题,中介不会主动帮你搜索所有适合你的房子,大多时候是罗列list让你自己挑选,如果你不问得话,一般他们也不会给你提供太多其他资料。% R8 u, v- I: i6 {8 F2 i+ p
7 f8 ]9 p& D+ L8 T0 ]# ^" `
3. 关于房子选择的建议
8 A$ L. `! m$ F建议大家谨慎对待Plaster和木料外墙的房子(不包括weatherboard),因为其材料特性和建筑方式, 因此时间长比较容易造成漏水或墙体损坏,这类房子,特别是plaster的修葺费用极其高,购买此类房子,需要有这方面专家来做check. 砖外墙的房子比较推荐,维护费用低,结构发生变化的几率相对小, 还有一些其他材料也不错,这里就不多说了.
/ d. g: E" T* y9 y另外,房檐也是个大而且比较容易忽视的问题, 一般最好买房檐能大大超过和遮盖外墙和窗户的房子,不要买房檐和外墙及窗户基本在一个平面的,因为这边房屋的特殊建筑结构和多风多雨的气候,大的房檐能最大限度的保证雨水不会通过房檐和外墙缝隙进入房子,不会长时间侵蚀墙壁和窗户的缝隙, 以确保房屋不漏水. 漏水房屋已经是新西兰民宅最大的威胁,它的修复费用非常昂贵,而且一旦你的房子有漏水纪录,就没人愿意买了.
9 b) W! \+ I+ p4 u# O
9 c2 F3 |% Q2 }; O4.必要的Builder & Lawyer(建议决定要买房的朋友提前找好他们)当你有中意的房子后,下面就是要Builder出场了,他是很重要的,最好找洋人比较大的专业房屋评估公司(house inspection company),他们会按照你的要求帮你check LIM,也就是到city council 查你房子的合法性,文件的完整性,有无改建,扩建,是否有必要批文(有时候你可以要求house owner 提供lim, 自己复印还是很贵的, Ps. lawer也做lim check,但个人认为bulider好一些,因为他会去实地看房子,以确定房屋现状和council记录相符,lawyer就坐在屋里收钱), 另外肯定也一定要builder给你做house inspection, 他会实地给房子做外观检查,确定有无大问题,比如漏水,有霉等,就算找到小的问题,你也可以要求房主在交房前修复或给你相对折扣。Builder check 一般在递完“有条件合同“后做,此点下面会谈到。Lawyer 也很重要,虽然他们都一直坐在屋子里收钱,但可以帮你查lim, 最重要的还有对方房主的合法性,是否有贷款,是否有不良债务和房屋挂钩,以确定交易合法顺利的进行,这里需要找有责任的律师,当然能讲中文或有中文翻译的优先,这个道理就不用说了吧:)。
; s3 }/ T% _: ?% }" n
5 I: o+ L' k; r9 C& g P5.Why “conditional offer” " H% K, w/ \* G' s9 [4 V& E1 u
有条件合同是必要的,其中的条件可包括: Finance, Lim check, builder report , 交房日期等你觉得需要的, 为什么呢? 其实还是为了保护你自己的权益(这也是kiwi最长用的).5 T/ H# `0 T, q3 A

& K2 }1 _1 r3 e% g+ W* OFinance: 一旦你有它,在整个合同期,如果你单方面出现买房困难或改变主意,可以用finance problem取消合同,增加了自己的灵活度和安全性.; S# c& V$ u- w$ w% _

+ H5 [+ n; w/ l2 t0 E' H0 B$ Q; YLim check, builder report: 前面说过了,一个是看房子修建的合法性,如果有问题,当然不能买,另一个是看房子的现状,有大问题,也不能买,就是有小毛病,也可以要求房主修葺或降价. 在这里补充一点, 最好不要找bulider朋友帮忙看,特别是当你买相对比较贵的房子时,你checking fee是省下了,但是万一有问题谁负责,一些比较大的专业房屋评估公司同时还对其检查合格的房子提供一年或更久的保证,也会给你的房屋保险公司提供担保,所以一旦有问题(指质量),他们会负责.8 ^* _9 F/ z7 Z% ~3 @, F$ N

8 J% S4 L, Q4 o* ^. }6. GV or CV 误区
7 W; h: u8 c2 S5 h' sGV or CV 是政府为收地税而给房屋的估价, 两个是同一个东西不同时期/年代不同的叫法而以, 没有区别. GV or CV 具有一定的价格指导意义, 但决对不是准确的市场估价,有很多房子的GV or CV都比实际市场价格高( 可以理解,政府想多收钱嘛),所以千万不要被一些类似 “will below GV or CV” 的广告迷惑,最好和同一区域相似的房子进行比较, 如果还不放心,就请专业估价公司对房屋做valuation report.
0 X/ u/ [' ]" ~+ f5 B5 k# ]# q! J Q9 n3 x' \# ^/ W
7.买房的心情
7 ]2 D! B O8 |# ]/ O0 z买房一定不能着急,能理解很多人看中中意房子时患得患失的感觉,但是一旦因为这个原因造成的急促合同(特别是拍卖,如拍卖前没做好调查,一旦拍卖成功,就要接受房子所有的现状)很容易造成失误. 现在是买方市场,个人估计从现在到明年下半年都应该是买入的好时期,不如慢慢看,一定能拿到便宜质量又好的房子,所以心态很重要哦!

Friday, November 21, 2008

字符串处理函数库

AddSlashes: 字符串加入斜线。
bin2hex: 二进位转成十六进位。
Chop: 去除连续空白。
Chr: 返回序数值的字符。
chunk_split: 将字符串分成小段。
convert_cyr_string: 转换古斯拉夫字符串成其它字符串。
crypt: 将字符串用 DES 编码加密。
echo: 输出字符串。
explode: 切开字符串。
flush: 清出输出缓冲区。
get_meta_tags: 抽出文件所有 meta 标记的资料。
htmlspecialchars: 将特殊字符转成 HTML 格式。
htmlentities: 将所有的字符都转成 HTML 字符串。
implode: 将数组变成字符串。
join: 将数组变成字符串。
ltrim: 去除连续空白。
md5: 计算字符串的 MD5 哈稀。
nl2br: 将换行字符转成

Ord: 返回字符的序数值。
parse_str: 解析 query 字符串成变量。
print: 输出字符串。
printf: 输出格式化字符串。
quoted_printable_decode: 将 qp 编码字符串转成 8 位字符串。
QuoteMeta: 加入引用符号。
rawurldecode: 从 URL 专用格式字符串还原成普通字符串。
rawurlencode: 将字符串编码成 URL 专用格式。
setlocale: 配置地域化信息。
similar_text: 计算字符串相似度。
soundex: 计算字符串的读音值
sprintf: 将字符串格式化。
strchr: 寻找第一个出现的字符。
strcmp: 字符串比较。
strcspn: 不同字符串的长度。
strip_tags: 去掉 HTML 及 PHP 的标记。
StripSlashes: 去掉反斜线字符。
strlen: 取得字符串长度。
strrpos: 寻找字符串中某字符最后出现处。
strpos: 寻找字符串中某字符最先出现处。
strrchr: 取得某字符最后出现处起的字符串。
strrev: 颠倒字符串。
strspn: 找出某字符串落在另一字符串遮罩的数目。
strstr: 返回字符串中某字符串开始处至结束的字符串。
strtok: 切开字符串。
strtolower: 字符串全转为小写。
strtoupper: 字符串全转为大写。
str_replace: 字符串取代。
strtr: 转换某些字符。
substr: 取部份字符串。
trim: 截去字符串首尾的空格。
ucfirst: 将字符串第一个字符改大写。
ucwords: 将字符串每个字第一个字母改大写。

Wednesday, November 19, 2008

Styling an input type="file"

Of all form fields, the file upload field is by far the worst when it comes to styling. Explorer Windows offers some (but not many) style possibilities, Mozilla slightly less, and the other browsers none at all. The "Browse" button, especially, is completely inaccessible to CSS manipulation.

The problem


For a site I created I needed input fields like this one:


The designer wanted the same styles, plus a "Select" image, to apply to all file upload fields. When I applied the rules of normal input fields to file upload fields, though, it didn't really work. There were wild differences between the browsers, and styling the default button is totally impossible.


Ponder the differences.

Screenshot: File input fields in the various browsersFile input fields in the various browsers


This is hardly what anyone would call a nicely designed form field. Until recently, though, it was the best we could do.


Also note Safari's fundamentally different approach. The Safari team has probably decided on this approach to disallow the manual entering of a file name and this avoid exploits like this one. The drawback is that the user can't decide not to upload a file after having selected one.

The solution


Fortunately, reader Michael McGrady invented a very neat trick that allows us to (more or less) style file upload fields. The credits for the solution presented on this page are wholly his, I only added the position: relative, a few notes and tests, and ported it entirely to JavaScript.


Without the technique your browser reacts like this:


Using McGrady's technique, I was able to produce this file upload field:


Now that looks much better, doesn't it? (Provided your browser supports opacity)


McGrady's technique is elegant in its simplicity:


1. Take a normal <input type="file"> and put it in an element with position: relative.

2. To this same parent element, add a normal <input> and an image, which have the correct styles. Position these elements absolutely, so that they occupy the same place as the <input type="file">.

3. Set the z-index of the <input type="file"> to 2 so that it lies on top of the styled input/image.

4. Finally, set the opacity of the <input type="file"> to 0. The <input type="file"> now becomes effectively invisible, and the styles input/image shines through, but you can still click on the "Browse" button. If the button is positioned on top of the image, the user appears to click on the image and gets the normal file selection window.

(Note that you can't use visibility: hidden, because a truly invisible element is unclickable, too, and we need the <input type="file"> to remain clickable)


Until here the effect can be achieved through pure CSS. However, one feature is still lacking.


5. When the user has selected a file, the visible, fake input field should show the correct path to this file, as a normal <input type="file"> would. It's simply a matter of copying the new value of the <input type="file"> to the fake input field, but we need JavaScript to do this.


Therefore this technique will not wholly work without JavaScript. For reasons I'll explain later, I decided to port the entire idea to JavaScript. If you're willing to do without the visible file name you can use the pure CSS solution. I'm not sure if this would be a good idea, though.

The HTML/CSS structure


I've decided on the following HTML/CSS approach:


div.fileinputs {

position: relative;

}


div.fakefile {

position: absolute;

top: 0px;

left: 0px;

z-index: 1;

}


input.file {

position: relative;

text-align: right;

-moz-opacity:0 ;

filter:alpha(opacity: 0);

opacity: 0;

z-index: 2;

}


<div class="fileinputs">

<input type="file" class="file" />

<div class="fakefile">

<input />

<img src="search.gif" />

</div>

</div>


The surrounding <div class="fileinputs"> is positioned relatively so that we can create an absolutely positioned layer inside it: the fake file input.


The <div class="fakefile">, containing the fake input and the button, is positioned absolutely and has a z-index of 1, so that it appears underneath the real file input.


The real file input field also gets position: relative to be able to assign it a z-index. After all, the real field should be on top of the fake field. Then we set the opacity of the real file input field to 0, making it effectively invisible.


Also note the text-align: right: since Mozilla refuses a width declaration for the real file field, we should make sure that the "Browse" button is at the right edge of the <div>. The fake "Search" button is also positioned at the right edge, and it should be underneath the real button.


You'll need some subtle CSS to set all widths, heights, borders and so on, but I didn't include it in this code example. View the source of this page to study my approach in this particular case; your pages will be different, though, so you'll have to change these values.

Why JavaScript?


Nonetheless, I decided to go for a strict JavaScript solution. My first reason is that we need JavaScript anyway to copy the file path to the fake field.


Secondly, a JavaScript solution would avoid meaningless extra HTML: the <div class="fakefile">. It'd keep my code cleaner.


Finally, older browsers can't really handle the CSS, down to the point that the file input becomes inaccessible in Netscape and Explorer 4. As to users of no-CSS browsers, they'd see two input fields, and wouldn't understand what the second one was for.


Below is a pure CSS solution:

Browse


Some browser screenshots will further explain the accessibility issues.

Problems - Netscape 4


First Netscape 4. As you see, the user sees only the button. This may be because the form is spread across two layers by my use of position: absolute, and Netscape 4 can't handle that.


Worse: the user can't click on the button. Maybe an extensive week long study would reveal a partial solution to this problem, but frankly I can't be bothered. Nonetheless, the field must be accessible to Netscape 4 users.

Screenshot: How it looks in Netscape 4How it looks in Netscape 4

Problems - Explorer 4


Explorer 4: an odd shadow of the original "Browse" button, and it's not clickable, either. The solution is inaccessible in Explorer 4.

Screenshot: How it looks in Explorer 4How it looks in Explorer 4

Problems - Netscape 3


Finally, users of Netscape 3, or any other non-CSS browser. The field is still accessible, but users will quite likely be confused by the extra input field.

Screenshot: How it looks in Netscape 3How it looks in Netscape 3

Solution - JavaScript


The solution to all this nastiness is simple: generate the fake input and button through JavaScript. Now, the worst that can happen is that the script doesn't work, in which case the user only sees the real <input type="file">. Less beautiful, certainly, but still accessible.


So the hard coded HTML is reduced to:


<div class="fileinputs">

<input type="file" class="file">

</div>


We'll add the rest of the elements through JavaScript.

The script


So I wrote the following script:


var W3CDOM = (document.createElement && document.getElementsByTagName);


function initFileUploads() {

if (!W3CDOM) return;

var fakeFileUpload = document.createElement('div');

fakeFileUpload.className = 'fakefile';

fakeFileUpload.appendChild(document.createElement('input'));

var image = document.createElement('img');

image.src='pix/button_select.gif';

fakeFileUpload.appendChild(image);

var x = document.getElementsByTagName('input');

for (var i=0;i<x.length;i++) {

if (x[i].type != 'file') continue;

if (x[i].parentNode.className != 'fileinputs') continue;

x[i].className = 'file hidden';

var clone = fakeFileUpload.cloneNode(true);

x[i].parentNode.appendChild(clone);

x[i].relatedElement = clone.getElementsByTagName('input')[0];

x[i].onchange = x[i].onmouseout = function () {

this.relatedElement.value = this.value;

}

}

}


Explanation


If the browser doesn't support the W3C DOM, don't do anything.


var W3CDOM = (document.createElement && document.getElementsByTagName);


function initFileUploads() {

if (!W3CDOM) return;


Create the <div class="fakefile"> and its content. We'll clone it as often as necessary.


var fakeFileUpload = document.createElement('div');

fakeFileUpload.className = 'fakefile';

fakeFileUpload.appendChild(document.createElement('input'));

var image = document.createElement('img');

image.src='pix/button_select.gif';

fakeFileUpload.appendChild(image);


Then go through all inputs on the page and ignore the ones that aren't <input type="file">.


var x = document.getElementsByTagName('input');

for (var i=0;i<x.length;i++) {

if (x[i].type != 'file') continue;


Yet another check: if the <input type="file"> does not have a parent element with class fileinputs, ignore it.


if (x[i].parentNode.className != 'fileinputs') continue;


Now we've found an <input type="file"> that needs tweaking. First we add "hidden" to its class name. I add the advanced styles (opacity and positioning) with this new class, since they might conceivably cause problems in old browsers.


x[i].className = 'file hidden';


Clone the fake field and append it to the <input type="file">'s parent node.


var clone = fakeFileUpload.cloneNode(true);

x[i].parentNode.appendChild(clone);


Now we've succesfully styled the <input type="file">. We're not yet ready, though, we have to make sure the user sees the path to the file he wants to upload.


First we create a new property for the <input type="file"> that points to the fake input field:


x[i].relatedElement = clone.getElementsByTagName('input')[0];


We use this to easily access the fake field as soon as the user changes the real <input type="file"> (ie. selects a file), so that we can copy its value to the fake input field.


A problem here, though: which event do we use? Most natural would seem the change event of the file field: if its value changes, the fake input field's value should also change.


Unfortunately Mozilla 1.6 doesn't support the change event on file fields (Firefox 0.9.3 does, by the way). For Mozilla's sake I also use the mouseout event, which conveniently fires only after the user has selected a file. (This also works in Explorer, but not in Safari)


x[i].onchange = x[i].onmouseout = function () {

this.relatedElement.value = this.value;

}


Problems and extensions


One problem remains: the user can't choose not to upload a file after all.


Suppose the user selects a file, then on second thought decides not to upload it. In a normal <input type="file"> he can simply remove the path, and the file won't be uploaded. In our example, though, this is very difficult. Try it, it can be done, but it's totally counter-intuitive.


So what we'd like to do is allow the user to select and modify the content of the fake file upload and copy all changes to the real file upload.


Allowing selection is somewhat possible. When the user selects any part of the real file upload, we select the entire value of the fake file upload.


x[i].onselect = function () {

this.relatedElement.select();

}


Unfortunately, JavaScript security does not allow us to change the value of an <input type="file">, so we can't let the user manually change the fake input. Therefore I decided to entirely leave out the onselect event handler.


A possible solution would be to add a "Clear" button to the fake input, which triggers a script that entirely trashes the <input type="file"> and creates a new one. It's a bit cumbersome, but we might be able to remove the chosen file entirely. I didn't write that part of the script, though, so I'm not sure if it would actually work.

Route the click event


A reader proposed to remove all the complicated CSS stuff, totally hide the file upload field, and route all click events on the fake upload field to the real one. An excellent idea, and much simpler than the one described above.


fakeField.onclick = function () {

realField.click()

}


The click() method allows you to simulate a click on a form field. Checkboxes get toggled, radios selected, and so on. Unfortunately Mozilla and Opera haven't added this method to file upload fields. I wonder why, adding it is not really a security risk since the worst that can happen is that the file selection window pops up.


So unfortunately we cannot use this simple solution.

Sunday, November 2, 2008

ereg正则表达式的用法!

语法: int ereg(string pattern, string string, array [regs]);
传回值: 整数/阵列
函式种类: 资料处理
本函式以 pattern 的规则来剖析比对字串 string。比对结果传回的值放在阵列参数 regs 之中,regs[0] 内容就是原字串 string、regs[1] 为第一个合乎规则的字串、regs[2] 就是第二个合乎规则的字串,余类推。若省略参数 regs,则只是单纯地比对,找到则传回值为 true。


通常上, 正则表达式会用到以下的几个"符号":
^ - 代表字串前面一定要有这样的字, 如^http://, 代表前面一定要有http://
$ - 代表字串后面一定要有这样的字.
? (一个问号) - 它代表一个或没有字元
* (一个*) - 它代表没有或者更多前面的字元
. (一个句点) - 它代表任何一个字元
+ (一个加) - 它代表至少一个或更多前面的字元
[xyz] - 它代表任何一个字元, 或x, 或y, 或z
[a-z] - 它代表任何一个字元, 由a至z
[[:alnum:]] - 代表由a至z, 0至9
[[:digit:]] - 代表由0至9

当使用正则表达式时, 必需注意ereg及eregi可大大不同喔~
ereg是非常敏感的 (意即大小字母都分得非常清楚), 而eregi则不是 (只要记着i代表case-insensitive就可以了)

这里举一些例子:

$regexp = eregi("a?c", "abc"); //-- 这是对的, 因?可以代表"一个"或没有字元
$regexp = eregi("a?c", "ac"); //-- 这也是对的, 因?可以代表一个或"没有"字元
$regexp = eregi("a?c", "a"); //-- 这样就不对了, 纵使有a, 可是还是要有c

$regexp = eregi("[abc]", "a"); //-- 这是对的, 因a是大括号里的其中一个字元
$regexp = eregi("[a-z]", "c"); //-- 这是对的, 因c包括在a至z里
$regexp = eregi("[a-z]", "0"); //-- 这是不对的, 因0并不包括在a至z里面

$regexp = eregi("a.c", "abc"); //-- 这是对的, 因一个.代表"任何"一个字
$regexp = eregi("a.c", "ac"); //-- 这可就不对了, 因.代表"一个"字元, 所以放abbc也是不对的

$regexp = eregi("a+c", "aaaac"); //-- 这是对的, 因+代表一人或"更多"前面的字元
$regexp = eregi("a+c", "abbc"); //-- 这样是不对的, +代表一个或更多"前面的字元", 而不是代表任何一个字元
$regexp = eregi("a+c", "abc"); //-- 这样也是不对的, 注释如上

$regexp = eregi("[^abc]", "a"); //-- 这是比较不同的一点, 那就是如果^出现在[]里面, 代表"除"了里面的字, 全部都是对的.
$regexp = eregi("[^abc]", "d"); //-- 这是对的, 因d并不在abc里面
$regexp = eregi("[^[:alnum:]]", "9"); //--这是对的, 因~并不包括在a至z, 0至9里面
当然, [[:digit:]]用法也是相同:
$regexp = eregi("[^[:digit:]]", "a"); //-- 这是对的, 因a并不包括在0至9里面

最后, 举个有用的例子,
比如说, 我要每个人的密码都不准拥有0至9, 可以这样试验:
$regexp = eregi("^[^0-9]+$", "aaa9"); //--把aaa9当做密码
if ($regexp == "") {
echo "密码拥有号码, 请改过";
} else {
echo "密码没有号码, 通过";
}

测验显示, 密码拥有号码, 请改过.
相信每个人都看到, [^0-9]前后各有^及$, 这是为了确保前后不能拥有号码, 而+则确保中间没有任何的号码,
[]里面的^, 则是"除了0至9之外, 其他一律通过"
所以只要将9拿去, 就会显示"密码没有号码, 通过"了 !