成就PHP高手的五个必由之路

原文名称: 5 ways to be a better php developer
原文链接: [url]http://www.developertutorials.com/blog/web/5-ways-to-be-a-better-php-developer-36/ [/url]英文版原文已经摘抄在本文后面,供参考。
中文翻译: Altair

  经常有一些经验不足的PHP开发人员在Freenode的##php IRC频道上问问题。如果问题很琐碎,或者答案显而易见,或表现得象一个菜鸟,很快他们就会发现会受到如下一些回复的炮轰:“去读该死的手册去吧”,“好好去学一学PHP吧”,“我们不是你个人的导师”或更直接的“你需要成为一个更好的PHP开发者”。但是,怎样才能成为一个更优秀的PHP开发者呢?在这篇文章中,我列出了五种成为更优秀的PHP开发者的方法,让你在PHP开发过程中提高效率,用更少的代码来完成更多的事情。在PHP的开发过程中永远会有更多的内容需要去学习,如新的核心函数,新的框架,新的设计模式,新的编码或文档规范等等。下面就是一些成为更优秀的PHP开发者的最佳途径。

1.阅读手册

  没什么比阅读手册更值得强调的事了–仅仅通过阅读手册你就可以学习到很多东西。特别是有关字符串和数组有关的函数。就在这些函数里面包括许多有用的功能,如果你仔细阅读手册,你会经常发现在以往的项目开发过程中,很多时候你在“重复发明轮子”,而实际上你只需要一个核心函数就可以完成相应的功能。手册是你的朋友。

2.阅读程序源代码

  有很多使用PHP开发的开源程序。为什么不去学习和借鉴呢?下载一份开源的PHP应用程序的源代码,仔细阅读它吧。也许越大的项目越值得去阅读,虽然它们也许有更复杂的结构和系统,但也有更详细的解释文档。如果你不知道从哪里开始,可以看看网站 http://www.sourceforge.net 。

3.学习一种框架

  现在的框架如雨后春笋般纷纷出笼;它们中的大部分都是开源的,可以直接从网上下载,当然你要知道从哪里去下载。可以先选择一些主流的框架 — 网站[url]http://www.phpframeworks.com[/url]里有一个非常好的主流框架的列表。

4.研究

  在PHP网站开发过程和讨论中你可能听说过很多术语。从OOP到MVC,KISS到DRY,YAML到INI,甚至REST到XML-RPC,也许有数百个与你的工作直接相关的技术概念。你也许对它们有了一个基本的了解,但你真的了解它们到底是什么,对你有什么意义吗?花一点时间去做些实实在在的研究吧。Wikipedia是从事这些研究的很好的起点。你一定会从中学到一些新知识的。

5.学习面向对象程序设计

  这也许是上一个方法的继续,但是OOP比你想象的更重要。你真的了解PHP5中OOP是如何实现的吗?例如,你真的了解抽象类,接口,“implements”关键字,静态方法和静态属性,访问修饰符“protected”吗?甚至许多有经验的开发人员都倒在这些问题的面前。如果你能充分利用OOP的特征,你就可以节省很多的开发时间。

  就是这些。要想成为 PHP 高手,这是五个最直接而又重要的的方法

附英文原文:
5 Ways to be a Better PHP Developer
Often, an inexperienced PHP developer will hop onto IRC and ask a question in ##php on Freenode. And if the question is trivial, the answer seems obvious or they simply seem like a newbie, they may soon find themselves bombarded with such comments as “RTFM”, “Go learn PHP”, “We are not your personal tutors” or simply “You need to become a better PHP developer”. So, how is it that one becomes a better PHP developer? In this post, I’ll outline five ways to be a better developer, improve your productivity, write less code and achieve more with your web applications.There’s always more to learn when it comes to PHP development. New core functions, new frameworks, new design patterns, new code documentation styles. Here are some of the best ways you can become a better PHP developer.

1. Read the manual
I really can’t emphasize this enough – there’s a lot to be learned just reading the PHP manual. Especially check out the string and array functions. There’s a lot of functionality available right there, and often by reading through the manual you’ll find you’ve been reinventing the wheel in past projects when you could have just used a core function. The manual is your friend.

2. Browse through some code
PHP has a lot of open source code out there. So why not learn from it? Download an open source PHP application and have a read through the code. The bigger projects are probably better, as they’ll have more complex structures and systems in place but also more thorough documentation explaining it all. Check out SourceForge.net if you can’t find a good place to start.

3. Learn a new framework
There are more PHP frameworks out there than you’ve had hot dinners; a lot of them are open source and available online if you know where to look. Try the major ones first – phpframeworks.com has a good list. Your framework can never be entirely complete, your next job may require a different framework and you might just find the functionality of another comes in handy in one of your projects.

4. Research
You’ve probably heard a lot of terminology and discussed in the context of PHP web development. From OOP to MVC, KISS to DRY, YAML to INI, even REST to XML-RPC, there are hundreds of technical concepts out there that could directly relate to your work. You may have formed a basic understanding of them, but do you really know what they are or what they mean for you? Spend some time doing real research; Wikipedia is a good place to start. You’re bound to learn something new.

5. Learn OOP
Maybe this follows on a little from the previous point, but OOP is more important than you think. Do you really know about PHP5′s implementation OOP? For example, are you familiar with abstract classes, interfaces, the implements keyword, static methods and properties, the ‘protected’ access modifier? Even many experienced PHP developers fall down in this area. If you make use of the features of OOP, you could save yourself a lot of development time.

So there you have it. Five, straightforward yet significant ways to be a better PHP developer.

10位顶级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篇的日志。

  如果有人知道如何让网站的规模伸缩自如,这个人一定是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框架可以让你的代码结构更加规范,并且节省大量时间。

  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的时间。

PJBlog日志删除后访问页面出错的解决方案

  今天查看我这个博客的访问来源和访问入口时点击了其中一个被访页面,发现出现错误:[quote]错误 '80020009'
/blog/article.asp,行 33
[/quote]
  仔细一想,这个文章是在原来的服务器上用上个版本时忘了开启目录写权限,发布文章时文章没显示出来就多发布了几次后来删除掉的,但由于前几天转移服务器时原来的数据没及时备份出来,把老的数据处理了下,这时删除掉的不是原来删除掉的文章,导致搜索引擎收录也变化了,以至于我把备份恢复后访问到的文章是原来已经删除掉的文章。
  知道问题的起因,那解决起来就容易了。初步判断是程序里判断文章存在与否的语句出现问题。找到article.asp,从行33开始,相关代码如下:[code] If (log_View.EOF or log_View.bof) or (log_View(“log_IsDraft”) = True And not stat_Admin And memName <> log_View(“log_Author”)) Then
log_View.Close
showmsg “错误信息”, “不存在当前日志!<br/><a href=””default.asp””>单击返回</a>”, “ErrorIcon”, “”
End If
[/code]
果然,33行这个判断语句有业务逻辑上的错误。这里的意思是判断文章存在与否及是否有阅读权限。由于VBS里的Or是要把所有的条件都执行一次的,所以虽然前面已经能判断出记录不存在,但后面还是继续做判断,而在记录不存在的情况下再读取其中的字段值就会出错了。修改下判断的流程,做两步判断,先判断记录是否存在,然后再判断是否有阅读权限。修改后的代码如下:[code] If log_View.EOF or log_View.bof Then
log_View.Close
showmsg “错误信息”, “不存在当前日志!<br/><a href=””default.asp””>单击返回</a>”, “ErrorIcon”, “”
End If

If log_View(“log_IsDraft”) = True And not stat_Admin And memName <> log_View(“log_Author”) Then
log_View.Close
showmsg “错误信息”, “不存在当前日志!<br/><a href=””default.asp””>单击返回</a>”, “ErrorIcon”, “”
End If
[/code]
  测试通过。
  错误问题是解决,但随后我又考虑到一个问题,像这种从搜索引擎过来的,都是找相关信息的,如果遇到这样删除掉的文章,或者像我这样文章还在,只是id变了,最终看到的却只是文章不存在的提示,多不友好。我想可以通过来源获取相关关键字,然后搜索本站,找到相关的文章供来访者参考。由于时间关系,具体实现代码有空再写。

PHP数组的Hash冲突实例

上一篇文章, 我介绍了一个利用Hash冲突(碰撞)来对各种语言(包括,PHP, Java, Ruby等等)实施拒绝服务攻击的可能, 但是没有给出实例, 文章发出后, @Ferrari同学给出了一个另外一篇文章Supercolliding a PHP array, 文章中作者介绍了一种基于PHP的冲突实例, 以及带来的性能恶化对比. 我就借花献佛, 翻译给大家看看.

你知道不知道, 插入65536个经过构造的键值的元素到PHP数组, 会需要耗时30秒以上? 而一般的这个过程仅仅需要0.1秒..

请看如下的例子:

  1. &lt;?php
  2. $size = pow(2, 16);
  3. &nbsp;
  4. $startTime = microtime(true);
  5. $array = array();
  6. for ($key = 0, $maxKey = ($size - 1) * $size; $key &lt;= $maxKey; $key += $size) {
  7. &nbsp;&nbsp;&nbsp;&nbsp;$array[$key] = 0;
  8. }
  9. $endTime = microtime(true);
  10. echo '插入 ', $size, ' 个恶意的元素需要 ', $endTime - $startTime, ' 秒', &quot; &quot;;
  11. &nbsp;
  12. $startTime = microtime(true);
  13. $array = array();
  14. for ($key = 0, $maxKey = $size - 1; $key &lt;= $maxKey; ++$key) {
  15. &nbsp;&nbsp;&nbsp;&nbsp;$array[$key] = 0;
  16. }
  17. $endTime = microtime(true);
  18. echo '插入 ', $size, ' 个普通元素需要 ', $endTime - $startTime, ' 秒', &quot; &quot;;

上面的例子, 在我的机器上的执行结果如下:

  1. 插入 65536 个恶意的元素需要 43.1438360214 秒
  2. 插入 65536 个普通元素需要 0.0210378170013

这个差别是不是很夸张?!

我在上一篇文章中介绍过, 经过特殊构造的键值, 使得PHP每一次插入都会造成Hash冲突, 从而使得PHP中array的底层Hash表退化成链表:

Hash collision

这样在每次插入的时候PHP都需要遍历一遍这个链表, 大家可以想象, 第一次插入, 需要遍历0个元素, 第二次是1个, 第三次是3个, 第65536个是65535个, 那么总共就需要65534*65535/2=2147385345次遍历&hellip;.

&nbsp;

那么, 这个键值是怎么构造的呢?

在PHP中,如果键值是数字, 那么Hash的时候就是数字本身, 一般的时候都是, index &amp; tableMask. 而tableMask是用来保证数字索引不会超出数组可容纳的元素个数值, 也就是数组个数-1.

PHP的Hashtable的大小都是2的指数, 比如如果你存入10个元素的数组, 那么数组实际大小是16, 如果存入20个, 则实际大小为32, 而63个话, 实际大小为64. 当你的存入的元素个数大于了数组目前的最多元素个数的时候, PHP会对这个数组进行扩容, 并且从新Hash.

现在, 我们假设要存入64个元素(中间可能会经过扩容, 但是我们只需要知道, 最后的数组大小是64, 并且对应的tableMask为63:0111111), 那么如果第一次我们存入的元素的键值为0, 则hash后的值为0, 第二次我们存入64, hash(1000000 &amp; 0111111)的值也为0, 第三次我们用128, 第四次用192&hellip; 就可以使得底层的PHP数组把所有的元素都Hash到0号bucket上, 从而使得Hash表退化成链表了.

当然, 如果键值是字符串的话, 就稍微比较麻烦一些了, 但是PHP的Hash算法是开源的, 已知的, 所以有心人也可以做到

通过构造Hash冲突实现各种语言的拒绝服务攻击

上周的时候Dmitry突然在5.4发布在即的时候, 引入了一个新的配置项:

Added max_input_vars directive to prevent attacks based on hash collision

这个预防的攻击, 就是”通过调用Hash冲突实现各种语言的拒绝服务攻击漏洞”(multiple implementations denial-of-service via hash algorithm collision).

攻击的原理很简单, 目前很多语言, 使用hash来存储k-v数据, 包括常用的来自用户的POST数据, 攻击者可以通过构造请求头, 并伴随POST大量的特殊的”k”值(根据每个语言的Hash算法不同而定制), 使得语言底层保存POST数据的Hash表因为”冲突”(碰撞)而退化成链表.

这样一来, 如果数据量足够大, 那么就可以使得语言在计算, 查找, 插入的时候, 造成大量的CPU占用, 从而实现拒绝服务攻击.

PHP5.4是通过增加一个限制来尽量避免被此类攻击影响:

  1.   - max_input_vars - specifies how many GET/POST/COOKIE input variables may be
  2.     accepted. default value 1000

 

目前已知的受影响的语言以及版本有::

Java, 所有版本

JRuby <= 1.6.5

PHP <= 5.3.8, <= 5.4.0RC3

Python, 所有版本

Rubinius, 所有版本

Ruby <= 1.8.7-p356

Apache Geronimo, 所有版本

Apache Tomcat <= 5.5.34, <= 6.0.34, <= 7.0.22

Oracle Glassfish <= 3.1.1

Jetty, 所有版本

Plone, 所有版本

Rack, 所有版本

V8 Javascript Engine, 所有版本

不受此影响的语言或者修复版本的语言有::

PHP >= 5.3.9, >= 5.4.0RC4

JRuby >= 1.6.5.1

Ruby >= 1.8.7-p357, 1.9.x

Apache Tomcat >= 5.5.35, >= 6.0.35, >= 7.0.23

Oracle Glassfish, N/A (Oracle reports that the issue is fixed in the main codeline and scheduled for a future CPU)

CVE: CVE-2011-4885 (PHP), CVE-2011-4461 (Jetty), CVE-2011-4838 (JRuby), CVE-2011-4462 (Plone), CVE-2011-4815 (Ruby)

原文: http://www.ocert.org/advisories/ocert-2011-003.html

四个最值得使用的思维图软件

MindManager – 功能最强、最好用的思维图软件

MindManager是“老字号”的思维图软件了。我从2002年开始就使用它的4.0版本。我也是通过它才认识了思维图。相信很多人也是和我一样,通过这个软件认识思维图的吧?

MindManager功能强大,非常适合办公使用。它可以和MS Office完美集成。可以导出doc,excel,pdf文件。界面和使用习惯和MS Office非常接近,快捷键的安排也很顺手。MindManager还有丰富的模板功能,样式丰富。MindManager还有“头脑风暴”功能,只用 键盘就可以迅速地展开联想。放个投影,可以开展头脑风暴会议。

MindManager制作的思维图布局整齐。这是优点也是缺点。整齐——符合商务办公的要求,即使不熟悉思维图的人也能接受。缺点是这种过于整齐 的布局不符合标准思维图的原则。这么说吧:标准的思维图倾向“右脑思维”,MindManager制作的思维图倾向“左脑思维”。

MindManager 8是最新版。个人试用觉得8的功能和7的区别不是特别大。MindManager 8在界面上好像做了一些优化,比7流畅一些,图形显示也比较平滑。也许MindManager的功能也是差不多到顶了,新的版本很难再有创新。 MindManager 8在思维图上的功能没有增加什么,却增加了一些Web2.0的功能,例如“社会化网络”的应用。这方面功能我还要花时间研究一下。

iMindMap – 思维图发明者监制的思维图软件

Tony Buzan创造了思维图,他的著作《The Mind Map Book》也是学习应用思维图的入门教材(你没看过?那要找来看一下了)。如果Buzan出手,制作思维图软件会是什么样子的呢?iMindMap这个软 件给了答案。iMindMap的全名是 Buzan’s iMindMap,这是一个由思维图的发明者Buzan监制的思维图软件。

既然是由思维图的发明者监制,绝对忠实于思维图的规范。思维图的规范是什么?我用iMindMap制作了一张思维图,说明了思维图的一些主要规范(点击看大图)。

iMindMap和MindManager制作的思维图,最大区别在于线条、文字的布局,还有“节奏”的处理。iMindMap的布局样式更接近手 绘的效果;线条的粗细变化更符合Buzan在《The Mind Map Book》书中所建议的样式(平滑的弧线、粗细变化富有节奏)。

iMindMap在操作上倾向于手绘,可以沿着鼠标(或者笔,如果有)划出的轨迹,建立平滑、富有节奏变化的分支线。整个界面似乎也是为“平板电 脑”而设计,图标超大。如果可以用笔操作,将会非常自然。刚好我有一个wacom的15寸屏,试着在屏幕上绘画思维图,还是比较接近手绘的感觉。 iMindMap还有一个MindManager没有的功能,就是可以手绘插图。例如下图是iMindMap的界面截图,其中的iPhone就是直接在 iMindMap中手绘的。

iMindMap是一个Java程序,启动比较慢,操作上稍微有些粘滞的感觉。界面和MindManager相比,显得不是那么成熟。不支持拖放改 变结构层次。键盘操作也没有MindManager那么顺手。iMindMap的导出功能也比较丰富。可以导出excel文件或者OpenOffice的 Calc文件,也可以导出PPT幻灯片格式。导出图片或者PDF、HTML一样都不少。唯独不能导出为Word文件。

FreeMind – 免费开源的思维图软件

前面两个软件都是收费的商用软件,价格也不便宜。FreeMind就是一个免费开源的思维图软件。FreeMind有点像是MindManager 的免费模仿版。操作、功能和MindManager比较接近。当然界面就比较朴素简陋了。FreeMind也是一个Java程序,如果能吸收 iMindMap的特点,相信会更有前途。如果对制作的要求不是很高,只是想用一款软件辅助思维,FreeMind是不错的选择。不仅免费,而且体积还非 常小。

Instaviz – iPhone上用的思维图软件

这个是iPhone上用的思维图工具。其实按照Instaviz网站的介绍,Instaviz是一个“概念图”软件,所谓“概念图”包括了思维图。 用Instaviz不仅可以用来画思维图,也可以画一些简单的流程图。Instaviz的功能非常简单,如果只是用来辅助思维,也足够了。

纸和笔 – 最强大、最自由的思维图工具

就目前来说,任何软件都比不上纸和笔好用。所以我最喜欢的思维图工具还是一本活页的“速写本”,一支自动铅笔(或者其他笔)。马上行动起来,拿起纸和笔,享受思维的乐趣吧。

IT 圈里有哪些经常被读错的词?

===总结版===
*感谢各位朋友在评论中的指正。本贴旨在纠正各种明显的发音错误。如@梁海,@依云,@汤海所说,拿中文近似肯定会存在误差——对于这些误差,请直接参考音标或者真人发音。

()标相应英文单词
[]标音标

=====公司/产品名=====
Youtube (You-tube [tju:b]) 念 优tiu啵 不念 优吐毙
Skype [ˈskaɪp] 念 死盖破 不念 死盖屁
Adobe [əˈdəʊbi] 念 阿兜笔 不念 阿斗伯
Chrome [krəʊm] 念 克肉姆
C# (C Sharp) 念 C煞破
GNU [(g)nuː] 念 哥怒
GUI [ˈɡui] 念 故意
JAVA [ˈdʒɑːvə] 念 扎蛙 不念 夹蛙
AJAX [ˈeɪdʒæks] 念 诶(ei)贾克斯 不念 阿贾克斯
Ubuntu [uˈbuntuː] 念 巫不恩兔 不念 友邦兔
Debian [ˈdɛbiən] 念 得(dei)变
Linux [ˈlɪnəks] [ˈlɪnʊks] 两种发音 丽娜克斯 和 李扭克斯 都可以
LaTeX [ˈleɪtɛk] [ˈleɪtɛx] [ˈlɑːtɛx] [ˈlɑːtɛk] 雷泰克,拉泰克 都可以 (根据Knuth的建议,雷泰克斯和拉泰克斯不正确。而且LaTeX的重音是放在雷或拉上。感谢@Rio讨论。另外感谢发音大牛@梁海刚刚指出, [ˈlɑːtɛx] 注音符号里的x发的不是克斯的音,而是接近“巴赫”的那个赫。)
GNOME [ɡˈnoʊm] [noʊm] 两种发音 格弄姆 弄姆 都可以
App [ˈæp] 念阿破(与爱破也比较像,参见音标),不能把三个字母拆开念成A P P。

=====一般英语=====
null [nʌl] 念 闹
jpg [ˈdʒeɪpɛɡ] 念 zhei派个 不念 勾屁记
WiFi [ˈwaɪfaɪ] 念 歪fai
mobile [moˈbil] [ˈmoˌbil] [ˈməubail] 膜拜哦 和 牟bou 都可以
integer [ˈɪntɪdʒə] 念 音剃摺儿 不念 阴太阁儿
cache [kæʃ] 念 喀什 不念 卡尺
@ 念 at

=====感谢@Lawrence Li同学的补遗=====
Tumblr (Tumbler) 念 贪不勒
nginx (Engine X)念 恩静 爱克斯(@Lawrence Li有不同意见)
Apache [əˈpætʃiː] 念 阿趴气
Lucene [ˈluːsin] 念 鲁信
MySQL [maɪ ˌɛskjuːˈɛl] [maɪ ˈsiːkwəl] 念 买S奎儿 或 买吸扣 都可以
Exposé [ɛksˈpəʊzeɪ] 念 埃克斯剖Z (重音在Z上)
RFID 【本条争议颇大】:有人念af rid, ri fid,但是RFID官方念法依然是四个字母分开读R F I D
JSON (jason) 念 zhei森
Processing [ˈprəʊsesɪŋ] 重音在Pro上
avatar [ˌævə'tɑr] 念 艾瓦塌儿

IE崩溃解决案例

  最近打开QQ空间,IE选项卡老是出现崩溃,然后自动恢复。查看日志,发现有如下错误信息:

错误应用程序 iexplore.exe,版本 8.0.6001.19048,时间戳 0x4d633f27,错误模块 mpc_mtcontrol.dll_unloaded,版本 0.0.0.0,时间戳 0x456a6335,异常代码 0xc0000005,错误偏移量 0x0e404070, 进程 ID 0x2584,应用程序启动时间 0x01cc70963bb143a0。

  上网查,也没查到什么解决方法,再仔细一看错误信息,发现其中有&ldquo;mpc_mtcontrol.dll_unloaded &rdquo;,于是在电脑里搜索mpc_mtcontrol.dll这个文件,发现是快播QVOD的一个文件,大概罪魁祸首就是快播吧。为了验证是不是这个造成的,我打开IE加载项管理,禁用了此加载项,看还会不会再出现此问题。过几天再来总结。

2011 年 20 个最棒的免费 HTML5 网站模板

  HTML5 现在很火你知道吗,如果不知道你就比我小编辑还 out 了,别再觉得 HTML5 为时尚早了,现在开始学才不晚。

1. Free Website Template Slider Typography

2. Free Communication HTML5 wesite template

3. HTML5 website template for airline company

4. TheHoleInOne HTML5 template

5.Free Science HTML5 template

6.&nbsp; Free HTML5 Template For Hosting&nbsp; Website

7. CowboyUp HTML5 Template

8. HTML5 Templates For Real Estate Websites

9. HTML5 Portfolio Website Template

10. Website Template For Business Company

11. BoldAs HTML5 Template

12. HTML5 Music Website Template

13. HTML5 Template For Design Company Website


14. ArchiteXtrue HTML5 Template

15. Eductation Website Template For Learn Center

16. Static Facebook template For Music Band Page

&nbsp;17) Free Travel Website Template

18) Free Business Website Template

19) Free Website Template Web Design Studio

20) Free Music Website Template

在php中使用mysqli中的预处理和事务处理语句操作MySql

使用mysqli中的预处理和事务处理语句,效率和安全都比mysql有保障

预处理:
prepare($sql); //放到数据库

$stmt->bind_param(“sdis”,$name,$price,$num,$desn); //给占位符传值,类型-变量(不能是值)

$name=”zhangsan”;
$price=56.56;
$num=66;
$desn=”good”;

$stmt->execute(); //执行

echo “最后ID”.$stmt->insert_id;
$stmt->close();

/*=================select语句=================*/

$sql=”select id,name,price,num,desn from shops where id>?”; //准备一条语句放到服务器中

$stmt=$mysqli->prepare($sql); //放到数据库

$stmt->bind_param(“i”,$id); //给占位符传值,类型-变量(不能是值)

$stmt->bind_result($id,$name,$price,$num,$desn); //绑定结果集

$id=99;

$stmt->execute(); //执行

$stmt->store_result(); //一次性讲结果都取过来,才能移动指针和获取总数

//字段信息
$result=$stmt->result_metadata();

while($field=$result->fetch_field()){
echo $field->name;
}
echo “
“;

//记录信息
$stmt->data_seek(2);

while($stmt->fetch()){
echo “$id–$name–$price–$num–$desn
“;
}
echo “记录总数:”.$stmt->num_rows;

$stmt->free_result();

$stmt->close();

?>

事务处理:

set_charset(“utf8″); //设置字符集

$mysqli->autocommit(0); //关闭自动提交

$error=true;
$price=50;
$sql=”Update zhanghaodb set yue=yue-{$price} where name=’zhangsan’”;
$result=$mysqli->query($sql);

if(!$result){
$error=false;
echo “从张三转出失败
”;
}else{
if($mysqli->affected_rows==0){
$error=false;
echo “张三的钱没有变化”;
}else{
echo “张三的钱转出成功
”;
}
}

$sql=”Update zhanghaodb set yue=yue+{$price} where name=’lisi’”;
$result=$mysqli->query($sql);

if(!$result){
$error=false;
echo “从李四转入失败
”;
}else{
if($mysqli->affected_rows==0){
$error=false;
echo “李四的钱没有变化”;
}else{
echo “李四的钱转入成功
”;
}
}

if($error){
echo “转账成功!”;
}else{
echo “转账失败!”;
$mysqli->rollback(); //回滚
}

$mysqli->autocommit(1); //开启自动提交
$mysqli->close();
?>

一次执行多条SQL语句:

50;”;
$sqls.=”delete from shops where id < 20″; if($mysqli->multi_query($sqls)){
echo “多条语句执行成功!
”;
echo “最后插入的ID:”.$mysqli->insert_id.”
”;
//echo “影响的行数:”.$mysqli->affected_rows; //不准确!
}else{
echo “ERROR”.$mysqli->errno.”—”.$mysqli->error;
}

/*===========有结果集:select===========*/
$sqls=”select current_user();”;
$sqls.=”desc shops;”;
$sqls.=”select * fron shops”;

if($mysqli->multi_query($sqls)){
echo “多条语句执行成功!
”;
do{
$result=$mysqli->store_result(); //获取结果集

echo ‘

’;
echo ‘
’;
while($field=$result->fetch_field()){
echo ‘

’;
}
echo ‘

’;

while($row=$result->fetch_assoc()){
echo ‘

’;
foreach($row as $col){
echo ‘

’;
}
echo ‘

’;
}
echo ‘

’.$field->name.’
’.$col.’ 

’;

if($mysqli->more_results()){ //判断还有没有结果集
echo “

”;
}

}while($mysqli->next_result()); //取得下一个结果集
}else{
echo “ERROR”.$mysqli->errno.”—”.$mysqli->error;
}

$mysqli->close();
?>