手机浏览 RSS 2.0 订阅 膘叔的简单人生 , 腾讯云RDS购买 | 超便宜的Vultr , 注册 | 登陆
浏览模式: 标准 | 列表全部文章

向东的工作周报(2月 20 日-4月2日)

从名字可以看出来,这是向东的工作周报。不过,他的这一周,好长啊。。。其实是他每周的工作情况的简报啦。
这个习惯真好,我就没有养成。

他的第一个问题,我在以前与java那边交互的时候就遇到过,开始也是一直判断一直判断。最后发现获取的就是字符串,都跨语言了,还是用的curl来取值的,怎么可能传递布尔值?

最后它说的BOM问题,这就不太应该了。不过他的正则写得不错。我一直用editplus,文件选项里可是有一条:保存时始终去除BOM,就行了啦。用记事本,是会生成BOM的,微软的东西是差呀。。

框架这东西,仁者见仁智者见智,不多分析


原文如下:http://www.xiangdong.org/blog/post/1699/

近半年的工作心得,摘录如下:
(    2月 20 日--   2月  26  日)
工作心得
一.Ajax通过POST提交给$_POST数组变量问题:
和 js人员一块调试ajax提交一些数据的时候,在ajax调用的时候,js人员通过Post方式传给我一个'allowComment',它为 True\false,刚开始误以为是一个TRUE 或 FALSE是PHP里面的一个布尔值(实际是一个字符串),于是写下如下代码片段:
if(true ==  $_POST['allowComment'])
{
  $this->_par['allow_comment'] = 0;//0为允许评论

}else
{
  $this->_par['allow_comment'] = 1;
}
导 致出现无论post过来的数据是true还是false,只走if不走else,当时很奇怪,我通过print_r()来打印看到明明是false,但是 还是不走else这条路,最后听建鑫说它是个字符串,我于是改用var_dump()函数来看:var_dump($_POST)发现它其实就是个 string类型的字符串:string(4) "ture",不是布尔型的一个变量。而修改为:(引号引起来即可)
if(‘true’ ==  $_POST['allowComment'])
{
  $this->_par['allow_comment'] = 0;//0为允许评论

}else
{
  $this->_par['allow_comment'] = 1;
}
结论:尽管PHP是弱类型语言,但我们调试时候最好用var_dump(),而不是print_r();
二.DIV模板取高度自动适应的问题:
在 做这次记录套页面的时候,提供的页面是一整张页面,这就需要php工程师去去掉里面的一些没有用的DIV标签和多余的html代码,但是在把最后剩下的一 些HTML代码套好页面后,在放到pengyou里面测试时候,发现页面被遮挡,最后发现是由于刘嵩Js想取到一个DIV的高度没有得到正确的值,而这正 是由于HTML设计人员把一整张页面让PHP开发人员去从里面提取出需要的东西,但是往往会出现某些DIV没有带到Smarty页面里渲染,才导致js在 通过ID或者NAME去取高度时候出错,也就是PHP工程师套页面的时候并不知道UI提供的页面中哪些DIV是JS人员必须要的,而UI人员就把整个页面 给PHP工程师自己去剔掉多余的DIV和HTML,而刚好把JS需要的DIV给干掉了造成的.
结论:切页面得按照产品结构来,而不是仅仅UE,涉及到JS的得事先和PHP工程师和JS人员沟通。
三.接口变动问题:
一 些底层接口的变动往往造成输入(入数据库)和输出(如:页面)出现一些明显的逻辑错误,于是我们首先会想可能是不是程序逻辑出现了问题,进一步去查程序代 码的逻辑是否严密,会发现数据库里面出现一些和现实逻辑不同的情况,而很容易把陈脚搞乱,特别是有其它系统的介入,更让人很难发现其中错误。
结论:尽量少动接口返回的数据结构,保持结口稳定,而一旦改变,及时通知接口使用和开发方。

(    3月 6 日--   3月  12  日)

工作心得
对重构的一点体会:

1.改进软件的结构:
在开发记录的时候有时由于一个新的需求导致为了更快的满足用户,不故到程序的整体结构,而这种解决方法不能以一个系统的角度来解决问题,如果任其发展会使代码的质量越来越难以维护,而重构能改善这个问题。

2.增加可读性:
以 前的记录的数据层是由外包人员写的,让我觉得有点难懂,而有人说,修改别人的代码不如自己写,但事实上往往自己写的代码比上一个人还难以让别的人读懂,但 是如果这个人有一天离职或者没有上班那就有些耗费时间去读懂对方的代码,而我们的重构可以通过一些命名规范和类的规范和层次结构的规范来尽量防止这类事情 的发生,仅管我也参考了他们的代码。

3.及早地发现错误:
进行重构我们必须对项目的每一行代码的逻辑都了解,明确它的功能和上下程序调用关系,这样的理解我觉得有助于少犯错误和及时发现自己的错误。

4.提高了开发速度:
知道用户80%的需求的情况下,这种情况下重构,可能从一定程度上能提高开发速度。
(    3月 13 日--   3月  19  日)
遇到一问题
   在对记录的项目中进行重构的时候发现需要通过Ajax多提交一个POST变量到PHP那边去,发现不能随意加,而和js开发人员沟通了一下,结果是必须得 修改一下js代码,把多提交的一个加进去才行,但是我个人觉得js的Ajax Post应该做得像表单提交数据那样,只要多加一个数据<input type="text" value="add_value" name="XXX" id="XXX" />加入<form>
</form>表单,就可以对它POST提交到另一个PHP文件,而不是仅仅对一个单独的应用而写一个Ajax Post提交数据 ,不知能否改进成这样?

工作心得
1.
  做项目最好先了解需求,然后明确需求,再思考用例,然后画数据流,最后才是数据库的设计,当然最后的数据库设计也是最重要的!
2.
  对于一些定义分级和对应级别的少量数据最好放到PHP数组里面,而尽量不要放到数据库里,而对一些不是经常改动而却又是经常频繁查询用到的数据在量不是很在的情况下如放到数据库里面会显得成本太高,放到一个文本里变为一个配置文件来用效率可能会反而更高。
3.
  对 大并发和高访问的数据库设计解决方法现目前还是分表,如还不行,再Hash打散分库,但不能无限分,一个库尽量256表,动用4个库来也就分了1000个 表左右,建鑫的经验告诉这样可能性能和稳定性相对高一些,而不能随意乱分。不知按时间或者天数来分表这种情况会有什么样的问题,期待通过人缘项目来尝试一 下。


2009-03-20 ----2009-03-26:
遇到一问题
工作心得
对于上次邮件里面讨论到的PHP BOM问题,我来说来句就当心得吧,其实这个BOM问题一直在我们进行开发的时候经常出现,前些日子在企业邮箱里面第一次遇到这个问题,当时好像是企业的图标LOGO没有办法显示出来,因为<img alt="" src="http://www.xiangdong.org/blog/img.php" />,是img.php去读一个图片的内容然后给img显示,经过长仔细排查出现在输出图片资源前就有输出,那时候用的是notepad+editplus,最后用Zend studio来看这个文件头出现一个锘�字,证明了该问题。

第二次遇到BOM问题,是陈鑫鑫在纸条项目里面输出XML数据到IE浏览器中展现出现XML错误。

第三次也就是我们的记录APP调用外部接口返回用户的昵称出现乱码,经琳琳查也由BOM造成!
为 何经常出现这种类似的问题,我看大家都在按照自己的方式来建立和开发PHP,特别是用Notepad来新建文件,系统默认在是ANSI格式,但我们的 PHP编码是UTF-8的,于是又通过Notepad的另存为修改为UTF-8格式的,这样也就产生了一个BOM,最后,再用现在统一的开发工具Zend for eclipse去编辑这个带BOM的PHP文件,但BOM依然存在文件当中,它一般是表现不出任何问题,但一旦在页面前不能有输出的情况:如上面我遇到的 三种情况它也就显现出来了。

BOM如此讨厌,该如何避免:
建议:
1.  切实统一开发工具:统一用Zend for eclipse 来新建PHP文件,和修改PHP文件编码!
2.  在 项目完成后对目录里面所有的PHP 文件进行遍历驱出有可能出现的BOM。如:用sed批量替换掉bom:(syscore目录和所有下级目录的PHP文件替换)   find ./syscore -type f -name "*.php" -exec sed -i '1s/^\xef\xbb\xbf//' {}  \;



(3月27日---4月2日)
遇到一问题:
在调试记录的js时发现超过了页数却没有出现翻页导航的页,开始首先以为是数据没有输出程序的问题, 最后查明是由于朋友下面的frame把下面给档住了,Js人员修正了这个问题,这个问题还经常出现,希望js人员也多注意一下!
工作心得:
本周收到老姜发的一点对PHP框架的看法,我也斗胆也说说我自己对这个问题的看法,有些可能说得不太准确或者有些错误,还望包含:
首先,我个人是不反对PHP采用一些轻量级的框架,但极力反对对PHP用一些重型的框架的,为什么呢?因为它的执行方式决定了它的这个特点:php每一 个脚本先全部载入所有资源,执行完毕后全部放弃,所以使用太重的框架,会极耗内存和计算资源,形成调用栈太深占用系统资源,个人觉得轻量框架和简单的分层 还是一定要采用的。
其次,你会说像Java这样的语言它能采用一些的框架,而且还涌现出了一些红红火火的框架了呢:)
个人觉得那是因 为java的执行方式和PHP不一样,对于内存管理也不一样,有很多都是一次装入内存,直到jvm重启才被释放的, 事务性,安全性等等很多基础性的服务,都需要预先装入,何况java是基于工业级应用产生的,php只是个人网站开发才出现的,能一样吗?不能。所以,不 能我们也不要一边倒,看人家采用什么什么了,自己也想把PHP往边上套。
再次,C++和Java强悍的框架不少,但惨不忍睹的框架也更多,为 什么呢?用一个越是尖端的东西越不容易用好,对于重型的编程语言对软件工程功底的要求是相当高的,不是谁说想做个框架就做个框架,更何况各个项目的千差万 别,实际的情况也不尽一样,更不能以一个框架来以逸待劳,放大了框架的作用,它并不是万能的。
最后,我仅对PHP的框架也就领悟到:轻量框架和简单的分层还是PHP在大多数项目开发中还是一定要采用的,但切忌过重,把握好度,适可而止。

Tags: php, 经验

从用户体验UE角度设计用户登录系统

很老的一篇文章,可即使是如今看来,也有可取之处。06年的了。现在都09年了
最近,几乎所有的网站都在以改善用户体验为首要目标,所以,更加需要查看这些文章来做参考。

原文:http://www.bloghuman.com/post/196/

内容如下:(图片我也没有下载到本地,直接用的该网站的)

登录界面经常遇到的几个问题:
1、“注册”“找回密码”等这些个非“登录”任务本身的嫡亲应该安排在那里?
我的观点:首先一定要明确“严格来说他们并不属于这个任务”。
放在那里不重要,重要的是我们需要给表现成“相关任务”,不要当作该任务界面的主要元素来处理。(无论在架构还是在交互上都不要让他“喧宾夺主”)
2、“保存cookies”“登录设置”等些个“登录”任务的直系亲属应该如何处理?
我的观点:首先,这些属于任务的一部分
其次, 如果默认设置能够帮助完成这些信息可以尽量不需要在登录任务里显示,
然后,如果需要 一定要简洁,但简洁的同时要注意文字的表达(如,“自动登录=保存密码+自动登陆”的表达就很不合适)。而且一定要注意默认的备选项设置。
3、表单的排列是横排还是竖排?横排该怎么排,竖排又该怎么排?
我的观点:横排还是竖排要看页面的排版所需,没有什么大的原则问题。具体怎么排只要用心思考一下肯定就知道权衡了,
横排用户的焦点轨迹跨度较大,但空间占用较小;竖排用户的焦点轨迹可以是直线,但空间较大。如果条件允许我建议用竖排,如果规范所限或条件有限我不介意用横排。但大部分情况下我很介意在输入框中默认一些类似"再次输入密码"等傻瓜提示信息的行为
4、是否需要验证码?
我的观点: 如果安全性没有大问题的话一定不要。
但好像你的技术搭档绝大部分时候都会告诉你“安全性”有大问题,所以很多时候我们不能“为了细节的良好体验而纵容了系统的安全受挫”...
所以这个命题索性可以改成“验证码”应该怎么设计?
我反对一: 中文验证码 (纯弱智的设计)
我反对二: 英文和数字混合的验证码 (给用户输入带来了不少麻烦)
我反对三: 超过4位的验证码 (记忆中好像据说是什么研究结果)
我反对四: 有大写字母的验证码
特别是大小写混合且实际系统判断时还不区别大小写的 —— 虽然你不区分大小写,但你显示的是大写很多用户就会很费劲的打开大写输入填写大写字母,无形中给用户带来了负担。
5、目前看到的一个我最喜欢的登录任务的设计:
点击在新窗口中浏览此图片
喜欢一: 任务明确,登录任务应该包括“登录信息+登录设置”,“找回密码”不属于登录任务,这些它都交代的很清楚。
喜欢二: 流程清楚,竖排排列用户可以直线思维操作, 用户>密码>保存密码>登录 一气呵成。
喜欢三: 设计精简,类似“保存我的信息”“自动登录”都没有放到这里,这就是我所说的“如果默认设置能够帮助完成,这些信息可以尽量不需要”。因为,大部分情况下如果你真的需要设置 说明你已经不是简单的初级用户,那么你一定有能力自己去找解决方案
喜欢四: 小细节大学问之 —— 错误密码记忆。
看看上图“用户>密码>保存密码>”三个步骤之间都有一个不小的行间距,这个间距空袭乍一看似乎并没有什么作用。
但研究过的人会发现里面的学问不小..
如,
点击在新窗口中浏览此图片
当我第一次输入一个错误的密码时,系统在判断错误后会在提示错误的同时把我的这个输入记忆,当我再次输入这个错误密码时,系统会自动在客户端提示“密码错误”。这样做减少了用户的一次误操作同时也减少了一次提交给服务器端的任务。因为: 密码的输入显示是*并非能直接看到你的确切输入结果,有很多时候你确实是记错了,可以你以为是你自己输入出错了。
喜欢五: 小细节大学问之 —— 验证码
等你输入错误一定次数时才会出现验证码。 (不是一开始就有验证码,也不是你输入错误多了就不让登录)
6、yahoo的登录也很有意思:
点击在新窗口中浏览此图片
优点一: “防密码失窃”功能的设计很有想法,这样的布局基于好的图形设计创新
优点二: 任务足够简单
优点三: 大家好像都具备这些..
缺点一: 任务足够简单,但拖泥带水过多
缺点二: 记忆用户ID的功能很好,但这种显示方式不舒服,给用户的修改增加了步骤
7、细节之 —— 减少用户的填写
我目前为止利用过四次很偶然的机会,观察过五个普通网民用户使用126邮件的过程。
他们在登录时有四个人遇见了同样的问题 —— 输入的时候不知道只要输入 whitecrow_zhu就可以了,而是输入完整的whitecrow_zhu@126.com。
另外一个没有出现这种情况的用户是因为,当他打到"@"符号时,旁边有个人提示他“你SB呀,后面的不用填”,所以他才没有填...

8、总之登录”就是一扇门“

一扇让产品和用户真正互通的门,让产品可以给用户体现出更多价值的门。
所以这个门一定要: 够宽、门槛够低、一直开着、记忆每次进出...

Tags: ue, 设计

摘:精通php的十大要点

1. 在合适的时候使用PHP - Rasmus Lerdorf
没有谁比PHP的创建者Rasmus Lerdorf明白PHP用在什么地方是更合理的, 他于1995年发布了PHP这门语言,从那时起,PHP就像燎原之火,烧遍了整个开发阵营,改变了互联网的世界。 可是, Rasmus并不是因此而创建PHP的PHP是为了解决web开发者的实际问题而诞生的。

和许多开源项目一样,PHP变得流行,流行的动机并不能用正常的哲学来进行解释,甚至流行得有些孤芳自赏。它完全可以作为一个案例,一个解决各种web问题的工具需求所引起的案例,因此当PHP刚出现的时候,这种工具需求全部聚焦到PHP的身上。

但是,你不能奢望PHP可以解决所有问题。Lerdorf是第一个承认PHP只是一种工具的人,并且PHP也有很多力所不能及的情况。

根据工作的不同来选择合适的工具。我跑了很多家公司,为了说服他们部署和使用PHP,但是这并不意味着PHP对所有问题都适用。它只是可以一个解决大部分问题的front-end脚步语言。

作为一个web开发者,尝试用PHP解决所有问题是不科学的,同时也会浪费你的时间。当PHP玩不转的时候,不要犹豫,试用一下其他的语言吧。

2. 使用多表存储提高规模伸缩性 - Matt Mullenweg

没有人愿意质疑Matt Mullenweg在PHP方面的权威性,他开发了这个星球上最流行的blog系统,(依靠一个强大的社区力量支持): Wordpress. 创建Wordpress以后,Matt和他的团队启动了Wordpress.com平台,一个基于Wordpress MU的免费blog站点。现在,Wordpress.com已经拥有大约400万用户, 这些用户每天提供超过 140,000篇的日志。 (要查看更多Wordpress.com的统计情况,请点击这里.)

如果有人知道如何让网站的规模伸缩自如,这个人一定是Matt Mullenweg。2006年的时候 Matt对Wordpress的数据结构进行了前瞻性的改进,并且解释了为什么Wordpress MU对每个blog使用独立的MYSQL表格, 而不是把所有的blog数据都塞进一个巨大的表格。

我们测试过这个方法,但是发现如果要扩展它的伸缩性,代价太高。如果用一个整体的数据结构,在大流量面前,你将会面临服务 器硬件的问题。在MU里面。用户们都被分布到独立的表格当中,并且可以轻易地组织起来。举个例子,WordPress.com把用户的数据分散存储到 4096个数据库中,这些数据库可以分散大规模的数据访问,实现流量和压力分流。

数据表的可迁移性让代码(blog)可以运行得更快,并且让系统具备更强的伸缩性。依靠强大的缓存策略和灵活的数据库运用策略, Matt向人们展示了时下最流行的Facebook和Wordpress.com都可以在PHP下稳定运行,并且处理惊人的访问量。

3. 千万不要相信用户 - Dave Child

Dave Child是 Added Bytes (previously ilovejackdaniels.com) 网站的核心人物,这个网站以他出色的《cheat sheets for many programming languages》而闻名。 Dave为很多英国的公司服务,并且已经在编程世界里树立起相当的权威。

Dave为PHP开发者提供了很多深谋远虑的建议,并总结成了《writing secure code in PHP》:千万不要相信你的用户,他们甚至可能会伤害你。

有一条web开发的基本原则,我重复多少遍都觉得不够,那就是:千万不要相信你的用户,同时要假设你网站中的每个数据单元 都是从用户那里收集来的恶意代码。很多时候,你必须用javascript在客户端检验表单提交过来的内容, 如果你习惯了如此,那么,这是一个好习惯。如果安全性对你来说很重要,这就是最重要最需要学习的原则。

Dave目前正致力于为它的《Writing Secure PHP》系列书籍整理实例,书的最后他说:

最后,变得偏执一点吧。除非你认为你的站点永远不会受到攻击,否则就正视所有的问题,当问题真正发生的时候,你的情况会变得很糟。你需要把每个用户都看成会带来一场攻防站的黑客,想尽一切办法来保护站点的安全,同时想好相应问题的解决方案。

4. 多使用PHP缓存 - Ben Balbo

Ben Balbo开发了Site Point,一个为developers和designers提供指导的网站。他是墨尔本PHP开发和开源俱乐部的成员, 因此他对PHP有一定的了解,同时对PHP caching有一定的想法和经验。

如果你拥有一个访问量很大,但更新并不频繁的站点(比如blog,基于某种CMS),或许它需要进行一些改造,这些改造不会花费太多的时间,但是对性能有突出的贡献。 如果要为一个复杂/更新频率很快的站点建立缓存机制,过程可能会很曲折,但是好处也是显而易见的。

PHP缓存技术有很多种,Ben为我们推荐了如下一些:

缓存函数的运行结果
设置过期时间
缓存IE下载的文件
模板缓存技术
Cache_Lite

由于PHP作为动态语言的特性,缓存机制对于更新频率并不快的站点来说非常重要。

5. 使用IDE, Templates和Snippets加速PHP开发 - Chad Kieffer

当Chad Kieffer从UI设计和数据库优化的工作中抽身出来的时候,他会在他的博客2 tablespoons上分享很多技术经验。由于Chad多方面的全面发展,他经常可以发现其他程序员不能发现的问题,并形成相关经验,尤其是他开发网站的方法。他参与了网站开发的各个环节,因此他的建议对于提高网站开发的大局观非常有用。

Chad认为使用Eclipse PDT
(Eclipse’s PHP development package) 这样的IDE,同时使用一些模板技术和开源项目可以有效地提高PHP的开发速度。

紧凑的计划,长长的to do lists以及deadlines让开发人员非常苦闷。不过有些功能,比如Eclipse Templates,可以有效减少编码的时间和出错的几率。

通常来说,任何项目都可以自动化,自动化程度越高, 你完成项目的时间就越短。花时间来开发使用频率很高的框架和模板,将会节省你以后更多时间。同时,使用像Eclipse and the PDT package这样的IDE,你会发现效率得到明显提高,IDE可以自动闭合,补全分号并且可以在本地debug。

6. 利用好PHP的过滤函数 - Joey Sochacki

或许Joey Sochacki并不像Matt Mullenweg那样有名 ,但他也是一个经验丰富的开发者,并且通过他的博客Devolio分享了很多技术经验

Joey发现在编写php代码的过程中有很多地方需要进行过滤,但却并没有太多的coder关注php的内置过滤函数。

过滤数据是我们经常需要做的事情,但是很多功能丰富的PHP内置过滤函数却不为人知。使用类似filter_* 的PHP内置函数,我们几乎可以处理所有的过滤任务,包括数据类型验证/URL/email和IP地址验证/特殊字符处理等等。

过滤是一件复杂的事情,但是我相信joey的发现会给你很多启发,让你认识到PHP强大的过滤功能。
7. 使用PHP框架 - Josh Sharp

对于是否应该使用Zend, CakePHP, Code Igniter, 或者 其他PHP框架,一直存在着很多争议,但是在web开发者的心中,他们有自己衡量的标准。

Josh Sharp自己创建了一家提供面包和黄油服务的网站,因此他对于使用PHP框架来开发网站有一定的经验。他认为使用一个PHP框架来进行项目开发(use a PHP framework ),可以有效地节省时间,并且减少出错的几率。为什么?因为他觉得PHP实在是太好上手了。

PHP的易于使用有时候也有缺陷,因为并不严格的语法,经常会导致很多错误代码的诞生。但如果使用一个PHP框架,出错的几率就会大大减少。

PHP框架可以让你的代码结构更加规范,并且节省大量时间,你可以阅读《 benefit of using a PHP framework 》来获得更多相关信息。

8. 不要使用PHP框架 - Rasmus Lerdorf

与Josh的观点恰恰相反, PHP的鼻祖Rasmus Lerdorf却认为最好不要使用PHP框架,为什么?因为不基于框架的PHP性能更好。

Rasmus在Drupalcon 2008的演讲上,用“Hello World”的例子来对比了一些框架PHP和简单PHP之间的性能,结果显示框架PHP的性能要远远落后。

9. 使用批处理 - Jack D. Herrington

Jack Herrington对PHP世界并不陌生, 并且为大名鼎鼎的IBM developerWorks贡献过超过30篇的专搞, 同时出版过《PHP Hacks》的书,因此他是一个真正的专家。

Herrington 推荐使用批处理和Cron来代替那些可以运行在后台的程序脚步,web用户并不愿意在线等待你的处理过程,所以有些事情更适合放到后台来处理。

诚然,在某些情况下,这有点大材小用了,但是你可以清楚地看到,使用Cron, MySQL, PHP面向对象的方法以及Pear::DB这些便捷的工具来创建一个批处理工具并不是一件复杂的事情。

Jack认为使用cron, PHP和MySQL在后台处理一些任务,比起多进程的业务逻辑要划算得多。

两种方法我都尝试过,我认为Cron非常符合”Keep It Simple, Stupid” (KISS) 的原则,它让后台处理变得简单。与多进程的业务逻辑相比,它没有内存溢出的风险。你可以创建一个简单的批处理脚本,并且在cron中运行,这个脚本会定时 检查是否有任务需要处理,处理完之后就会自动退出,因此你不用担心是否有进程卡壳,或者陷入死循环。

10. 及时启用错误报告 - David Cummings

David Cummings有一个专门提供CMS软件服务的公司 ,并且获得过几次奖 ,他有非常丰富的PHP开发经验。

David曾经写过《two PHP tips he wished he’d learned in the beginning》,其中一点就是:及时启用错误报告,这会节省大量的时间。

我告诉人们,最重要的事情就是最大程度地开启PHP的错误报告,为什么?因为PHP可能会隐藏很多小问题:

  • 变量没有预定义
  • 在代码片段中引用了不可用的变量
  • 使用了未定义的常量
  • 这些因素看起来并不是什么大事,除非你在使用面向对象的方法编写一些类库。通常,关闭错误报告将可能使你付出更大的成本来维护你的代码。

错误报告可以帮你轻易地找到代码的问题所在,如果错误报告的等级够高,细微的错误都能被立即发现,帮助你节省整体debug的时间。
原文地址:http://nettuts.com/tutorials/php/10-principles-of-the-php-masters/
翻译整理:Andrew

Tags: 精通, php

老王:单例模式是邪恶的么

老王的看法,不过,事实上就是这样,现在很多开发人员还是很少在运行时候把对象作为参数传给某个方法或者class

原文:http://hi.baidu.com/thinkinginlamp/blog/item/ea586b63472627680c33fa38.html

正文:

写在前面的话:PHP每次运行重建环境,这样的运行方式本身就决定了PHP没有传统意义上的单例。

单例模式(singleton)也被叫做单件模式。使用它的目的是为了确保某个类只有一个实例。因为它的实现方式很简单,所以多数模式书籍都把单例模式作 为入门模式来介绍,可以说对很多模式爱好者来说,单例模式是他们最熟悉的设计模式。可惜这间接造成了单例模式使用的泛滥,以至于到了无所不在的地步,比如 说,ZendFramework里连前端控制器都是单例的。那么,单例模式是邪恶的么?

下面看一个实际编程时很多人愿意采用的单例模式例子:

注意:正常的单例模式应该设置一个私有化的__construct,但是出于下文的需要,我省略的它,至于限制__clone的行为,因为我嫌它占地方, 所以也没写,这两点你自己注意一下就好了,和文本讨论的问题关系不大。完整的例子可以参考:http://www.php.net/manual/en /language.oop5.patterns.php。

class Database
{
    private static $instance;

    public static function getInstance()
    {
        if (!isset(self::$instance)) {
            $class = __CLASS__;
            self::$instance = new $class;
        }

        return self::$instance;
    }
}


如此的单例模式通常是这样调用的:

class Article
{
    private $dasebase;

    public function __construct()
    {
        $this->database = Database::getInstance();
    }
}

$article = new Article();


下面我们就来讨论一下这样使用单例模式好还是不好。

文章在构造函数内通过单例模式的方式得到数据库实例,这看起来很正常,但是对于文章这样的领域概念来说,数据库实例属于纯粹的技术实现手段,明显属于外来 物,应该尽可能隔离才对,这样才符合单一原则,在测试驱动开发的领域,这被称作MOCK,但是在上例中,由于我们是在构造函数里通过单例模式静态方法调用 得到的数据库对象,这就造成了没有办法从外部替换掉这个数据库对象。

为了克服这样的问题,按照如下的方式获取数据实例更好一些:

class Article
{
    private $dasebase;

    public function __construct($database)
    {
        $this->database = $database;
    }
}

$database = Database::getInstance();
$article = new Article($database);


一旦我们把数据库实例化的过程放到了外面,便可以随意替换掉其具体的实现方式,这很棒,特别是在测试的时候很有用,因为数据库环境是一个很大的不安定因 素,替换掉它有助于让测试用例更高效的运行。你甚至可以把程序搞得再智能化一点,一切外部对象依赖都通过容器注入的方式挂接。

此时再看看上面代码里的$database = Database::getInstance($database);突然又感觉有点莫名其妙,因为实在看不到在这里使用单例模式有什么额外的好处,直接按照最平常的实例化方式并没有什么不妥:

$database = new Database();
$article = new Article($database);

外部数据库对象通过构造函数的方式注入到文章里,保存在$this->database属性中,至于文章级联的评论 ($article->comments)也需要数据库实例这样的情况,可以在实例化评论的时候把文章的$this->database属性 通过评论构造函数注入的方式传递过去,当然,还有其它的方法,总而言之,你不再需要一个单例模式的数据库实例。

再回到单例模式的本意上:为了确保某个类只有一个实例。比如说公司只有一个CEO(如果有一个公司有多个CEO,那么这个公司必然会犯很多逻辑错误)。但 是反思现在很多人对单例模式的使用,往往并没有按照单例模式的本意来使用,拿上面的数据库例子来说,如果文章有一个数据库实例,评论有另一个数据库实例。 这有什么逻辑问题么?答案是没有。既然不必确保数据库只有一个实例,那么在这里使用单例模式的动机本身就值得推敲。当然,有人会说文章和评论使用不同的数 据库实例本身就低效。但如果仅仅是出于效率的考虑来使用单例模式,那么本质上不符合单例模式的定义,更何况即便不使用单例模式,我们也可以像文中的例子一 样通过注入的方式来解决所谓的低效问题。

写在后面的话:单例模式本身并不邪恶,邪恶的是在错误的环境下使用单例模式。不要为了单例而单例。

Tags: 单例, 模式

如何提高网站的访问速度 - 从30秒到3秒的改变

又一篇不是我写的东西,不错,对于WEB开发人员来说还是有参考意义的。所以我就贴了回来,也可以做个参考吧。。

原文:摘自:http://xinsync.xju.edu.cn/index.php/archives/4504

2006年10月份,我开始对web开发产生了兴趣,并决定自己也尝试开发一个网站。在此之前,我做过3年的java application的开发,对web开发应该算一无所知。在比较了java,php,ror,和python后,我选择了基于python的web框 架 - django 。到目前为止,我还认为这是一个明智的决定。Django高效的开发效率让我仅仅用一个月的业余时间,就基本完成了网站的开发。这是一个网络书签的网站, 我加上了一些有意思的特性,让网站显得有些与众不同。

我购买了域名和Dreamhost 的主机空间。Dreamhost支持django,并且第一年的费用只有180元人民币。2006年11月份,http: //www.hpbookmarks.com 上线了。网友们发来了善意的评论,“很有创意”,“点意思”,“一些feature很不错”。同时,还有一个非常一致的意见就是,“访问速度太慢了”。其 实,当时的情况不只是访问速度慢,而且是相当不稳定。很多时候是几个小时网站无法访问。当时,我并没有在意,因为我有两个自以为“合理”的解释。第一,我 用的是国外最便宜的虚拟主机,国内访问慢是很正常的。第二,django的还处于0.95的状态,效率和稳定性方面有问题也正常。

但是,我慢慢发现上面的解释不过是自己骗自己的借口。很多用dreamhost的网站,访问起来也很快。而且django也已经被成功应用在许多 大型的网站。我开始认真考虑提高网站速度的问题了。毕竟,速度慢的网站很可能在第一次就失去的用户,他们可以永远不会再来了。终于,我进行了下面一步一步 的优化工作,并且取得了一个看起来还不错的结果。

第一步,用Ajax提高用户体验

由于我的网站上链接字体的大小是根据点击次数决定,所以每次点击都要提交到服务器端并记录次数,再在客户端打开网站链接。这在localhost 测试的时候没有发现问题,但是部署到服务器上,会感到明显的等待。解决办法就是用Ajax。用户点击网站链接后就直接打开,再通过Ajax将点击的事件提 交到服务器端记录。这样用户感觉不到任何延时。

第二步,将逻辑移到客户端的javascript中

在开始的时候,“网站标签高亮”和“手气不错”的功能都是提交到服务器端操作,然后返回结果的。后来,我发现其实很多逻辑是可以移到客户端,由 javascript来实现的。Javascript非常强大,可以完成很多复杂的逻辑。将逻辑移到客户端的javascript中,可以很有效的减少和 服务器通讯的次数,获得更好的访问速度。

第三步,解决进程的

由于采用的是fastCGI的方式,我配置了django.fcgi。可是,我发现系统进程中,有大量的django.fcgi进程被标记为 < defunct>(失去功能)。这些进程会导致服务器有时无法正常访问。我开始尝试用命令来kill掉这些进程,但是很快发现这无法从根本上解决问 题。后来,我看到一个老外在blog上提到一个解决方案,将django.fcgi改名为dispatch.fcgi。原来,dispatch.fcgi 是一个dreamhost的系统进程,它的健壮性是可以得到保障的。果然,我将django.fcgi改名为 dispatch.fcgi后,的现象再没有出现。

第四步,优化SQL语句

SQL语句的执行通常也是一个很花费时间的操作。经过检查,我发现我的一条SQL语句,是一个嵌套三层的子表查询。而这条SQL还必须是一个 Raw SQL,即不能采用django的OR Maping。这意味着不能被cache缓存,每次都是真刀真枪的执行。更失败的是,经过我的分析,这条SQL完全可以不执行。这是一次设计上的失误,标
准的over design(过渡设计)。当时,我是想通过数据库得到一个最精确的统计值。后来发现,这个值完全可以用一个近似的常量代替。优化SQL,尤其是避免不必要的SQL执行,带来的效果是非常明显的。

第五步,尽量减少页面大小

随着添加网站越来越多,有一天我发现django生成的首页已经达到了80k。我很清楚这是一个非常不能被接受的数字。我开始检查页面,很快发现 了线索。 第一,因为偷懒,页面中很多layout是用空格( )实现的。第二,因为为了增加代码可读行,调试方便,每行生成的页面都增加换行符 (\n)。第三,最糟糕的是,大量的用了
inline css。就是将css style直接嵌入标记块中。于是,我立即动手,用css的align解决layout,去掉\n,将inline css抽象到独立的css文件中。这样下来,在不更改任何内容的情况下,80k变成了57k。(补充:由于网站链接大部分是打开新窗口,所以用了大量的 target=_blank。在ylsdd的提示下,在html的head里增加了,又节约了4k。)

第六步,用gzip进行页面压缩

当我兴高采烈的把页面优化结果贴到了smth bbs上,却被直接泼了盆凉水。原来百分之二十几的优化结果,实在太一般了。ylsdd给我了一个很重要的线索,deflate。原来apache的 deflate模块可以把文件进行gzip压缩,压缩后的文件传到浏览器后再被解压。主流的浏览器都支持这种gzip的解压操作。于是,我在apache 的配置文
件中加入了Add OutputFilter DEFAULT html css js的语句。经过测试,css,js这些文本文件的压缩后都只有原来尺寸的25%。这里,和大家分享一个网站http: //www.port80software.com/products/httpzip/compresscheck 它的作用是检测你的网站是否被压缩,以及压缩比率等。

第七步,回归静态页面

新的问题又来了。原来deflate只支持静态文件的压缩。而我的首页是django动态生成的,deflate模块没有进行压缩。我突然想到, 网站的首页为什么不能是静态页面呢?于是,我增加了一个runtime的api,这个api提供的是和原来一样由django动态生成的页面。我又写了一 个 python的程序,通过urllib2模块下载这个动态生成的页面,并保存为index.html。我将网站的root映射到index.html这个 静态页面。最后,通过linux crontab定义一个行为,每五分钟执行一下这个python程序,生成新的index.html。值得一提的是,由于网络原因,python程序不一 定每次都能准确完整的下载动态生成的页面。所以我们必须再进行一个校验算法。当页面大小要超过一定数字,页面中出现某个校验字符串的情况下,才保存 index.html。这样,每次用户提交的访问,不是由服务器端动态生成页面,极大的节省了服务器端的开销。而静态页面又可以有效的被deflate压 缩。最后结果,首页被压缩为13k,为原来的22%。唯一的区别就是,新提交和推荐的网站不能立即出现在首页。但是我认为,这应该是可以被接受的。

至此,网站的优化工作基本完成。网站的访问速度从原来30秒以上,缩短到3秒左右,应该说算是一个飞跃。虽然,3秒的速度也不是非常快,但是,考虑到虚拟主机等客观原因,这个结果我还是满意的。原来感觉我的网站很慢的朋友们,也可以再试试。

以上的优化方案出自我的个人经验,并不一定适合所有网站。但是,它告诉我们一个事实。影响网站访问速度的不仅仅是服务器配置,网络带宽。也许,你 糟糕的设计,低效率的方案也是致命的因素。应当注意的是,优化工作也不能匆匆上手。一定要仔细研究,具体情况具体分析,得到统计数据,找到真正的问题所 在,再开始优化。相信自己,提高网站的访问速度并不是不可能。毕竟,Nothing is Impossible。祝大家成功。

Tags: 优化, 网站