为了使一些了解 HTML 的 UI 人员和了解 .NET 的后端人员之间能够更好地协作,我们正在考虑使用 MVC Web 应用程序并使用 phalanger 作为视图引擎的架构。
除了一点之外,将 phalanager 集成为视图模型看起来相当容易。我不确定如何将模型传递给页面脚本。任何想法如何实现?
一个想法是从 php 脚本调用静态 .NET 方法,但感觉有点笨拙。我希望能够将参数传递给脚本并让脚本能够在变量中获取它。
为了使一些了解 HTML 的 UI 人员和了解 .NET 的后端人员之间能够更好地协作,我们正在考虑使用 MVC Web 应用程序并使用 phalanger 作为视图引擎的架构。
除了一点之外,将 phalanager 集成为视图模型看起来相当容易。我不确定如何将模型传递给页面脚本。任何想法如何实现?
一个想法是从 php 脚本调用静态 .NET 方法,但感觉有点笨拙。我希望能够将参数传递给脚本并让脚本能够在变量中获取它。
在后端使用 .NET,在前端使用 PHP(使用 Phalanger)看起来是一个不错的场景。我认为最好的选择是在 .NET 中实现模型并使用 PHP 来实现控制器和视图(直接或使用一些 PHP 框架)。
从使用 Phalanger 编译的 PHP 调用 .NET 模型非常容易,因为 PHP 代码可以访问 .NET 对象。假设您有一个 C# DLL,其中包含DemoDataLayer
具有以下类型的命名空间:
public class Data {
public List<Category> GetCategories() {
var ret = new List<Category>();
// Some code to load the data
return ret;
}
}
然后,您可以从 Phalanger 网站(使用 )引用 C# 库,web.config
并使用 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
element.xml 中。上面使用的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