2011-05-26 21 views
3

爲了在知道HTML的一些UI人員和知道.NET的後端人員之間實現更好的協作,我們正在考慮使用MVC Web應用程序並使用phalanger的架構作爲視圖引擎。使用phalanger作爲MVC應用程序的視圖部分

作爲視圖模型的集成phalanager看起來相當容易,除了一點。我不知道如何將模型傳遞給頁面腳本。任何想法如何實現?

一個想法是從PHP腳本調用一個靜態的.NET方法,但它感覺有點哈克。我希望能夠將參數傳遞給腳本,並讓腳本能夠在變量中進行提取。

回答

4

在後端使用.NET,在前端使用PHP(使用Phalanger)看起來是一個很好的場景。我認爲最好的選擇是在.NET中實現這個模型,並使用PHP來實現控制器和視圖(直接或使用一些PHP框架)。

使用Phalanger調用PHP編譯的PHP模型非常容易,因爲PHP代碼可以訪問.NET對象。假設有一個包含一個命名空間DemoDataLayer與以下類型一個C#DLL:

public class Data { 
    public List<Category> GetCategories() { 
    var ret = new List<Category>(); 
    // Some code to load the data 
    return ret; 
    } 
} 

然後就可以從Phalanger網站(使用web.config)引用C#庫,並使用由Phalanger提供PHP擴展使用Data類作爲如果這是一個標準的PHP對象:

<? 
    import namespace DemoDataLayer; 
    $dl = new Data; 
    $categories = $dl->GetCategories(); 
?> 
<ul> 
<? foreach($categories as $c) { ?> 
    <li><a href="products.php?id=<? echo $c->ID ?>"><? echo $c->Name ?></a></li> 
<? } ?> 
</ul> 

要配置的參考,您需要將C#DLL添加到bin目錄,並將其納入classLibrary元素。上面使用的import namespace語法是Phalanger特定的語言擴展名(使用.NET命名空間),需要使用PhpClr功能被打開:

<?xml version="1.0"?> 
<configuration> 
    <phpNet> 
    <compiler> 
     <set name="LanguageFeatures"> 
     <add value="PhpClr" /> 
     </set> 
    </compiler> 
    <classLibrary> 
     <add assembly="DemoDataLayer" /> 
    </classLibrary> 
    </phpNet> 
</configuration> 
+0

感謝您的回答托馬斯,但我希望能圓做它的其他方式:有.NET代碼調用php腳本並傳遞參數以自動創建一個像「$ categories」這樣的綁定,以最小化必須編寫的「php .net」代碼的數量。這可能嗎? – Robert 2011-05-27 10:23:01

+0

@羅伯特:是的,還有一些方法可以做到這一點(我需要檢查細節)。問題是,你想如何實例化PHP代碼?如果你使用ASP.NET MVC,我假設你想在你的控制器中使用'return PhpView(「foo.php」)''。 (目前沒有這方面的支持,但這聽起來很有趣,它肯定可以完成!) – 2011-05-27 23:14:36

+0

我有我自己的MVC框架,它有它自己的F#ish調用視圖的方式,但基本上你會做一些像返回PhpView(「foo.php」)來調用PHP視圖。我一直在看,它看起來很難,因爲所有與編譯腳本相關的東西都被標記爲內部。看起來它需要製作phalanger的自定義版本並更改一些可見性設置。 – Robert 2011-05-28 07:05:50

1

退房http://phpviewengine.codeplex.com/

該項目包含了以下方法轉換CLR類型的形式,你的PHP腳本可以使用:

object PhpSafeType(object o) 
    { 
     // PHP can handle bool, int, double, and long 
     if ((o is int) || (o is double) || (o is long) || (o is bool)) 
     { 
      return o; 
     } 
     // but PHP cannot handle float - convert them to double 
     else if (o is float) 
     { 
      return (double) (float) o; 
     } 
     // Strings and byte arrays require special handling 
     else if (o is string) 
     { 
      return new PhpString((string) o); 
     } 
     else if (o is byte[]) 
     { 
      return new PhpBytes((byte[]) o); 
     } 
     // Convert .NET collections into PHP arrays 
     else if (o is ICollection) 
     { 
      var ca = new PhpArray(); 
      if (o is IDictionary) 
      { 
       var dict = o as IDictionary; 
       foreach(var key in dict.Keys) 
       { 
        var val = PhpSafeType(dict[key]); 
        ca.SetArrayItem(PhpSafeType(key), val); 
       } 
      } 
      else 
      { 
       foreach(var item in (ICollection) o) 
       { 
        ca.Add(PhpSafeType(item)); 
       } 
      } 
      return ca; 
     } 
     // PHP types are obviously ok and can just move along 
     if (o is DObject) 
     { 
      return o; 
     } 
     // Wrap all remaining CLR types so that PHP can handle tham 
     return PHP.Core.Reflection.ClrObject.WrapRealObject(o); 
    } 

可以使用這樣的...

// Get setup 
var sc = new ScriptContext.CurrentContext; 
var clrObject = /* Some CLR object */ 
string code = /* PHP code that you want to execute */ 

// Pass your CLR object(s) into the PHP context 
Operators.SetVariable(sc,null,"desiredPhpVariableName",PhpSafeType(clrObject)); 

// Execute your PHP (the PHP code will be able to see the CLR object) 
var result =   return DynamicCode.Eval(
       code, 
       false, 
       sc, 
       null, 
       null, 
       null, 
       "default", 
       1,1, 
       -1, 
       null 
       ); 

這甚至可以處理匿名類型。例如,在上面插入以下內容。

var clrObject = new { Name = "Fred Smith" }; 
Operators.SetVariable(sc,null,"person",PhpSafeType(clrObject)); 

然後,您可以訪問這個在PHP:

echo $person->Name; 

這當然輸出Fred Smith

相關問題