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