使用Phalanger整合PHP和.Net

  英文原文:Integrating php with .NET Using Phalanger

  作者:Tomas Petricek 译者:侯伯薇

  Phalanger 是一种 php 语言编译器,也是针对 .NETphp 运行时。 它可以用于把 php web 项目编译成 .NET 字节码,并在 Windows 中使用 IIS 或者在 Linux 上使用 Mono 和 Apache 作为 ASP.NET 应用程序来执行。 然而,Phalanger 不仅仅是把已经存在的 php 应用编译到 .NET 中。

  我们可以使用 Phalanger 创建组合 .NETphp 的解决方案,所采用的方式用标准的 php 解释器是不可能做到的。 有了 Phalanger 扩展,php 程序可以直接使用 .NET 类,而 .NET 程序(比方说用 C# 编写的)也可以动态地调用 php 脚本,或者使用在 php 中实现的函数和类【6】。

  本文中,我么会简要地介绍 Phalanger,然后查看三种使用方案。 我们会讨论如何整合 php 应用程序和 .NET;如何高效地在 Windows 上运行 php 应用程序,以及如何使用 php 作为 ASP.NET 的视图引擎(view engine)。

  Phalanger 简介

  Phalanger 已经存在一段时间了。 第一版 Phalanger 是于 2003 年在布拉格的查尔斯大学作为软件项目创建的。稍后就开始了2.0版本的开发,并且于 2006 年在 CodePlex 作为开源项目发布。 微软支持了这个项目一段时间,后来一位 Phalanger 开发者加入微软,并从事动态语言运行时方面的工作。

  Phalanger 相关活动在 2008 年恢复,这多亏有了与 Jadu 的合作,它使用 Phalanger 为在 php 中开发的 CMS 构建了 .NET 版本。 从 2010 年开始,Phalanger 的开发主要由 DEVSENSE 提供资金支持,它也为 Phalanger 提供了商业支持。 最近发布的版本 Phalanger 2.1【7】,其中提升了与标准 php 实现的兼容性,在动态操作的实现过程中利用了 DLR,并提供了 php 和其他 .NET 语言(像C#、F#和 Visual Basic)之间的互操作性。

  Phalanger 的组件

  Phalanger 包括多个部分独立的组件,可以用来开发运行在 .NET 上的 php 应用程序,并使用 .NET 或 Mono 来运行它们:

  • Phalanger 编译器
    Phalanger 会把 php 源代码编译成 .NET 程序集,它可以使用 .NET JIT(Just-in-time 编译器,它会为当前平台生成本地代码)执行。 编译后的 php 代码会使用 Phalanger 运行时和动态语言运行时,从而提供了 php 语言动态特性的高效率实现。
  • Phalanger 运行时和类库
    Phalanger提供了对数组之类 php 特性的实现。 Phalanger 还包含了针对I/O、正则表达式以及其他标准 php 类库的 .NET 实现。
  • 本地扩展
    在 32 位 Windows 平台上,Phalanger 可以通过本地的桥接程序使用所有现存的 php 4 扩展。 尽管这会带来一些运行时负载,但这让我们不需要额外工作就可以运行某些 php 应用程序。
  • 托管的扩展
    通过包装 .NET 中提供的类似功能,php 扩展也可以重新实现。 这些扩展可以是由任何 .NET 语言编写,并提供很好的性能。 Phalanger 中包含多个扩展,包括 SPL、JSON、SimpleXML、MySQL 和 MS SQL 的提供程序。 DEVSENSE【9】还提供了附加的扩展,像 Memcached、图像和 cURL 等。
  • 与 Visual Studio 的集成
    Phalanger 还与 Visual Studio 集成(最近的更新支持 Visual Studio 2010)。 集成功能添加了针对 php 文件的颜色突出显示和智能提示功能,让我们可以调试使用 Phalanger 运行的 php 应用程序。

  Phalanger 使用案例

  Phalanger 在很大程度上与 php 5 兼容,可以运行大量开源php 项目,包括 WordPress 和 MediaWiki。 我们可以使用它把这些项目集成到 .NET 生态系统中,也可以开发新的项目,它会兼有 php 和 .NET 的优势。 在本文剩下的内容中,我们会讨论以下三种使用案例:

  • 方案1: 高效运行 php 应用程序。 使用 PHalanger 在 Windows 上编译的 php 应用程序的性能,要比通过 FastCGI 使用标准 php 解释器运行的高。 这使得选择 Phalanger 在 Windows 环境中部署 php 很具有吸引力。
  • 方案2: 把 WordPress 与 ASP.NET 整合。 使用 Phalanger 编译的 php 代码能够调用所有 .NET 程序库。 这可以用于在 phpASP.NET 应用程序之间共享用户数据库或者其他数据。
  • 方案3: 从 ASP.NET 应用程序中调用 php php 的灵活性对于编写脚本或者编写 web 应用程序的表现层非常有用。 有了 Phalanger,我们就可以在 .NET 中开发应用程序,并使用 php 作为脚本语言或者视图引擎。

  以下三个部分会详细讨论各种方案。 我们首先会给出概览,然后查看一些技术细节,它会说明 Phalanger 中让你感兴趣的内容。

  方案1: 高效运行 php 应用程序

  Phalanger 之所以能够高效地运行 php 应用程序,是因为以下两个原因。 首先,它会编译 php 源代码,而不是解释它;其次,它会把应用作为 ASP.NET 应用程序运行,那会在 Windows 下提供额外的性能优势。

  使用 Phalanger 和 .NET 编译 php

  编译过程如图 1 所示。正如图上所显示的,Phalanger 会把 php 源代码编译成 .NET IL(中间语言),那是与架构独立的低级字节码。 编译后的代码会使用 php 核心库(Phalanger 的一部分)和动态语言运行时(DLR)来执行标准的 php 操作。 当应用程序启动时,.NET JIT(just-in-time)编译器会把这些组件转换为针对当前处理器架构优化过的本地代码。

图1. 使用 Phalanger 把 php 源代码编译成本地代码的过程

  正如 Phalanger 评测显示【10】,使用 Phalanger 编译的 WordPress 在 Windows 下的性能比通过 FashCGI 使用标准 php 解释器的好,也比通过 WinCache 使用 php 的稍好一些。 然而,评测没有测试 Phalanger 最新的版本,它使用 DLR 进行了进一步优化。

  使用 ASP.NET 部署 php 应用程序

  Phalanger 应用程序的运行方式和 ASP.NET 应用程序完全相同。 这让它具有了重要的性能优势,特别是在 Windows 系统下,进程要比线程耗费更多资源。

  图 2 显示了运行 php 应用程序的不同可选方案。

  当使用标准 CGI 模式时,web 服务器会为每个进入的请求启动新的进程。 在 Windows 下,这样做的效率不高,它还阻止了共享位于共享内存中的状态,也很难进行进程中缓存(in-process caching)。 当使用 FashCGI 模式时,web 服务器会重用进程,这样它不需要为每个请求启动新的进程。 然而,这还是无法共享内存中的状态,因为不同的进程拥有不同的状态。

图2. 使用 CGI、FashCGI 和 Phalanger 运行 php

  Phalanger 的行为方式和所有 ASP.NET 应用一样。 单独的叫做应用池(Application Pool)的 ASP.NET 进程会处理所有进入的请求。 我们甚至可以在单一进程(应用池)中配置多个 php 应用程序(像多个 WordPress 的独立实例)。 在进程中,会有多个线程,这些线程会被重用以处理单独的请求。 在 Windows 下,线程要比过程更轻量级,所以这种解决方案更有效率,并且会消耗更少的内存。

  对于运行在单一进程中的应用程序,我们可以进行进一步的优化,并采用其它有趣的方案。 例如,Phalanger 会使用动态语言运行时(DLR)来做动态方法调用。 DLR 会使用与时间相适应的缓存机制,因此在几次请求之后,DLR 就会“知道”应用程序使用的是哪个方法,并变得更快一些。 这只有在单一进程中处理请求的情况下才可能做到。

  在单一进程中运行所有代码也意味着应用程序可以在内存中存储全局状态。 这可以用于实现与 WinCache 提供的 User Cache 类似的功能,但是不会有跨进程通信造成的负载。

  方案2: 把 WordPress 与 ASP.NET 整合

  php 的一点优势就在于拥有大量优秀的开源 CMS 系统(WordPress、Joomla 等等)、表单应用程序(phpBB 及其他)和 wiki(Mediawiki 及其他),其中很多都通过了 Phalanger 的测试。

  这些应用通常会比 .NET 平台下类似的程序包提供更多特性。 开发基于 ASP.NET 网页的公司可能会面临以下情况:

  • 它需要向现存的 ASP.NET 解决方案中添加 wiki、论坛或者博客,但是只有在 php 中存在合适的应用程序(例如,免费并且带有所有必要特性)。
  • 应用程序可能会在子域下运行,但是它应该共享用户数据库。 此外,一旦用户登录到主页,那么他就应该同时登录到 wiki、论坛和博客上。

  ASP.NET 应用程序可以使用 ASP.NET 的成员管理(ASP.NET Membership),它还用来管理用户、角色和功能的标准机制。 有了 Phalanger,我们就可以修改开源php 项目,从而使用同样的机制。 下一部分会演示使用 WordPress 如何做到这一点。

  为 WordPress 实现 ASP.NET 成员管理插件

  如果你对代码不感兴趣,那么就可以略过这个部分,直接查看第三种情况。 但是,我们不会查看技术细节,只是对让 php 调用 .NET 程序库的 php 扩展做简要的概述。

  我们可以使用插件轻松地自定义在 WordPress 管理用户的方式。 管理用户的插件需要实现一个 php 类,其中有各种成员函数。 其中最值得期待的功能就是身份验证,它会获得用户名和密码。 它应该填充当前用户的信息,或者,当用户不存在的时候,就会把名称设置为 NULL。

  为了使用 .NET 中的 ASP.NET 成员管理来实现身份验证功能,我们可以使用 System.Web.Security 命名空间中的功能。 静态方法 Membership.ValidateUser 会检查密码是否正确,而 Membership.GetUser 会返回用户的基本信息。 使用 Phalanger,我们可以访问 .NET 对象,就像它是标准的 php 对象一样,这样实现验证机制就很简单了。 代码 1 展示了简化后的代码。

  代码 1 在 WordPress 插件中实现身份验证功能的函数

import namespace System:::Web:::Security;

function authenticate (&$username,$password) {
global $errors;

// Test whether the password is correct
if (Membership::ValidateUser ($username,$password)) {
// Get information about the user and fill $userarray
$user = Membership::GetUser ($username);
$userarray['user_login'] = $user->UserName;
$userarray['user_email'] = $user->Email;
$userarray['display_name'] = $username;
$userarray['user_pass'] = $password;
// Loading of roles & profiles omitted for simplicity

// Update or create the user information in WordPress
if ($id = username_exists ($username)) {
$userarray['ID'] = $id;
wp_update_user ($userarray);
}
else
wp_insert_user ($userarray);
} else {
// Report error if the login failed
$errors->add ('user-rejected', 'Log-in failed!');
$username = NULL;
}
}

NET技术使用Phalanger整合PHP和.Net,转载需保留来源!

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。