Использование phalanger в качестве части представления приложения MVC
Чтобы улучшить взаимодействие между пользователем UI, который знает HTML, и бэкэндом, который знает.NET, мы думаем об архитектуре, в которой мы используем веб-приложение MVC и используем phalanger в качестве движка представления.
Интеграция phalanager в качестве модели представления выглядит довольно легко, за исключением одной точки. Я не уверен, как передать модель скрипту страницы. Есть идеи, как этого достичь?
Одной из идей было бы вызвать статический метод.NET из сценария php, но это выглядит немного странно. Я хотел бы иметь возможность просто передать параметр в сценарий и иметь возможность сценария подобрать его в переменной.
2 ответа
Использование.NET на бэкэнде и PHP (с использованием Phalanger) на веб-интерфейсе выглядит хорошим сценарием. Я думаю, что лучший вариант - реализовать модель в.NET и использовать PHP для реализации контроллеров и представлений (либо напрямую, либо с использованием некоторого PHP-фреймворка).
Вызвать модель.NET из PHP, скомпилированного с помощью Phalanger, довольно просто, потому что код 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# с веб-сайта Phalanger (используя web.config
) и использовать расширения PHP, предоставленные Phalanger, для 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