Yii是在iorange的推荐下使用的,这两天我才刚刚在使用。做点笔记而己,没有其他
1、就象我在neatcn.com写的,创建项目非常简单,yii.bat这个命令就可以完成了。详细就在http://www.neatcn.com/show-57-1.shtml
2、项目目录中components中的文件,会在autoload中被引用,也只有这一个目录下的会被autoload,其他的都是有固定规范的。(不知道有没有理解错)
3、model目录下居然是tablemodel和form两种的集合,有点乱(官方的例子是这样的),不过想着form的validation也是用tablemodel来完成的,又能够理解这种做法,普通的tablemodel类继承cActiveRecord。
4、Controllers目录下是控制类,默认是SiteController,和其他框架默认是indexController有点不一样。继承自CController类。controller类中有一个layout的变量,可以设定layout。一般可以手工指定,如果同一个类里有不同的layout,估计还是要写个方法才行
5、Model的activeRecord返回的是对象,而不是象其他框架默认返回数组,因此取集合时要用getAttributes方法,当然,如果是只有一条数据,也可以直接$model->fieldname这样的方式来获取值 。
才学了这么一点,慢慢来吧。。重构路是漫长的。
这篇文章很有意思,以前注意过,但没仔细考虑过用来注入,或许就象王猛说的:
了解很长一段时间的web安全了,个人觉得世上最聪明的程序员其实是黑客,一次想N步,逻辑超强,技术全面,从操作系统漏洞、到语言本身漏洞、数据库本身漏洞、再到开发者代码,无孔不入。
文章来自寂寞hacker,http://hi.baidu.com/isbx/blog/item/08ef48547ef1ad58574e00bf.html:
当前的Web开发者中肯定有不少人没有注意到作者所提到的这两个问题的。
第一个问题是这样的,MySQL默认有一个配置参数 max_packet_size,这个参数是用于限制MySQL客户端和MySQL服务器端数据通信的数据包大小,MySQL的默认配置是1MB。如果客 户端发送的数据超过了1MB,则MySQL服务器端会忽略掉这个请求数据。作者接下来举了两个利用这个缺陷的例子,第一个是利用超长数据来使MySQL的 日志记录程序失效,第二个是在PHP+MySQL的环境下,PHP的Session清理程序会由于一次发送的清理session数据的请求数据包超过 max_packet_size的限制,而导致清理session失败。
而实际上,由于很多PHP+MySQL的程序都会运行用户上传附件之类,而一般的PHP+MySQL的上传附件限制都是大于1MB的,所以PHP的 程序开发人员一般是会去修改max_packet_size的值为大于1MB。这就给我们的漏洞利用带来了一定的麻烦,毕竟在当前的网络状况下,构造 1MB多的数据去上传还是可以忍受的。但是太大的数据量就比较考验我们的耐心了,呵呵。
第二个问题就比较严重了,MySQL对于超过字段长度的数据插入操作会进行默认的字符串截短。例如一个字段定义的长度为10,如果插入的字符串长度 超过10,MySQL会将长度超过10的部分字符串自动舍去后插入到数据表中。默认配置条件下,MySQL会产生一个警告信息,但是这个警告信息不会被 Web应用程序捕获到。所以,从表面上来看,超长数据也是可以“成功”插入数据表的。作者在下面举的这个例子就很有代表性了,首先是一个场景假设:
- The application is a forum where new users can register
- The administrator’s name is known e.g. ‘admin’
- MySQL is used in the default mode
- There is no application restriction on the length of new user names
- The database column username is limited to 16 characters
用户如果尝试注册一个用户名为admin的用户,会由于Web应用程序中的isAlreadyRegistered函数的校验而注册失败。
SQL代码
- SELECT * FROM user WHERE username='admin'
但如果用户使用用户名’admin x’来注册(注意admin和x之间有11个空格),则注册流程会是这样的:
isAlreadyRegistered函数会使用上面的SQL语句来检查user表中是否存在相同用户名的用户,查询结果肯定是不存在的。那么用户注册成功!
实际上,真正插入到user表中的用户名是’admin’!也就是说,MySQL不仅会截短超过长度限制部分的字符串,也会对字符串头尾的空白字符进行截短!所以,在user表中,现在存在了两个admin用户!
接下来,用户登陆,他使用的是用户名admin,密码是他刚才设置的’admin x’的密码。假设Web应用程序的登陆认证和授权函数是这样的一段代码:
PHP代码
- $userdata = null;
- if (isPasswordCorrect($username, $password)) {
- $userdata = getUserDataByLogin($username);
- ...
- }
其中isPasswordCorrect函数使用的SQL语句为:
SQL代码
- SELECT username FROM users WHERE username = ? AND passhash = ?
getUserDataByLogin函数使用的SQL语句为:
SQL代码
- SELECT * FROM users WHERE username = ?
可以看得出,上面的语句使用了预编译的SQL语句,是无法实施SQL注入的。但是由于MySQL的默认字段截短策 略,isPasswordCorrect函数会成功执行并返回用户名admin,接下来的getUserDataByLogin也会正确执行,返回的结果 虽然是一个数组,但是Web应用程序一般是取返回数组中的第一个结果,也就是真正的管理员用户admin的所有数据!
怎么样,不用SQL注入,一样拿到管理员权限!
后记:经过测试,上面的漏洞利用过程在MySQL 4中是确实存在并且可以利用的。但是在MySQL 5中,本机测试失败。失败的关键就在于MySQL 5对于超过字段长度限制的字符串插入会报错,并停止字符串插入操作。
附:MySQL 4的测试过程
SQL代码
- mysql> select * from tb_sqltest where name='jason';
- +
- | id | name | remark | time | col1 | col2 | col3 |
- +
- | 1 | jason | NULL | NULL | NULL | NULL | NULL |
- +
- 1 row in set
-
- mysql> select * from tb_sqltest where name='jason x';
- Empty set
-
- mysql> insert into tb_sqltest (id,name) values (2,'jason x');
- Query OK, 1 row affected
-
- mysql> select * from tb_sqltest where name='jason';
- +
- | id | name | remark | time | col1 | col2 | col3 |
- +
- | 1 | jason | NULL | NULL | NULL | NULL | NULL |
- | 2 | jason | NULL | NULL | NULL | NULL | NULL |
- +
- 2 rows in set
这是javaeye上的一篇访谈翻译(摘自程序员杂志),里面有一段关于PHP的安全性的话有点意思,用该页面下面的评论来说,搞的就象几个中国哥们在聊天一样。
我是觉得他们就象在一个group里的聊天记录。啥时候我也把QQ群或者MSN群里的聊天记录整理一下,也来个啥啥啥访谈。。。
原文地址:http://www.javaeye.com/news/4143-masters-listening-to-talk-4-php-founder-rasmus-lerdorf-interview-2
原文如下:
《程序员》杂志上连载的《PHP创始人访谈录》 的第二部分。
Chris DiBona : PHP 这个名字代表什么?
Rasmus Lerdorf : PHP是 , 恩 。 Hypertext Preprocessor , 这名字很蠢, 就是 PHP。 Zee v 与 Andi 是97年中加入进来的, 他们当时使用 php/fi, 在用到深度嵌套中碰到了一些问题, 他们都是计算机专业的, 知道如何写解析器 , 不像我是通过 hack 状态机这种方式来实现的 , 我想他们看到我程序的时候,一定对它竟然能工作感到惊奇吧 。
Chris DiBona : 呵呵,竟然可以工作
Rasmus Lerdorf : 他们是自愿做这些工作的, 当时我有点太累了,感觉自己像是在给半个因特网写程序, 人们不是给我发补丁来修补程序,而是。。。
Leo Laporte: 这是我的程序, 把 bug 给改了吧。
Rasmus Lerdorf : 是的 , 改了这个 Bug, 给我写个程序做这个。 我跟他们说做实现这个很容易,只要这么做, 他们说:“ 好吧,这是最麻烦的, 那剩下那些bug呢”
Chris DiBona :赶紧把 bug 修复了吧
Rasmus Lerdorf : 我当时的确很郁闷, 简直要把我掏空了。 当时感觉要么我就快要死了,否则我得把它移交到一个更大的 team 来做 。
Leo Laporte: 等等, 在我们继续谈论前,我觉得这是一个很有趣的话题, 这在开源社区并非罕见的情况吧。这种事情常常发生, 人们在说:“我管理不了这个社区了,我不干了,我简直要疯掉了”, chris 你肯定经历过很多这种情形, 这对于开源社区是不是个问题啊。
Chris DiBona : 是的,实际上我跟Rasmus探讨过这个问题, 每隔五个月,就有人公开在社区挑起这种事端, “天哪,开源项目完蛋了, 有人离开社区了”。 你知道的, 其实有人进入,有人离开这是很正常的。
Leo Laporte:事实上这事最近发生在 Zend Framework 社区了
Chris DiBona :是啊,让我们来谈谈吧,Rasmus
Rasmus Lerdorf : Zend Framework 是一个分离的项目,实话说,我也不是很清楚 ,你得问问他们,我也不清楚原因。
Chris DiBona : 从某一方面来说,实际上对大多数社区而言,某些人悄悄地离开了这也没有什么,尽管我不愿意这么说。
Leo Laporte: 对于用户而言,我们有时候的确不太满意所用的产品。
Rasmus Lerdorf :直到 php 3 ,实际上只有我一个人在做,当某人给我发了个 php 的补丁,我一定会重新写一遍,因为这是我的产品
Leo Laporte: 看来你不擅长移交工作。
Rasmus Lerdorf :我也不清楚开源的理论,当时也没什么开源的东西,我自己也是后来才想清楚了这些。没过多久,我在多伦多大学找了份工作, 建立一个对话访问系统。我想那大概是 97 年吧,哦,是 96年,偶尔我还能收到一些关于 php 的补丁,有些 bug 是我从来没碰到过的, 我碰到些困难, 有个在日本的程序员给我发了一些补丁,非常酷, 还有有一些在日本的朋友帮我做了咨询方面的工作,但是这并不是经常性的。 一年之后我想通了 , 我的确需要鼓励这种贡献,人们提交了 patch, 我不能接管然后自己再重写, 我应该接收它, 放弃控制。给他人以权力随心所欲的做自己想做的事情。对于大多数开源的开发者来说,这很难,即便在现在,开源项目是他们孩子, 他们应该控制它,但是对于长期发展来说, 你应该放手, 让其他贡献者做他们要做的事情 , 你不能做太多限制。
Leo Laporte: 看来,我们作为用户应该更激进一些,呵呵
Rasmus Lerdorf : 这没关系, 你应该意识到这点,这些人大部分也都是在家里做开源开发的,百分之九十的开源开发者不管他们是做什么。他们把孩子哄上床,为开源项目贡献出两个小时,然后 他们打开自己的邮件,发现一大堆愤怒的信息,全都是"这里有 Bug, 另外这里还有 Bug, 这个 bug 使得我们上百万的电子商务操作无法进行" , 但他们只能说:“好吧,我已经在晚上贡献了2个小时, 这确实不是我应该太过在乎的事情(你的上百万电子商务程序)"。 所以说,人们对这些开源项目的开发者应该给予一些尊重。
Leo Laporte: 开源是如此繁荣,我想说你们这些人才是开源社区的源动力,我们所能做的就是给予你们以应得的尊重。
Chris DiBona : 恩, 我发现 Rasmus 的车子有点脏了,呵呵
Leo Laporte: 呵呵,我愿意为他擦洗车子,我欠他的太多了,我在服务器上运行了那么的 php 程序 ,从日志跟踪程序到 drupal .
Rasmus Lerdorf : 你不欠我什么,不欠我任何东西,我们 php 项目现在有 1100个开发人员。
Chris DiBona : 看来你现在已经把移交工作做的很好了
--------------------------------------------------------------------------------------------
Leo Laporte: 1100 个开发者可不是个小数目啊。
Rasmus Lerdorf :是的, 如果你修复了 PHP 项目的一个bug, 发来一个不错的补丁, 那么PHP 社区就非常欢迎你的到来。
Leo Laporte: 我知道Perl 社区老早就说起开发 Perl 6 了, 不知道 PHP 6 的号角是否已经吹响.
Rasmus Lerdorf :我们不太善于做市场方面的工作, 但是 PHP 6 工作的确正在进行了.
Leo Laporte: 跟我们讲点这方面的事情吧
Rasmus Lerdorf :PHP 6 最大的一部分改进在于对 Unicode 的支持. PHP 6 任何一部分代码都是基于 utf16 编码的.
Leo Laporte: 这大概是 PHP 6 大部分被重写的地方之一吧.
Rasmus Lerdorf :是的, Unicode 很艰深, 我跟 200 多名懂得 unicode 的开发者开过一个会, 其中包括一些日本的开发人员,他们工作于 IBM 公司, 知道很多 ICU 项目的东西. ICU 是 IBM 的 Unicode 项目, 当时 ICU 项目并不是很好, 它太大了. 它的代码比 PHP 的源码还大, 差不多有10倍了吧.
Leo Laporte: 等等, 你说什么, ICU 项目的代码量是 PHP 的10倍
Rasmus Lerdorf :它太庞大了, 太让人吃惊了, 而且它不是模块化的, 这意味着你无法从中取出你所需要的部分. 但是现在 ICU 也发展了, 我们可以取出我们需要的部分, 所以如今在 PHP 项目中加入 ICU 支持是可行的, 这使得 PHP 可以在任何地方完全支持 Unicode , 这是 Php 6 最大的改动, 此外的改进还有“命名空间”等其它特点.
Chris DiBona :那其它的库是否也要因此重写以支持 unicode 呢?
Rasmus Lerdorf :你说的是库和扩展吧, 有一些函数是要重写的, 基本上涉及到传递字符串或者操作字符串的函数都需要重新审核一下, 是的,这是很大的工作量. 大概在年底会有一个alpha 的测试版发行, 这个版本只是说: 大家看看,测试一下, 看看你现有的代码中有多少因为采用这个版本而无法运行, 估计大多数 Php 5 的代码都不会有什么问题, 我们并不担心, 或许你马上就可以利用它实现一些 unicode 的有趣功能. 如果你正确使用它, 熟悉这个版本的过程中就不会有太多的麻烦, 不过也有可能出现一些我们没考虑到的问题, 所以我们希望尽早发布测试, 而不是像某些语言一下等上5年.
Leo Laporte: 我在自己的服务器上运行的是 php4, 顺便说一句, 非常感谢你们的工作, 开发了这么好的产品. 像很多人一样, 我使用的是 Php 4
Rasmus Lerdorf :恩, 它的确工作的很好, 如果你没什么必要的话, 也可以不升级...
Chris DiBona :火是很可怕的( 注解: 5(five) 和 fire 英文发音相同)
Leo Laporte: 哈哈, 是的, 我并不怕火, 呵呵, 我只是不想换版本, 因为它现在工作良好, 是吧?
Rasmus Lerdorf :是不应该害怕升级的, 直到我们认为完全可以抛弃这个版本之前, 我们将继续提供 php 4 的安全补丁. 对于大多数产品来说, 在 php 4 上良好运行的程序都应该在 php5 上运行. 最困难的是那些大型的 ISP, 它们有成百的用户, 上千个运行的 PHP 程序, 其中若是有几个程序无法运行, 这对他们来说,的确很可怕, 如果没人抱怨升级的问题, 的确没这个必要冒险去升级版本. 但是 PHP 5 的确有一些很吸引人的功能, 比如简单 XML 处理支持, Soap 扩展, 相当快的 Soap 处理, 如果你程序中要处理 Web 服务, 需要解析大量 XML 那么用 PHP 4 来处理就相当痛苦了, 这是我们分支出 PHP 5 版本的主要关注点.
Leo Laporte: 好吧, 为了支持 PHP 5 我要去重新编译我的 Apache 了, 你们两个继续谈.
Chris DiBona :好啊, 待会见.
Leo Laporte: Twit.tv 服务器宕机了, 我一会再来.
Chris DiBona :你可以给 Rasmus 写邮件.
Leo Laporte: 你能给我写代码吗? Rasmus
Chris DiBona :奇怪, Drupal 好像运行 Php 5 没什么问题?
Leo Laporte: 我也不知道为什么我要运行 php4, 好像Drupal 最新版本 5.1.4 重新编译支持 php5 , 如果没有什么特别的原因, 是否应该将程序运行从 PHP 4 转到 PHP 5 呢?
Rasmus Lerdorf :恩 ...
Chris DiBona :会运行更快一些吗?
Rasmus Lerdorf :也许不会那么快吧, 有一些程序会运行的很快, 有一些程序的运行速度和原来差不多, 这取决于你的代码做什么, 如果你的代码恰巧使用了我们做大量工作优化的部分, 那么速度就会很快, 否则就和原来速度差不多.
Leo Laporte: 让我们来谈谈人们常常说的 PHP 的一些问题吧, 有一些人经常抱怨 PHP 的性能问题, 我从来没碰到这些困扰, PHP 的扩展性很好.
Rasmus Lerdorf :你混淆了两个概念, 性能和扩展性没有什么联系。
Leo Laporte: 是吗? 让我们来谈谈这个.
Rasmus Lerdorf :是的, 性能是单一服务器对单一请求的服务有多快; 而扩展性是指你能扩展的宽度, 比如, 如果你有10万个并发访问, 你如何能将它控制在一定的响应时间之下.
Leo Laporte: 我想两者都很重要,但是扩展性更重要一些
Rasmus Lerdorf :是的, 但是从某方面说, 性能也很重要, 你可以更换一个更快的CPU, 但是无法并排放大量的服务器, 如果单一请求的响应延迟是半秒钟, 那么并排放500个服务器, 除非你有大量的访问请求, 否则每个请求的响应时间还是半秒钟. 性能问题跟响应延迟有关, 你可以在单一服务器上服务于更多的请求, 扩展性则更多与架构有关, 你要确定你所做的不要和某个服务器紧密绑定, 我们在 PHP 中做的很多事情都有这么一个概念叫做"share nothing"的架构(不共享任何东西), 就像一个 "PHP 黑箱", 你接受一个php 请求, 然后处理该请求, 任何关于这个请求的东西都在这个请求结束后消失, 没有什么东西可以跨越请求存在的, 你要建立一个这样的系统, 每个请求都是相互独立存在的, 因为每个请求可能来自不同的服务器, 你可能在一个负载均衡程序的后面放了 500 个服务器, 那么程序也能将照常运行. PHP 的 Session 机制默认是保存在本地的 tmp 目录中的, 但是我们提供了一个很简单的机制将 session 保存在数据库中, 所以我们在 php 中做的任何事情都保证它是可扩展的, 这也是为什么yahoo 和 flick 的程序员采用 php 的原因. 因为扩展性是内建在 php 之中的. 有人说 php 是不可扩展的, 是因为他们不了解如何去实现扩展性. 就我而言, 我们没有碰到任何扩展性的问题, 所以你可能看不到我们关于扩展性方面讨论的文章. 但你不能说, PHP 不可扩展仅仅因为我们没有讨论它的可扩展性问题
Leo Laporte: 哈哈
Rasmus Lerdorf :有时候这真让人头疼. 恩, 关于性能的问题, 你能做的事情不多, PHP 像大多数脚本语言一样, 分为两步访问. 首先是将磁盘上的文本编译为 op-code , 然后将 op-code 传递给执行程序, 这有点像 Java 的字节码. 我们可以把 op-code 放到缓存中, 比如我们已经用了多年的 APC , 还有其它一些产品. 它们将编译好的 op-code 放到共享内存中, 如果第二次请求 php 脚本的时候, 我们将看到, 嗨, 检查一下共享内存, 这是 inode , 我们的共享内存中是否有这个缓存过这个 inode 块, 如果有的话, 我们可以直接执行共享内存的 op-code , 这将会使得代码提速达30至40 倍之多.
Leo Laporte: 这有点类似 python 的 pyc 字节码, 只是你没有在磁盘上保存编译的版本
Rasmus Lerdorf :是的, 因为性能最慢的地方就是读取磁盘.
Leo Laporte: 这并不能节省多少时间, 是吧?
Rasmus Lerdorf :是节省不了多少, op-code 本身就是很小的文件, 500 字节和1000 字节在文件系统中可能都是占用一个块, 你从大小上节省不了什么. 相反你应该避免这种磁盘操作, 任何这类操作都是挺耗费时间的. 不经过任何拷贝操作, 直接从共享内存中执行代码是最快的. 如果我们修改了磁盘上的代码, 我们需要告诉 APC , 可能需要重新启动 web 服务器.
Leo Laporte: 这么说系统需要足够的内存以运行程序了
Rasmus Lerdorf :所有高性能的网站都会用到缓存的
Leo Laporte: 这么说我们将为运行 PHP 投入更多的内存了.
Chris DiBona :那么 Zend 提供了些什么, 更好的解析器? 他们确实在销售一些性能优化的产品.
Leo Laporte: 他们也有一些缓存的产品吧
Rasmus Lerdorf :一样的, 他们本身也没有 op-code 缓存, 他们也提供这方面的缓存产品, 你可以选择.
Leo Laporte: 你有自己喜欢的缓存产品吗?
Rasmus Lerdorf :我比较喜欢的是 APC , 不是我创建的它, 别人创建的, 我只是帮着他们让其良好运行. 我需要一个缓存得以开始这方面的工作.
Leo Laporte: 习惯上, 如果你运行一个访问量比较大的网站, 通常都会要用到一个缓存系统.
Rasmus Lerdorf :是的,你应该有一个, 你可以从 Zend 公司购买, 或者试一试开源的缓存系统.
Chris DiBona :APC 是什么意思?
Rasmus Lerdorf :Alternative PHP Cache, PHP 是开源语言, 所以我们需要一个开源的缓存系统, APC 运行的很好.
Leo Laporte: 不错, 我要在我的服务器上实验一下. 谈谈 PHP 的安全性吧, 你对安全性考虑的有多少?
Rasmus Lerdorf :这么多年有很多讨论 PHP 安全性的问题, 我觉得有一些是正常的, 大多数批评对 PHP 是很不公平.
Leo Laporte: 有很多不好的实现
Rasmus Lerdorf :的确有很多很烂的代码, 我们无法把他们都修复了, 有一些错误的确是我们的问题, 我们的程序确实有 bug , 我们会尽量正确地修复它. 但是还有很多是我们无论如何都无法解决的. PHP 比别的语言跟容易出现这种问题, 因为它比其它语言更容易学习, 也就是说越是缺少编程经验的人越容易采用 PHP , 有一些代码的确写的不那么安全, 结构也不好. 而且 PHP 项目的命名也是个问题, 人们总喜欢用 PHP 来命名自己的项目.
Leo Laporte: 是啊, 宝贝, 这可是用PHP写的. 不用其它名字来命名项目了.
Rasmus Lerdorf :呵呵, 我也不知道为什么我们会有这个问题, 别人就不会起 Python Mailman 这样的名字. 其它语言开发的项目不会起名为 Perl XXX, Python XXX, Ruby XXX , 当然 Ruby on rails 是个例外. 你看, 这么多项目都以 PHP 命名, 他们似乎都想打上 PHP 的标签.
Leo Laporte: Php Myadmin 也是其中之一, 有很多这种方式命名的项目
Rasmus Lerdorf :任何一个关于这些项目的 bug 都会归到 PHP 头上, 如果 Mailman 出现了安全性的问题, 你的第一反应不是 Python 出了什么安全性问题, 至少通过名字关联不会这么想, 你最多只是说:"Mailman 这程序太蠢了", 如果 PHP 的项目出了问题, 他们就会说:"PHP 又出问题了, 这个语言的确不安全, 看看这些问题吧"
Leo Laporte: 你有什么类似 perl 的一些措施限制程序员去做正确的编程吗?
Rasmus Lerdorf : 我们有很多级别的错误报告机制, 你可以打开开关,如果你访问一些未赋值的变量, 就会出现警告等等。
Leo Laporte: 你在 yahoo 工作
Rasmus Lerdorf : 是的
Leo Laporte: 它们用了很多 php 代码, 你可以说说他们都是在什么地方采用 php 开发的。
Rasmus Lerdorf : 几乎所有 yahoo 网站都采用了吧
Leo Laporte: 是吗? 这倒是可以作为 php 扩展性的一个好的典范, 任何人说 php 扩展性不好的,都可以去看看 yahoo . yahoo 的邮件系统也是用 php 写的吧
Rasmus Lerdorf : 老版本的邮件系统不是基于 php 的。
Leo Laporte: apple 的网站是基于 php 的吗?
Rasmus Lerdorf : 说实在的,我也不知道。
Leo Laporte:它们大部分都是基于 javascript
Rasmus Lerdorf : apple 的网站很多都是基于客户端的技术,我不知道它们有什么地方用到了服务端的技术, 客户端也不是我所关注的技术。
Leo Laporte:我非常喜欢 Yahoo 的邮件系统, 它可是 ajax 技术运用的一个良好示范啊。太感谢你了,Rasmus,给我们提供了这么好的语言, 可以做许多强大的事情。
Chris DiBona :非常方便
Leo Laporte: 1100 名开发人员, php 社区可真是强大啊, 真让人惊奇。
Chris DiBona : Pretty Handy Processor (Chris 开玩笑解释 PHP 命名)
Leo Laporte: 哈哈,你又来了, 不过这个解释我喜欢
Rasmus Lerdorf : 大概是人们讨厌 Perl 吧。
Leo Laporte: 哈哈, 这个理由我接受。
Rasmus Lerdorf : 对不起,对不起,Larry ( Larry 是 Perl 语言的创始人)
Leo Laporte: 我们确实想采访一下 Larry 。