本节书摘来自异步社区《写给PHP开发者的Node.js学习指南》一书中的第1章,第1.3节,作者【美】Daniel Howard,更多章节内容可以访问云栖社区“异步社区”公众号查看
1.3 Eclipse PDT
写给PHP开发者的Node.js学习指南
学会如何分析堆栈追踪信息是PHP到Node.js成功转换的一个重要技能。堆栈追踪是查找代码错误的一个诊断工具,就像医生用X光来检查病人一样。从某种观点来看,PHP到Node.js的转换可以类似于一个复杂的外科手术。你要对PHP和Node.js代码进行手术。像手术过程一样,转换需要技巧和耐性,但是一个好的环境也有很大帮助。就像手术室中使用X光一样,堆栈追踪就是转换过程中开发环境中的工具。下一步,我们会讨论集成开发环境,为转换过程提供类似“手术室”一样的环境。
很快你可能就需要面对几十个PHP文件,成千上万行的PHP代码,紧接着,几十个Node.js文件和成千上万行的Node.js代码,一个简单的文本编辑器无法有效地追踪所有的内容完成转换。对于尝试一个简单的例子来学习如何使用Node.js编程来说,文本编辑器足够了,但是在面对大量的PHP和Node.js代码时,你需要更有效的工具。
在开发PHP或者Node.js本身时,你可能会选择一个单语言支持的集成开发环境(IDE)直接使用。Eclipse PDT(PHP Development Tools)是一个非常流行的PHP IDE,用Java编写,由Eclipse基金创建。其他的还有Zend Studio、PHPEdit和Dreamweaver。对Node.js来说,选择就比较少了,并且对其适用范围和有效性持怀疑态度。在写本书的这个时候,我知道的有Komodo Edit、nide和Cloud9。
然而,你的目标是将PHP代码移植到Node.js,同步地改进两个代码库并添加新的特性。为了有效地完成这一过程,我推荐使用Eclipse PDT,需要做一些修改来支持Node.js。还需要知道的是如何在转换过程中更容易地对比PHP和Node.js代码。
现在,在我开始介绍如何为PHP到Node.js转换过程设置Eclipse PDT之前,我需要为那些拒绝使用类似工具坚持使用文本编辑器的开发人员做出声明。他们说,“我只使用vi”。如果你也是这么想的,那么你可以跳过本章其余的部分然后用任何你觉得对的方法设置你的转换环境。我会在这里介绍如何安装以及配置Eclipse PDT,只是因为对我来说它是一个非常重要的工具,帮助我将PHP代码移植到Node.js,对其他开发人员来说这也会是一个非常有用的工具。
要安装Eclipse PDT,首先下载Java。所有Eclipse IDE都是Java开发的,需要Java运行环境,当然包括Eclipse PDT。我偏向于安装Java JDK而不是JRE。在编写本书的这个时间,我使用jdk-6u29-windows-i586.exe。
下一步,浏览http://eclipse.org/pdt/downloads。考虑使用Zend Server Community Edition(CE)安装,这包含了Eclipse PDT、Zend Server HTTP 服务器、内建PHP调试支持,还有MySQL数据库。我假定你的PHP Web应用使用MySQL数据库,或者至少可以支持MySQL数据库。
在写书的时候,Eclipse PDT下载页面上有下载PDT和Zend Server Community Edition的链接。如果链接不存在了或者你有其他的Web服务器,可以根据你的操作系统下载合适的Eclipse PDT。然后可以跳过以下几段,一直到讲解安装和配置Eclipse PDT的段落。按照链接下载Eclipse PDT for Zend Server CE。现在,我用的是zend-eclipse-php-helios-win32-x86.zip。解压但是暂时不要运行Eclipse PDT。
在同一个页面上,下载Zend Server CE。我使用的是ZendServer-CE-php-5.3.8-5.5.0- Windows_x86.exe。
安装Zend Server CE。简要来说,一直选择默认的选项直到Setup Type 页面。选择该页面的Custom按钮而不是Typical,然后点击下一步。在Custom Setup页面勾选“MySQL”Server。然后完成安装。
到这里,Zend Server CE会显示一个浏览器页面来进行配置。我们这种情况并不需要对服务器本身做任何特殊配置。
安装MySQL 数据库服务器,并配置其作为Zend Server CE安装包的一部分。默认情况下MySQL数据库服务器root密码为空字符串(也就是“”)。
运行Eclipse PDT。Zend Server CE是基于Apache2,有一个htdocs文件夹。当Eclipse PDT运行时,会查找并选择htdocs文件夹作为Eclipse PDT的工作空间文件夹。如果你使用Zend Server CE或者Apache之外的Web服务器,选择文档根目录作为Eclipse PDT的工作目录,部署到Web服务器的PHP文件就可以在适当的位置进行修改了。
这并不在本书范围之内,但是如果你愿意,可以在你现有的PHP代码库上尝试使用PHP debugger。
Eclipse PDT和你的Web服务器是你的转换开发环境的基础。现在,我们来做一些修改,学习如何使用Eclipse PDT有效地管理和实现转换过程。
Eclipse PDT本身已经支持JavaScript文件,而Node.js本身就是JavaScript,所以也可以支持Node.js。但是.njs并不是标准的文件扩展名,所以Eclipse PDT并不会认为.njs文件是Node.js文件。所以如果在Eclipse PDT里打开.njs文件(例如,httpsvr.njs),会显示成文本文件,没有像一般JavaScript文件(.js)的语法提示颜色,也没有代码补充提示。
为了使Eclipse PDT将.njs文件作为Node.js文件,在Eclipse PDT主菜单里打开Window菜单,选择Preferences菜单项;然后你可以看到Preferences对话框,包含两个窗格(图1-1)。在左侧的窗口,你会看到一个preferences的目录和子目录组成的树形层级结构。右边的窗口,你会看到一个按左侧窗口选定目录的可以浏览和编辑偏好选项的对话框。
在左侧窗口中,打开General 文件结构,选择Content Types选项。在右侧窗口中,你会看到content type的列表。在右侧窗口中打开Text树形文件夹。在Text目录下,选择JavaScript源文件。当你选择了JavaScript源文件,你会看到一个列表框,有一个选项“.js”,在“File associations”列表框中,还有一个Add按钮在窗口的右中位置。单击Add按钮,会弹出Add Content Type Association 对话框(图1-2)。你可以在“Content type”编辑表中输入“.njs”。
然后,在所有打开的对话框上单击OK按钮保存修改。
保存修改完成后,对保存为.njs的Node.js源文件,JavaScript语法高亮和代码补全功能会生效。
语法高亮对.njs文件生效后,你可以通过单词的错误颜色注意到一些简单的Node.js语法错误。对任何编程项目来说,肉眼检测都是很重要的一部分,尤其是PHP到Node.js的转换过程。另一个有用的肉眼检测技术是使用一个先进的可视化对比工具来比较PHP和Node.js代码,可以看到所有的东西,包括转换的质量和进度。
对比工具可以显示两个文件的差异。简单的基于文本的对比工具一般会将每个文件的每一行的差异作为单色的文本输出。这种对比工具对于分析PHP和Node.js的转换没有太大帮助。我们需要更高级一点的对比工具。文件需要并排显示而不是作为交替行文本;需要颜色对比,而不是单色;显示到字符级别的差异而不是只显示不同行的内容。
Eclipse PDT内建了一个不错的可视化对比工具。我们可以使用这个工具来对比一个.php文件和其对应的.njs文件。使用的时候选中.php和.njs两个文件,右键单击,选择Compare With 子菜单然后在该菜单内选择Each Other菜单项。图1-3是使用 Eclipse PDT对比工具对一个简单的.php文件和对应的.njs文件进行对比的截图。
你并不需要详细了解这个特性是如何工作的,只需要看到PHP代码和Node.js对比相似度即可。
左边是rand.njs文件,右边是rand.php文件。文件的差别用灰色显示,匹配到相似的字符用白色显示。
注意到有些行几乎完全是白色,除了一个美元符号($)是灰色。PHP和Node.js在同样的地方使用同样的关键字function,并且函数名位置也相同。多年以来,这成为各种新的语言的共性,避免语法结构的变化,采用相似的语法,比如定义函数。同样,也注意到while语句也基本一致。
这对开发人员来说是有好处的,对比php和.njs文件会变得更容易。
Eclipse PDT自带的可视化对比特性很好但是并不绝对可靠。有些时候,在文件中移动代码则希望可视化对比工具可以找到更多匹配的内容,这就是说,该工具会在两个文件中显示更多的白色。在文件中拷贝一个函数的时间与代码的表现和功能无关,但是可能会使可视化对比工具更精确地进行代码匹配。在转换过程中值得花一些时间来尝试在每个文件中移动代码,看看会对对比结果产生什么影响。
在Eclipse PDT中,代码既可以在单独的窗口中编辑,也可以在对比窗口中。如果在独立的窗口中编辑并且保存,任何显示该文件的对比窗口都会重新加载该文件并且重新进行比对。可视化对比工具的普遍实现都是在独立窗口中编辑代码之后对比窗口重新加载。
一般来说,将两个文件中的代码保持相同的格式,使用相同的名字(比如函数和变量),包括重构一个或者两个文件中的代码,都有助于对比工具找到尽可能多的匹配代码。
为了保持PHP和Node.js代码同步改进和添加新的特性,你需要依赖于对比工具确保PHP和Node.js代码的正确性。慢慢地,开发人员就可以培养一种感觉知道匹配到什么程度是最好的。
当匹配度不够时,对比工具就会偏离其本来的功能,尝试将.php文件中的PHP代码和.njs文件中的Node.js代码进行对比,这并不意味着匹配。会有很多表示差异的灰色的高亮,无法匹配。经常尝试修改可以纠正这种问题。
当白色高亮太多时,意味着.njs文件中的PHP代码没有完全转换为Node.js代码。即使.njs文件可以解析并且运行,太多的白色高亮意味着需要更进一步的转换。经常对Node.js代码进行肉眼检测会发现还没完成的一些特定转换。一个很容易忘记的转换就是给PHP变量加上美元符号($),Node.js变量不需要美元符号。给PHP代码中加上美元符可以减少白色匹配高亮,使对比工具接近于正确的匹配度。
视觉上的对比,特别是使用对比工具,要比交互式的测试PHP和Node.js代码快很多。肉眼检查可以作为“通烟测试”(Smoke Test)来检测转换过程是否接近正确。自动化测试用例,不在本书讨论范围内,可以快速检测移植的正确性与否。
在本书中,你有机会将一大段特定的PHP代码转换为对应的Node.js代码元素。例如,PHP中使用array()函数创建数组,而Node.js中,一般使用文字符号,比如花括号,创建数组。在转换开始时,拷贝了整个.php文件的代码到.njs文件进行转换,.njs文件中肯定包含很多PHP array()函数,需要被替换成Node.js对象的符号。一个简单的处理办法是使用Eclipse PDT的Find/Replace功能来进行“array(”的全局替换(全部替换为左半边花括号)。如图1-4所示。
这个对话框的使用非常简单。
本书使用文本速记来代替每次说明Find/Replace对话框时的截图。对上图中的Find/Replace对话框来说,使用以下文本作为替换:
有两种不同的使用Find/Replace对话框方式。
一种方式称为无条件(blind)全局查找替换操作。如图1-4所示。
称之为“无条件”是因为该操作会在文件中一次完成所有查找和替换操作,不提示警告信息,不需要手动干预。如果所有的Find/Replace对话框都经过测试并验证为安全的,无条件的全局查找替换操作速度快并且准确。但是,如果结果出现错误,只有两个选择:撤销之前的操作或者进行一次新的替换纠正前一次的错误。
值得一提的是对于查找和替换纠正工作的第二个选择。有些时候,一个简单易于理解的替换操作可能正确地替换了298处代码,但有两处替换错误,要比一个复杂的查找替换操作正确替换了300处代码好很多。手动查找和修复一些边缘案例是值得的,并不是所有的事情都需要完全自动化。即使PHP到Node.js的转换过程是一个漫长的过程,你也不需要一遍一遍重复操作。本书介绍的并不是“持续转换”,而是将转换作为一次性事件。所以对于完成工作来说完全可以接受手动查找和修复少数边缘案例。
第二种使用Find/Replace对话框的方式是全局查找单步替换操作。首先,Find/Replace对话框用于查找第一个匹配到的内容所在。开发人员检查该处是否需要手动修改代码(可以通过点击该处代码而不需要关闭对话框)或者执行替换(点击Replace/Find按钮),或者跳过当前所在查找下一处匹配(再次点击Find按钮)。以下是单步全局查找替换操作的简介:
Eclipse PDT中的Find/Replace也可以使用正则表达式。正则表达式是一种模式匹配技术:正则表达式用于描述一种搜索的模式,而不是准确的内容。每次找到匹配模式时,匹配上的内容都作为待替换区域。比如,如果数组正则表达式((.))匹配到了array(id=>‘name’),正则表达式中的(.)则表示内容id=>‘name’。这段内容被称为匹配字段,或者有时候被称为匹配组。在Eclipse PDT Find/Replace对话框中,匹配字段由它周围的括号决定。为了使匹配字段成为替换字段,匹配字段会按照匹配到的顺序列举出来。美元符($)用于描述一个特定的匹配字段,后面的数字表示匹配字段的编号。例如,替换区域中的$1表示第一个匹配字段,在之前的例子中表示id=>‘name’内容。一般情况下都只有一个匹配字段,所以经常使用的都是$1,很少看到$2、$3或者更多的。
以下表示使用正则表达式的无条件查找替换操作:
正则表达式的使用不包含在PHP到Node.js的转换过程中,所以本书并不会介绍如何理解和编写正则表达式相关的基础知识。所以正则表达式都是作为查找替换操作中的一部分,可以拷贝到Eclipse PDT Find/Replace对话框中的对应区域,你不需要去理解或者修改这些正则表达式。如果你确实需要正则表达式相关的帮助或者需要理解正则表达式的规则和它们的工作原理,鼓励你去研究Eclispse PDT,使用Google或者其他搜索引擎,查找网页、博客或者论坛来回答你的问题。
大部分时候使用正则表达式的查找替换操作比逐字逐句的替换查找(比如只匹配到一个特定的字符串)更容易理解并且效率更高。一个正则表达式可以使匹配的内容更加灵活,并且通过匹配字段,将匹配到的内容作为Replace字段。一般来说,按字符查找替换一次只能匹配到代码的开始或结尾,代码元素的中间部分可能有变化。而正则表达式,中间部分可以匹配某种模式,一次的替换查找操作就可以匹配整个代码元素。当这种代码元素的替换可以在一次查找替换的操作中完成,发生错误的概率就降低很多。
截止到这里,本章介绍了如何建立PHP到Node.js转换环境的一系列操作和相关知识。第一件事是下载Node.js本身,熟悉自带的两个命令。之后,通过调试Node.js堆栈追踪信息来学习如何阅读堆栈信息以及根据该信息找到定位问题背后真实的深层次的原因。接下来,安装Eclipse PDT作为开发环境的基础,包括对配置的修改使其支持.njs文件,专注于PHP到Node.js的转换。最后,了解了转换过程中很重要的可视化对比工具以及查找替换操作。
一个好的开发环境对提高开发效率以及完成工作至关重要。很多时候,业余的开发人员会陷入在编程的过程中而忽略了开发环境的重要性。最开始的时候,在任何环境下都可以很快开始开发工作,因为这个时候代码量较少容易改进。当代码库逐渐增长,代码的复杂度逐步上升,开发的速度就会降下来了。一个低效率的开发环境在复杂度层面上对开发人员没有任何帮助,但是一个好的开发环境可以帮助开发人员简化必备的知识维持开发速度,直到项目结束。
在PHP到Node.js的转换过程中,我们假定已经有一个很大的PHP代码库。在转换结束的时候,期待代码库在规模上可能会翻倍:PHP代码会因为转换进行重构,但不会缩减,所以代码量会增长。当然,还会添加一个完整的Node.js代码库。原始的PHP代码库可能由很多人合作开发,但是转换过程中的耦合太多一般是由一个人完成主要的工作。所以,对原始的PHP代码一个基本的开发环境也许就足够了,但是想要移植到Node.js则需要一个更复杂的开发环境。
如果一个项目已经有了一套自己的开发环境,也许不会选择Eclipse PDT。Eclipse PDT只是一个可用于转换的可工作的典型开发环境。其他的开发环境如果支持本章之前提到的各种特性,也可以使用。总而言之,开发环境需要支持.php和.njs文件的语法高亮,对两个文件进行单次级别的可视化对比而不仅仅是代码行级别,以及支持正则表达式的查找替换操作。
现在,转换过程的所有准备工作已经就绪,我们可以开始创建.njs文件来保存新的Node.js代码。在下一章中,会介绍一个初始.njs文件的模板,之后的章节中,PHP代码会被重构,复制到Node.js文件中,然后转换为可运行的Node.js代码。