|
英文原文:Integrating php with .NET Using Phalanger
作者:Tomas Petricek 譯者:侯伯薇
Phalanger 是一種 php 語言編譯器,也是針對 .NET 的 php 運(yùn)行時。 它可以用于把 php web 項目編譯成 .NET 字節(jié)碼,并在 Windows 中使用 IIS 或者在 Linux 上使用 Mono 和 Apache 作為 ASP.NET 應(yīng)用程序來執(zhí)行。 然而,Phalanger 不僅僅是把已經(jīng)存在的 php 應(yīng)用編譯到 .NET 中。
我們可以使用 Phalanger 創(chuàng)建組合 .NET 和 php 的解決方案,所采用的方式用標(biāo)準(zhǔn)的 php 解釋器是不可能做到的。 有了 Phalanger 擴(kuò)展,php 程序可以直接使用 .NET 類,而 .NET 程序(比方說用 C# 編寫的)也可以動態(tài)地調(diào)用 php 腳本,或者使用在 php 中實(shí)現(xiàn)的函數(shù)和類【6】。
本文中,我么會簡要地介紹 Phalanger,然后查看三種使用方案。 我們會討論如何整合 php 應(yīng)用程序和 .NET;如何高效地在 Windows 上運(yùn)行 php 應(yīng)用程序,以及如何使用 php 作為 ASP.NET 的視圖引擎(view engine)。
Phalanger 簡介
Phalanger 已經(jīng)存在一段時間了。 第一版 Phalanger 是于 2003 年在布拉格的查爾斯大學(xué)作為軟件項目創(chuàng)建的。稍后就開始了2.0版本的開發(fā),并且于 2006 年在 CodePlex 作為開源項目發(fā)布。 微軟支持了這個項目一段時間,后來一位 Phalanger 開發(fā)者加入微軟,并從事動態(tài)語言運(yùn)行時方面的工作。
Phalanger 相關(guān)活動在 2008 年恢復(fù),這多虧有了與 Jadu 的合作,它使用 Phalanger 為在 php 中開發(fā)的 CMS 構(gòu)建了 .NET 版本。 從 2010 年開始,Phalanger 的開發(fā)主要由 DEVSENSE 提供資金支持,它也為 Phalanger 提供了商業(yè)支持。 最近發(fā)布的版本 Phalanger 2.1【7】,其中提升了與標(biāo)準(zhǔn) php 實(shí)現(xiàn)的兼容性,在動態(tài)操作的實(shí)現(xiàn)過程中利用了 DLR,并提供了 php 和其他 .NET 語言(像C#、F#和 Visual Basic)之間的互操作性。
Phalanger 的組件
Phalanger 包括多個部分獨(dú)立的組件,可以用來開發(fā)運(yùn)行在 .NET 上的 php 應(yīng)用程序,并使用 .NET 或 Mono 來運(yùn)行它們:
- Phalanger 編譯器
Phalanger 會把 php 源代碼編譯成 .NET 程序集,它可以使用 .NET JIT(Just-in-time 編譯器,它會為當(dāng)前平臺生成本地代碼)執(zhí)行。 編譯后的 php 代碼會使用 Phalanger 運(yùn)行時和動態(tài)語言運(yùn)行時,從而提供了 php 語言動態(tài)特性的高效率實(shí)現(xiàn)。 - Phalanger 運(yùn)行時和類庫
Phalanger提供了對數(shù)組之類 php 特性的實(shí)現(xiàn)。 Phalanger 還包含了針對I/O、正則表達(dá)式以及其他標(biāo)準(zhǔn) php 類庫的 .NET 實(shí)現(xiàn)。 - 本地擴(kuò)展
在 32 位 Windows 平臺上,Phalanger 可以通過本地的橋接程序使用所有現(xiàn)存的 php 4 擴(kuò)展。 盡管這會帶來一些運(yùn)行時負(fù)載,但這讓我們不需要額外工作就可以運(yùn)行某些 php 應(yīng)用程序。 - 托管的擴(kuò)展
通過包裝 .NET 中提供的類似功能,php 擴(kuò)展也可以重新實(shí)現(xiàn)。 這些擴(kuò)展可以是由任何 .NET 語言編寫,并提供很好的性能。 Phalanger 中包含多個擴(kuò)展,包括 SPL、JSON、SimpleXML、MySQL 和 MS SQL 的提供程序。 DEVSENSE【9】還提供了附加的擴(kuò)展,像 Memcached、圖像和 cURL 等。 - 與 Visual Studio 的集成
Phalanger 還與 Visual Studio 集成(最近的更新支持 Visual Studio 2010)。 集成功能添加了針對 php 文件的顏色突出顯示和智能提示功能,讓我們可以調(diào)試使用 Phalanger 運(yùn)行的 php 應(yīng)用程序。
Phalanger 使用案例
Phalanger 在很大程度上與 php 5 兼容,可以運(yùn)行大量開源的 php 項目,包括 WordPress 和 MediaWiki。 我們可以使用它把這些項目集成到 .NET 生態(tài)系統(tǒng)中,也可以開發(fā)新的項目,它會兼有 php 和 .NET 的優(yōu)勢。 在本文剩下的內(nèi)容中,我們會討論以下三種使用案例:
- 方案1: 高效運(yùn)行 php 應(yīng)用程序。 使用 PHalanger 在 Windows 上編譯的 php 應(yīng)用程序的性能,要比通過 FastCGI 使用標(biāo)準(zhǔn) php 解釋器運(yùn)行的高。 這使得選擇 Phalanger 在 Windows 環(huán)境中部署 php 很具有吸引力。
- 方案2: 把 WordPress 與 ASP.NET 整合。 使用 Phalanger 編譯的 php 代碼能夠調(diào)用所有 .NET 程序庫。 這可以用于在 php 和 ASP.NET 應(yīng)用程序之間共享用戶數(shù)據(jù)庫或者其他數(shù)據(jù)。
- 方案3: 從 ASP.NET 應(yīng)用程序中調(diào)用 php。 php 的靈活性對于編寫腳本或者編寫 web 應(yīng)用程序的表現(xiàn)層非常有用。 有了 Phalanger,我們就可以在 .NET 中開發(fā)應(yīng)用程序,并使用 php 作為腳本語言或者視圖引擎。
以下三個部分會詳細(xì)討論各種方案。 我們首先會給出概覽,然后查看一些技術(shù)細(xì)節(jié),它會說明 Phalanger 中讓你感興趣的內(nèi)容。
Phalanger 之所以能夠高效地運(yùn)行 php 應(yīng)用程序,是因為以下兩個原因。 首先,它會編譯 php 源代碼,而不是解釋它;其次,它會把應(yīng)用作為 ASP.NET 應(yīng)用程序運(yùn)行,那會在 Windows 下提供額外的性能優(yōu)勢。
編譯過程如圖 1 所示。正如圖上所顯示的,Phalanger 會把 php 源代碼編譯成 .NET IL(中間語言),那是與架構(gòu)獨(dú)立的低級字節(jié)碼。 編譯后的代碼會使用 php 核心庫(Phalanger 的一部分)和動態(tài)語言運(yùn)行時(DLR)來執(zhí)行標(biāo)準(zhǔn)的 php 操作。 當(dāng)應(yīng)用程序啟動時,.NET JIT(just-in-time)編譯器會把這些組件轉(zhuǎn)換為針對當(dāng)前處理器架構(gòu)優(yōu)化過的本地代碼。
圖1. 使用 Phalanger 把 php 源代碼編譯成本地代碼的過程
正如 Phalanger 評測顯示【10】,使用 Phalanger 編譯的 WordPress 在 Windows 下的性能比通過 FashCGI 使用標(biāo)準(zhǔn) php 解釋器的好,也比通過 WinCache 使用 php 的稍好一些。 然而,評測沒有測試 Phalanger 最新的版本,它使用 DLR 進(jìn)行了進(jìn)一步優(yōu)化。
Phalanger 應(yīng)用程序的運(yùn)行方式和 ASP.NET 應(yīng)用程序完全相同。 這讓它具有了重要的性能優(yōu)勢,特別是在 Windows 系統(tǒng)下,進(jìn)程要比線程耗費(fèi)更多資源。
圖 2 顯示了運(yùn)行 php 應(yīng)用程序的不同可選方案。
當(dāng)使用標(biāo)準(zhǔn) CGI 模式時,web 服務(wù)器會為每個進(jìn)入的請求啟動新的進(jìn)程。 在 Windows 下,這樣做的效率不高,它還阻止了共享位于共享內(nèi)存中的狀態(tài),也很難進(jìn)行進(jìn)程中緩存(in-process caching)。 當(dāng)使用 FashCGI 模式時,web 服務(wù)器會重用進(jìn)程,這樣它不需要為每個請求啟動新的進(jìn)程。 然而,這還是無法共享內(nèi)存中的狀態(tài),因為不同的進(jìn)程擁有不同的狀態(tài)。
圖2. 使用 CGI、FashCGI 和 Phalanger 運(yùn)行 php
Phalanger 的行為方式和所有 ASP.NET 應(yīng)用一樣。 單獨(dú)的叫做應(yīng)用池(Application Pool)的 ASP.NET 進(jìn)程會處理所有進(jìn)入的請求。 我們甚至可以在單一進(jìn)程(應(yīng)用池)中配置多個 php 應(yīng)用程序(像多個 WordPress 的獨(dú)立實(shí)例)。 在進(jìn)程中,會有多個線程,這些線程會被重用以處理單獨(dú)的請求。 在 Windows 下,線程要比過程更輕量級,所以這種解決方案更有效率,并且會消耗更少的內(nèi)存。
對于運(yùn)行在單一進(jìn)程中的應(yīng)用程序,我們可以進(jìn)行進(jìn)一步的優(yōu)化,并采用其它有趣的方案。 例如,Phalanger 會使用動態(tài)語言運(yùn)行時(DLR)來做動態(tài)方法調(diào)用。 DLR 會使用與時間相適應(yīng)的緩存機(jī)制,因此在幾次請求之后,DLR 就會“知道”應(yīng)用程序使用的是哪個方法,并變得更快一些。 這只有在單一進(jìn)程中處理請求的情況下才可能做到。
在單一進(jìn)程中運(yùn)行所有代碼也意味著應(yīng)用程序可以在內(nèi)存中存儲全局狀態(tài)。 這可以用于實(shí)現(xiàn)與 WinCache 提供的 User Cache 類似的功能,但是不會有跨進(jìn)程通信造成的負(fù)載。
php 的一點(diǎn)優(yōu)勢就在于擁有大量優(yōu)秀的開源 CMS 系統(tǒng)(WordPress、Joomla 等等)、表單應(yīng)用程序(phpBB 及其他)和 wiki(Mediawiki 及其他),其中很多都通過了 Phalanger 的測試。
這些應(yīng)用通常會比 .NET 平臺下類似的程序包提供更多特性。 開發(fā)基于 ASP.NET 網(wǎng)頁的公司可能會面臨以下情況:
- 它需要向現(xiàn)存的 ASP.NET 解決方案中添加 wiki、論壇或者博客,但是只有在 php 中存在合適的應(yīng)用程序(例如,免費(fèi)并且?guī)в兴斜匾匦裕?/li>
- 應(yīng)用程序可能會在子域下運(yùn)行,但是它應(yīng)該共享用戶數(shù)據(jù)庫。 此外,一旦用戶登錄到主頁,那么他就應(yīng)該同時登錄到 wiki、論壇和博客上。
ASP.NET 應(yīng)用程序可以使用 ASP.NET 的成員管理(ASP.NET Membership),它還用來管理用戶、角色和功能的標(biāo)準(zhǔn)機(jī)制。 有了 Phalanger,我們就可以修改開源的 php 項目,從而使用同樣的機(jī)制。 下一部分會演示使用 WordPress 如何做到這一點(diǎn)。
為 WordPress 實(shí)現(xiàn) ASP.NET 成員管理插件
如果你對代碼不感興趣,那么就可以略過這個部分,直接查看第三種情況。 但是,我們不會查看技術(shù)細(xì)節(jié),只是對讓 php 調(diào)用 .NET 程序庫的 php 擴(kuò)展做簡要的概述。
我們可以使用插件輕松地自定義在 WordPress 管理用戶的方式。 管理用戶的插件需要實(shí)現(xiàn)一個 php 類,其中有各種成員函數(shù)。 其中最值得期待的功能就是身份驗證,它會獲得用戶名和密碼。 它應(yīng)該填充當(dāng)前用戶的信息,或者,當(dāng)用戶不存在的時候,就會把名稱設(shè)置為 NULL。
為了使用 .NET 中的 ASP.NET 成員管理來實(shí)現(xiàn)身份驗證功能,我們可以使用 System.Web.Security 命名空間中的功能。 靜態(tài)方法 Membership.ValidateUser 會檢查密碼是否正確,而 Membership.GetUser 會返回用戶的基本信息。 使用 Phalanger,我們可以訪問 .NET 對象,就像它是標(biāo)準(zhǔn)的 php 對象一樣,這樣實(shí)現(xiàn)驗證機(jī)制就很簡單了。 代碼 1 展示了簡化后的代碼。
代碼 1 在 WordPress 插件中實(shí)現(xiàn)身份驗證功能的函數(shù)
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技術(shù):使用Phalanger整合PHP和.Net,轉(zhuǎn)載需保留來源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。