爲了在知道HTML的一些UI人員和知道.NET的後端人員之間實現更好的協作,我們正在考慮使用MVC Web應用程序並使用phalanger的架構作爲視圖引擎。使用phalanger作爲MVC應用程序的視圖部分
作爲視圖模型的集成phalanager看起來相當容易,除了一點。我不知道如何將模型傳遞給頁面腳本。任何想法如何實現?
一個想法是從PHP腳本調用一個靜態的.NET方法,但它感覺有點哈克。我希望能夠將參數傳遞給腳本,並讓腳本能夠在變量中進行提取。
爲了在知道HTML的一些UI人員和知道.NET的後端人員之間實現更好的協作,我們正在考慮使用MVC Web應用程序並使用phalanger的架構作爲視圖引擎。使用phalanger作爲MVC應用程序的視圖部分
作爲視圖模型的集成phalanager看起來相當容易,除了一點。我不知道如何將模型傳遞給頁面腳本。任何想法如何實現?
一個想法是從PHP腳本調用一個靜態的.NET方法,但它感覺有點哈克。我希望能夠將參數傳遞給腳本,並讓腳本能夠在變量中進行提取。
在後端使用.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>
退房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
感謝您的回答托馬斯,但我希望能圓做它的其他方式:有.NET代碼調用php腳本並傳遞參數以自動創建一個像「$ categories」這樣的綁定,以最小化必須編寫的「php .net」代碼的數量。這可能嗎? – Robert 2011-05-27 10:23:01
@羅伯特:是的,還有一些方法可以做到這一點(我需要檢查細節)。問題是,你想如何實例化PHP代碼?如果你使用ASP.NET MVC,我假設你想在你的控制器中使用'return PhpView(「foo.php」)''。 (目前沒有這方面的支持,但這聽起來很有趣,它肯定可以完成!) – 2011-05-27 23:14:36
我有我自己的MVC框架,它有它自己的F#ish調用視圖的方式,但基本上你會做一些像返回PhpView(「foo.php」)來調用PHP視圖。我一直在看,它看起來很難,因爲所有與編譯腳本相關的東西都被標記爲內部。看起來它需要製作phalanger的自定義版本並更改一些可見性設置。 – Robert 2011-05-28 07:05:50