以前每当一个 Zend Studio 的新版本发布时都会同时发布一个新版的 Zend Studio Server 组件,这个组件可以让我们很方便地进行远程调试。但是自从 Zend 发布了 Zend Platform 以后他们就不再更新 Zend Studio Server 组件了。这就导致我们只能远程调试 PHP 5.1.x 的环境,而不能调试 PHP 5.2.x。要想调试 PHP 5.2.x 只能装一个庞大的 Zend Platform。:(
因此我一直在找一个“轻量级”的解决方案。近日在逛 Zend.com 时发现了一个好东西:Zend Studio Web Debugger,直觉告诉我,这就是我想要的。果不其然,今天试验成功!
下面就说一说我的试验步骤:
- 到这里下载 Zend Studio Web Debugger,然后将其解压到某一目录,比如:C:\Program Files\Zend,这就会在该目录里面新建一个 ZendDebugger-5.2.14-Windows-i386 子目录,里面有 4_3_x_comp、4_4_x_comp、5_2_x_comp 等目录,将这些 x_y_z_comp 分别改为 php-x.y.z(比如将目录 5_2_x_comp 改为 php-5.2.x);
- 确保已经加载了 Zend Extension Manager,如果安装了 Zend Optimizer 则会自动安装 Zend Extension Manager,若没有安装请先安装 Zend Optimizer 。或者你可以把 Zend Optimizer 中 Zend Extension Manager.dll 给提取出来,然后手工在 php.ini 中添加一行:
zend_extension_ts="C:\Program Files\Zend\ZendOptimizer\ZendExtensionManager.dll"
其中 ZendExtensionManager.dll 的位置请根据你的实际情况填写;
- 在 Web Server 的 php.ini 添加下面几行:
zend_extension_manager.debug_server_ts="C:\Program Files\Zend\ZendDebugger-5.2.14-Windows-i386"
zend_debugger.expose_remotely=allowed_hosts
zend_debugger.allow_hosts=127.0.0.1/32,192.168.1.0/16
zend_debugger.allow_tunnel=127.0.0.1/32
zend_extension_manager.debug_server_ts 的值请根据你的实际情况填写,就是 php-x.y.z 的父目录。
- 把 ZendDebugger-5.2.14-Windows-i386 目录下的 dummy.php 复制到你的 Web 站点根目录。
- 重启你的 Web Server,OK!
简单总结一下:Zend Studio 的远程调试功能是由 Zend Studio Server 组件(ZendDebuger.dll)提供的。本质上这是一个 Zend 扩展,因此你只要能把这个 Zend 扩展启用就可以了。只是 Zend 公司出品的 Zend 扩展只能由那个 Zend Extension Manager 负责加载,所以我们才需要做一些额外的步骤,否则只需简单地加一行 zend_extension_ts = xxxxxx
而已。
这些日子在看 .NET CLR 方面的书籍。由于和 Zend Engine 一样同属虚拟机运行方式,因此不可避免的就要互相比较一下,感触颇多。下面将我在这些天在看书时想到的一些对 Zend 可能有用的一些想法写一下,欢迎大家探讨。
Zend Engine 将 PHP 的执行机制划分为编译和执行无疑是革命性的举动。但现在看来,这似乎还未完全将这个思想贯彻到底。当前的 Zend Engine 虽然把编译和执行分成两个步骤来做,但这两个步骤对一个普通 PHP 脚本文件来说确是连续的。换句话说,当 web 服务器开始处理一个 PHP 脚本请求后,它将不得不每次都进行编译和执行两个步骤。很明显,对于一个开发完成不再进行经常性的修改的 PHP 脚本来说,这将是巨大的性能损失。
PHP6 或许会解决这个问题,但我估计和目前 eAccelerator 的解决方案类似。当脚本第一次运行后,以某种方式保存编译后脚本,在我们规定的缓存有效时间内,当第二次运行该脚本时就不在进行重复性的编译工作,而是直接调用前面保存的编译后文件,大大提高了程序性能。
但是,这是否就足够了呢?根本不够!还需要在此基础上再大胆地迈出一步,将编译和执行完全分离!即像普通地二进制 PE 文件一样,PHP 可独立解释编译后的文件!实现方法并不复杂,我们不妨约定一个编译后文件格式,并且让其开头几个字节为“ZIC”作为该类型文件的标识(姑且让我们暂称之为 PHP/Zend 中间码形式的可执行文件,以下简称 PHP 可执行文件)。若 Zend Engine 检测到某个文件为 PHP 可执行文件,则跳过编译函数直接调用执行函数开始执行代码。
慢着,你这不是和 eAccelerator 或 Zend Optimer 一样吗?是一样,但又不一样。说一样是因为运行效果一样,说不一样那是因为编译过程可以不放在 Zend Engine 里面!这意味着什么?这意味着 Zend Engine 将成为和 Windows 一样性质的虚拟机,即执行工作我 Zend Engine 来做,编译工作交给独立的 PHP 编译器来做。由于 PHP 可执行文件格式公开,那么各个公司、团体或个人都可以来开发相应编译器。编译效率高、可执行代码性能好编译器自然就会更受到市场的追捧,你可以想像市场对这种编译器的需求。Zend 只是 PHP 编译器的实现厂商之一。当然,由于 Zend 公司在 PHP 方面的特殊地位,Zend 公司出品的 PHP 编译器无疑会具有很大的先天优势。但不管怎样,这要比只有 Zend 团队自己来做要好很多。有竞争才会有进步嘛!这就像 Micosoft 之于 .NET 的 CLR,以及众多的 C/C++ 编译器之于 C/C++。
以上仅仅是好处之一,同时也是下面我谈的改进 Zend Engine 的种种设想的基础,没有上面机制的实现,那下面的几条设想也就无从谈起。
首先,我们可以像直接书写汇编代码一样直接书写中间代码。当然,这对开发人员有很高的要求。但对于 PHP 编译器的开发商来说,确实不可缺少的。
其次,增加 #define、#ifdef、#ifndef 这样条件编译指令。最好由 PHP 官方直接增加,不得已也可以让各 PHP 编译器厂商扩展增加这样的指令。反正最后产生的 PHP 二进制代码,不怕 Zend Engine 不运行。这样做的好处也是巨大的。我们可以根据适当的编译指令编译出 PHP4 版本的代码、PHP5 版本的代码,甚至是只限于 PHP5.1 的代码,在缩减代码长度,减小对内存需求的同时也更增加了程序的运行速度。自然的,我们也可以根据需要编译出标准版或者专业版等等的代码。更可以想到的,传统程序的编译优化,开发技巧都可以大批量的应用到 PHP 开发上。
再次,这也在一定程度上保护了源代码安全,至少不需要分发源代码了。而且跟 Open Source 并不冲突,若开发人员愿意,也可以在分发程序的同时分发源代码。
最后,提供对类似在 ASP.NET 中 web.config 文件(比如 php.config、app.config.php 等)的支持。此处关于这个文件的作用我不再多讲,感兴趣的朋友可以去 google 一下关于 ASP.NET 中 web.config 的信息。
这些就是我这些天对改进 Zend Engine 的一些思考。应该说,这些东西都是非常容易实现的,而且在 Zend Encoder/Zend Optimer 身上已经实现,Zend Encoder 就是一个编译器,Zend Optimer 也是一个独立执行器!
但这并不会给 Zend 公司带来业务上的冲突。相反,这会给 Zend 公司带来更多的发展潜力。前面已经提到过,Zend 公司在 PHP 编译器方面的先天优势可以说是巨大的。这一点无庸讳言。Zend 不应该定位在“我可以实现它”的层面上,而应该定位在让大家“都能实现它”但我是“实现最好的”这个层面。通俗点说,就是先让大家都来玩,都能玩,但是只有我才我能让你们玩得最爽!
再来谈谈 Zend Studio。Zend Studio 怎么发展?简单!学 Microsoft Visual Studio!做一个真正的 IDE,集成最 Cool 的编译器,完善的项目管理机制,再加上负载测试,想想都让人流口水~ 只是有一句话憋了很久了,别再用 Java 做 IDE 了。这只是方便了 Zend Studio 的开发人员,但却没有方便 Zend Studio 的使用人员,而且还给 Java 这个竞争对手露了脸。唉,不知道 Zend 公司是怎么想的~
最后再说说 Zend Encoder,加密会降低程序性能,混淆才是王道。混淆只是一种内存指针的替换,名字对于 CPU 来说无关紧要,但这对开发人员来说却很致命。有策略得进行混淆加密,完全可以在牺牲很小性能的情况下极大的增加反编译强度。这些方面,我以后有时间会再整理一下。况且混淆后的代码完全兼容于标准的 PHP 可执行文件,因此 Zend Optimer 就不是必须要加载的了,也减轻了客户的麻烦。
先说到这,不写了,这一篇文章把我最近思考的东西全都给榨干了。行文仓促,不当之处还望各位海涵指正。
注:这也是大概半年前的文章。关于 Zend Engine 部分,我当时已经把这个想法提交给了 PHP Internal 讨论组。可惜反响不多。:( 但我至今仍坚持认为,增加 Zend Engine 直接执行中间代码的能力是无论对开发还是 PHP 的执行效率,帮助都是莫大的,而且所须进行的工作和向前兼容性的影响都是可以忽略不计的。但 Zend 公司并未采纳这个建议,相信商业因素占了大部分因素。Zend Engine 是由一个商业公司负责的,福耶?祸耶?