您好,登錄后才能下訂單哦!
本篇文章為大家展示了如何使用Phalanger創(chuàng)建組合.NET和PHP,內(nèi)容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
Phalanger 是一種 PHP 語言編譯器,也是針對 .NET 的 PHP 運行時。 它可以用于把 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 的解決方案,所采用的方式用標準的 PHP 解釋器是不可能做到的。 有了 Phalanger 擴展,PHP 程序可以直接使用 .NET 類,而 .NET 程序(比方說用 C# 編寫的)也可以動態(tài)地調(diào)用 PHP 腳本,或者使用在 PHP 中實現(xiàn)的函數(shù)和類【6】。
我會簡要地介紹 Phalanger,然后查看三種使用方案。 討論如何整合 PHP 應(yīng)用程序和 .NET;如何高效地在 Windows 上運行 PHP 應(yīng)用程序,以及如何使用 PHP 作為 ASP.NET 的視圖引擎(view engine)。
Phalanger 簡介
Phalanger 已經(jīng)存在一段時間了。 ***版 Phalanger 是于 2003 年在布拉格的查爾斯大學作為軟件項目創(chuàng)建的。稍后就開始了2.0版本的開發(fā),并且于 2006 年在 CodePlex 作為開源項目發(fā)布。 微軟支持了這個項目一段時間,后來一位 Phalanger 開發(fā)者加入微軟,并從事動態(tài)語言運行時方面的工作。
Phalanger 相關(guān)活動在 2008 年恢復,這多虧有了與 Jadu 的合作,它使用 Phalanger 為在 PHP 中開發(fā)的 CMS 構(gòu)建了 .NET 版本。 從 2010 年開始,Phalanger 的開發(fā)主要由 DEVSENSE 提供資金支持,它也為 Phalanger 提供了商業(yè)支持。 最近發(fā)布的版本 Phalanger 2.1【7】,其中提升了與標準 PHP 實現(xiàn)的兼容性,在動態(tài)操作的實現(xiàn)過程中利用了 DLR,并提供了 PHP 和其他 .NET 語言(像C#、F#和 Visual Basic)之間的互操作性。
Phalanger 的組件
Phalanger 包括多個部分獨立的組件,可以用來開發(fā)運行在 .NET 上的 PHP 應(yīng)用程序,并使用 .NET 或 Mono 來運行它們:
Phalanger 編譯器
Phalanger 會把 PHP 源代碼編譯成 .NET 程序集,它可以使用 .NET JIT(Just-in-time 編譯器,它會為當前平臺生成本地代碼)執(zhí)行。 編譯后的 PHP 代碼會使用 Phalanger 運行時和動態(tài)語言運行時,從而提供了 PHP 語言動態(tài)特性的高效率實現(xiàn)。
Phalanger 運行時和類庫
Phalanger提供了對數(shù)組之類 PHP 特性的實現(xiàn)。 Phalanger 還包含了針對I/O、正則表達式以及其他標準 PHP 類庫的 .NET 實現(xiàn)。
本地擴展
在 32 位 Windows 平臺上,Phalanger 可以通過本地的橋接程序使用所有現(xiàn)存的 PHP 4 擴展。 盡管這會帶來一些運行時負載,但這讓我們不需要額外工作就可以運行某些 PHP 應(yīng)用程序。
托管的擴展
通過包裝 .NET 中提供的類似功能,PHP 擴展也可以重新實現(xiàn)。 這些擴展可以是由任何 .NET 語言編寫,并提供很好的性能。 Phalanger 中包含多個擴展,包括 SPL、JSON、SimpleXML、MySQL 和 MS SQL 的提供程序。 DEVSENSE【9】還提供了附加的擴展,像 Memcached、圖像和 cURL 等。
與 Visual Studio 的集成
Phalanger 還與 Visual Studio 集成(最近的更新支持 Visual Studio 2010)。 集成功能添加了針對 PHP 文件的顏色突出顯示和智能提示功能,讓我們可以調(diào)試使用 Phalanger 運行的 PHP 應(yīng)用程序。
Phalanger 使用案例
Phalanger 在很大程度上與 PHP 5 兼容,可以運行大量開源的 PHP 項目,包括 WordPress 和 MediaWiki。 我們可以使用它把這些項目集成到 .NET 生態(tài)系統(tǒng)中,也可以開發(fā)新的項目,它會兼有 PHP 和 .NET 的優(yōu)勢。 在本文剩下的內(nèi)容中,我們會討論以下三種使用案例:
方案1: 高效運行 PHP 應(yīng)用程序。 使用 PHalanger 在 Windows 上編譯的 PHP 應(yīng)用程序的性能,要比通過 FastCGI 使用標準 PHP 解釋器運行的高。 這使得選擇 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 作為腳本語言或者視圖引擎。
以下三個部分會詳細討論各種方案。 我們首先會給出概覽,然后查看一些技術(shù)細節(jié),它會說明 Phalanger 中讓你感興趣的內(nèi)容。
方案1: 高效運行 PHP 應(yīng)用程序
Phalanger 之所以能夠高效地運行 PHP 應(yīng)用程序,是因為以下兩個原因。 首先,它會編譯 PHP 源代碼,而不是解釋它;其次,它會把應(yīng)用作為 ASP.NET 應(yīng)用程序運行,那會在 Windows 下提供額外的性能優(yōu)勢。
使用 Phalanger 和 .NET 編譯 PHP
編譯過程如圖 1 所示。正如圖上所顯示的,Phalanger 會把 PHP 源代碼編譯成 .NET IL(中間語言),那是與架構(gòu)獨立的低級字節(jié)碼。 編譯后的代碼會使用 PHP 核心庫(Phalanger 的一部分)和動態(tài)語言運行時(DLR)來執(zhí)行標準的 PHP 操作。 當應(yīng)用程序啟動時,.NET JIT(just-in-time)編譯器會把這些組件轉(zhuǎn)換為針對當前處理器架構(gòu)優(yōu)化過的本地代碼。
圖1. 使用 Phalanger 把 PHP 源代碼編譯成本地代碼的過程
正如 Phalanger 評測顯示【10】,使用 Phalanger 編譯的 WordPress 在 Windows 下的性能比通過 FashCGI 使用標準 PHP 解釋器的好,也比通過 WinCache 使用 PHP 的稍好一些。 然而,評測沒有測試 Phalanger ***的版本,它使用 DLR 進行了進一步優(yōu)化。
使用 ASP.NET 部署 PHP 應(yīng)用程序
Phalanger 應(yīng)用程序的運行方式和 ASP.NET 應(yīng)用程序完全相同。 這讓它具有了重要的性能優(yōu)勢,特別是在 Windows 系統(tǒng)下,進程要比線程耗費更多資源。
圖 2 顯示了運行 PHP 應(yīng)用程序的不同可選方案。
當使用標準 CGI 模式時,web 服務(wù)器會為每個進入的請求啟動新的進程。 在 Windows 下,這樣做的效率不高,它還阻止了共享位于共享內(nèi)存中的狀態(tài),也很難進行進程中緩存(in-process caching)。 當使用 FashCGI 模式時,web 服務(wù)器會重用進程,這樣它不需要為每個請求啟動新的進程。 然而,這還是無法共享內(nèi)存中的狀態(tài),因為不同的進程擁有不同的狀態(tài)。
圖2. 使用 CGI、FashCGI 和 Phalanger 運行 PHP
Phalanger 的行為方式和所有 ASP.NET 應(yīng)用一樣。 單獨的叫做應(yīng)用池(Application Pool)的 ASP.NET 進程會處理所有進入的請求。 我們甚至可以在單一進程(應(yīng)用池)中配置多個 PHP 應(yīng)用程序(像多個 WordPress 的獨立實例)。 在進程中,會有多個線程,這些線程會被重用以處理單獨的請求。 在 Windows 下,線程要比過程更輕量級,所以這種解決方案更有效率,并且會消耗更少的內(nèi)存。
對于運行在單一進程中的應(yīng)用程序,我們可以進行進一步的優(yōu)化,并采用其它有趣的方案。 例如,Phalanger 會使用動態(tài)語言運行時(DLR)來做動態(tài)方法調(diào)用。 DLR 會使用與時間相適應(yīng)的緩存機制,因此在幾次請求之后,DLR 就會“知道”應(yīng)用程序使用的是哪個方法,并變得更快一些。 這只有在單一進程中處理請求的情況下才可能做到。
在單一進程中運行所有代碼也意味著應(yīng)用程序可以在內(nèi)存中存儲全局狀態(tài)。 這可以用于實現(xiàn)與 WinCache 提供的 User Cache 類似的功能,但是不會有跨進程通信造成的負載。
方案2: 把 WordPress 與 ASP.NET 整合
PHP 的一點優(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)用程序(例如,免費并且?guī)в兴斜匾匦裕?/p>
應(yīng)用程序可能會在子域下運行,但是它應(yīng)該共享用戶數(shù)據(jù)庫。 此外,一旦用戶登錄到主頁,那么他就應(yīng)該同時登錄到 wiki、論壇和博客上。
ASP.NET 應(yīng)用程序可以使用 ASP.NET 的成員管理(ASP.NET Membership),它還用來管理用戶、角色和功能的標準機制。 有了 Phalanger,我們就可以修改開源的 PHP 項目,從而使用同樣的機制。 下一部分會演示使用 WordPress 如何做到這一點。
為 WordPress 實現(xiàn) ASP.NET 成員管理插件
如果你對代碼不感興趣,那么就可以略過這個部分,直接查看第三種情況。 但是,我們不會查看技術(shù)細節(jié),只是對讓 PHP 調(diào)用 .NET 程序庫的 PHP 擴展做簡要的概述。
我們可以使用插件輕松地自定義在 WordPress 管理用戶的方式。 管理用戶的插件需要實現(xiàn)一個 PHP 類,其中有各種成員函數(shù)。 其中最值得期待的功能就是身份驗證,它會獲得用戶名和密碼。 它應(yīng)該填充當前用戶的信息,或者,當用戶不存在的時候,就會把名稱設(shè)置為 NULL。
為了使用 .NET 中的 ASP.NET 成員管理來實現(xiàn)身份驗證功能,我們可以使用 System.Web.Security 命名空間中的功能。 靜態(tài)方法 Membership.ValidateUser 會檢查密碼是否正確,而 Membership.GetUser 會返回用戶的基本信息。 使用 Phalanger,我們可以訪問 .NET 對象,就像它是標準的 PHP 對象一樣,這樣實現(xiàn)驗證機制就很簡單了。 代碼 1 展示了簡化后的代碼。
代碼 1 在 WordPress 插件中實現(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;}}
代碼首先聲明了重要的命名空間。 這是一個非標準的 Phalanger 擴展,它從引用的程序庫的 .NET 命名空間中導入了功能(我們可以使用 web.config 文件來引用程序庫)。 在將來的版本中,Phalanger 會使用 PHP 5.3 支持的標準命名空間,但是這項改變還沒有完全實現(xiàn)。
剩余部分的代碼看起來和標準的 PHP 代碼一樣。 然而,Membership 類實際上是標準的 .NET 類。 Phalanger 會把 PHP 類和 .NET 類同等對待,所以我們可以使用標準的語法來調(diào)用 .NET 方法。 函數(shù) ValidateUser 和 GetUser 都是靜態(tài)函數(shù),所以使用::語法來調(diào)用。 GetUser 的結(jié)果是一個 .NET 的 MembershipUser 對象, 其中帶有各種屬性,包括關(guān)于用戶的基本信息。 我們?nèi)匀豢梢允褂脴藴实臉擞浄▉碓L問對象的字段(它們被實現(xiàn)為 .NET 的屬性)。
正如你所看到的,我們可以很自然地在 PHP 中使用 .NET 功能。 由于代碼會被編譯成 .NET 程序,所以在調(diào)用 .NET 庫時不會有任何負載。 下一部分展示的是反方向的整合 —— 從 .NET 應(yīng)用程序中調(diào)用 PHP。
方案3: 從 ASP.NET 應(yīng)用程序中調(diào)用 PHP
PHP 的主要優(yōu)勢就在于靈活性和簡單性,這使得它成為編寫腳本和實現(xiàn)渲染 HTML 很棒的語言。 然而,有些人發(fā)現(xiàn),想要實現(xiàn)大型應(yīng)用程序,那么用靜態(tài)類型語言 —— 像 Java 或C# —— 會更容易一些。 使用 Phalanger,我們可以同時獲得兩方面的優(yōu)勢。
這個部分所討論的方案演示了一種組合 ASP.NET 和 PHP 的方式。 它基于先進的 ASP.NET MVC(模型、視圖、控制器)框架,將表現(xiàn)層、負責交互的層和應(yīng)用程序的業(yè)務(wù)邏輯分離開來。 我們可以使用不同的語言來開發(fā)單獨的組件:
C#模型和控制器
模型和控制器會在 C# 中編寫。 應(yīng)用程序的這個部分會實現(xiàn)業(yè)務(wù)邏輯,通常這在靜態(tài)類型語言中編寫更容易一些,特別是在業(yè)務(wù)邏輯非常復雜的情況下。 此外,我們還可以使用像 LINQ 之類的技術(shù)來存儲數(shù)據(jù),使用任務(wù)并行庫(Task Parallel Library)使用多線程來實現(xiàn)高性能計算。
PHP 視圖
應(yīng)用程序的表現(xiàn)層會用 PHP 編寫。 在這里,PHP 的簡單性和靈活性會提供***的好處。 此外,這意味著應(yīng)用程序的這個部分可以由開發(fā)經(jīng)驗比較少的開發(fā)者來編寫,因為大多數(shù) web 開發(fā)者的 web 設(shè)計師都對 PHP 有些了解。
還有一些情況,從 C# 中調(diào)用 PHP 會很有用。 例如,你可以在大型的 C# 項目中使用 PHP 作為腳本語言。 這也非常有用,因為 PHP 是一種廣為所知的語言。 另一種情況是,當在 C# 中使用 PHP 程序庫的時候 —— 正因為有了 Phalanger 的 duck typing 機制,這才得到了很大程度的簡化,該機制甚至可以為調(diào)用文檔齊備的 PHP 代碼生成靜態(tài)類型的 C# 接口。
在本文剩余的內(nèi)容中,我們會著重討論使用 PHP 實現(xiàn) ASP.NET 應(yīng)用程序表現(xiàn)層的方案。 你可以在文章末尾找到其他方案(像編寫腳本)的參考信息。
在 C# 和 PHP 中創(chuàng)建模型-視圖-控制器應(yīng)用程序
首先讓我們看下使用 C# 和 PHP 組合創(chuàng)建出來的簡單應(yīng)用程序。 應(yīng)用程序的模型和控制器都是使用 C# 編寫的,如代碼 2 所示。在這個例子中,模型只是一個簡單的 C# 類,它表示的是產(chǎn)品信息。 在現(xiàn)實情況下,這個類可能會負責從數(shù)據(jù)庫載入數(shù)據(jù),并且可能使用 LINQ 來實現(xiàn)。
代碼2: 示例 web 應(yīng)用程序(C#)的模型和控制器
public class Product { public string ProductName { get; set } public double Price { get; set } } public class HomeController : Controller { public ActionResult Index () { ViewData.Model = new Product { ProductName = "John Doe", Price = 99.9 }; return View (); } }
控制器組件是通過 HomeController 類實現(xiàn)的,它會繼承 ASP.NET MVC 控制器。 類中只包含一個動作,展現(xiàn)應(yīng)用程序的索引頁面。 當用戶訪問/Home/Index(或者根 URL)的時候就會觸發(fā)這個動作。 它會創(chuàng)建模型(Product 類的實例)并把它傳遞給視圖組件。
在標準的 ASP.NET MVC 應(yīng)用程序中,視圖組件通常會使用 ASPX 頁面或者使用帶有使用 C# 或 Visual Basic 編寫的代碼的 Razor 視圖來實現(xiàn)。 Phalanger 讓我們可以使用 PHP 來實現(xiàn)視圖。 代碼 3 展示了這個例子。
代碼 3 示例 Web 應(yīng)用程序(PHP)的視圖
<html><head> <title>Sample view written in PHP</title> </head> <body> <h2>Product Listing using Phalanger</h2> Product: <? echo $MODEL->ProductName; ?><br /> Price: <? echo $MODEL->Price; ?> </body></html>
視圖會使用下面描述的 ASP.NET MVC 擴展來渲染。 擴展會執(zhí)行代碼 3 中所示的 PHP 腳本,并定義名為$MODEL 的全局變量,其中會包含控制器返回的數(shù)據(jù)。 在上述示例中,$MODEL 是對標準 .NET 類的引用。 Phalanger 會對 .NET 類和 PHP 對象同等對待,所以使用 echo 結(jié)構(gòu),我們很容易就可以顯示產(chǎn)品的屬性。
示例顯示了應(yīng)用程序的基本結(jié)構(gòu),但是它極為簡單,所以不會真正顯示出在表現(xiàn)層使用 PHP 所能給我們帶來的好處:
PHP 與生俱來的動態(tài)特性使得渲染任何結(jié)構(gòu)的數(shù)據(jù)都很簡單。 視圖并不僅限與簡單腳本,并且可以使用任何現(xiàn)存的 PHP 庫,包括流行的模板引擎(templating engines)。
視圖可以使用 PHP 的 include 功能實現(xiàn)多文件的結(jié)構(gòu),這樣你可以完全控制頁面如何生成。
創(chuàng)建視圖的開發(fā)者不需要知道任何關(guān)于 .NET 的知識。 這意味著從 PHP 轉(zhuǎn)型為 C# 的公司,仍然支持現(xiàn)存的開發(fā)者技能。
為了讓你更好地了解這個方案的工作方式,以下部分會說明關(guān)于 PHP 和 C# 整合的技術(shù)細節(jié)。 如果你對細節(jié)不感興趣,那么就可以直接跳到總結(jié)部分。
透過現(xiàn)象看本質(zhì)
這個部分所描述的方案基于 PicoMVC 項目【4】,它讓我們可以組合 PHP 和 F#。 為了讓示例更簡單,我把代碼從F#轉(zhuǎn)換為C#。 在 PicoMVC 中 PHP 整合的核心是一個簡單的函數(shù),它會取得 PHP 腳本的文件名,并使用 Phalanger 運行時來運行。 函數(shù)如代碼 4 所示。
代碼 4 從 ASP.NET web 應(yīng)用程序調(diào)用 PHP 腳本
void PhalanagerView (string fileName, object model, HttpContext current) { // Initialize PHP request context and output stream using(var rc = RequestContext.Initialize (ApplicationContext.Default, current)) using(var byteOut = HttpContext.Current.Response.OutputStream) using(var uftOut = new StreamWriter (byteOut)) { // Current context for evaluating PHP scripts var phpContext = ScriptContext.CurrentContext; // Redirect PHP output to the HTTP output stream phpContext.Output = uftOut; phpContext.OutputStream = byteOut; // Declare global $MODEL variable (if model is set) if (model != null) Operators.SetVariable (phpContext, null, "MODEL", ClrObject.WrapDynamic (model)); phpContext.Include (fileName, false); } }
PhalangeriView 方法會獲得文件名(指向 PHP 腳本)、代表作為模型返回的數(shù)據(jù)的 .NET 對象以及當前的 HTTP 上下文。 它首先會初始化 RequestContext,從而 Phalanger 知道它是在處理作為 HTTP 請求一部分的腳本。 然后,它會確保所有 PHP 腳本生成的輸出都會直接作為 HTTP 響應(yīng)發(fā)送。 當作為腳本運行 PHP 的時候,輸出可以重定向到內(nèi)存流,從而以不同的方式處理。 ***,方法會聲明全局變量 MODEL,并使用 Phalanger 所提供的 Include 方法來執(zhí)行 PHP 腳本。
這個例子并不完全是從 C# 調(diào)用 PHP 的指引,你可以在 Phalanger 博客的文章中找到更詳細的信息。 然而,它應(yīng)該可以說明,使用 Phalanger 從 C# 調(diào)用 PHP 腳本相當容易。 這在本節(jié)討論的 web 編程情況下會很有用,但是它給了我們更多選擇。
簡要地介紹了 Phalanger —— 針對 .NET 的 PHP 編譯器 —— 以及幾種方案,我們可以在實踐中使用它來解決重要問題。 最近 Phalanger 項目非?;钴S,2.1 版本中包含了很多兼容性方面的改善、使用動態(tài)語言運行時(DLR)以獲得更好的性能,以及與 Visual Studio 2010 的集成。
我們看了三種可以在 web 開發(fā)中使用 Phalanger 的方案。 ***種方案是使用 Phalanger 在 Windows 環(huán)境下運行未經(jīng)修改的開源 PHP 項目(像 WordPress)。 使用 Phalanger 編譯的應(yīng)用程序可以運行在 ASP.NET 下,這種主機會更輕量級,運行效率也更高。
在第二種方案中,我們查看了集成在 .NET 生態(tài)系統(tǒng)中的 PHP 應(yīng)用程序。 有了 Phalanger 擴展,我們就可以在 PHP 代碼中直接調(diào)用 .NET 程序庫。 例如,這可以用來整合 ASP.NET 應(yīng)用程序和 WordPress 之間的用戶數(shù)據(jù)庫。
***一種方案演示了一種 web 框架,它使用 PHP 作為在 ASP.NET MVC 中編寫視圖的語言。 通過這種方式,.NET 開發(fā)者可以很容易地提供應(yīng)用程序的業(yè)務(wù)功能,而 PHP 開發(fā)者可以在表現(xiàn)層中直接使用它。
上述內(nèi)容就是如何使用Phalanger創(chuàng)建組合.NET和PHP,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。