Asp.net mvc 使用phalanger作为MVC应用程序的视图部分

Asp.net mvc 使用phalanger作为MVC应用程序的视图部分,asp.net-mvc,phalanger,Asp.net Mvc,Phalanger,为了使一些熟悉HTML的用户界面人员和熟悉.NET的后端人员能够更好地协作,我们正在考虑一种使用MVC web应用程序并使用phalanger作为视图引擎的架构 除了一点之外,将PhalManager集成为视图模型看起来相当容易。我不确定如何将模型传递到页面脚本。有什么想法可以实现这一点吗 一个想法是从php脚本中调用静态的.NET方法,但感觉有点粗糙。我希望能够将参数传递给脚本,并让脚本能够在变量中提取它。在后端使用.NET,在前端使用PHP(使用Phalanger)看起来是一个不错的方案。我

为了使一些熟悉HTML的用户界面人员和熟悉.NET的后端人员能够更好地协作,我们正在考虑一种使用MVC web应用程序并使用phalanger作为视图引擎的架构

除了一点之外,将PhalManager集成为视图模型看起来相当容易。我不确定如何将模型传递到页面脚本。有什么想法可以实现这一点吗


一个想法是从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;
  }
}
要配置引用,需要将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>

退房

该项目包含以下方法,用于将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

感谢Tomas的回答,但我希望用另一种方式:让.NET代码调用php脚本并传递它的参数来自动创建像“$categories”这样的绑定,以最大限度地减少必须编写的“php.NET”代码的数量。这可能吗?@Robert:是的,也有办法做到这一点(我需要查看细节)。问题是,您希望如何实例化PHP代码?如果您使用的是ASP.NET MVC,我假设您希望控制器中有类似于
return PhpView(“foo.php”)
的内容?(目前还没有对此的支持,但这听起来很有趣,而且肯定可以做到!)我有自己的类似mvc的框架,它有自己的调用视图的F#ish方式,但基本上你会做一些类似return PhpView(“foo.php”)的事情来调用php视图。我现在正在研究它,它看起来很难,因为所有与脚本编译相关的东西都标记为内部的。看起来需要定制phalanger并更改一些可见性设置。
echo $person->Name;