8

我是 PHP 的新手,今天我发现了DOTNET类。
所以我研究了手册,上网找了一些例子,最后写了我的测试应用程序:

  1. 使用 Framework 4.0 Client Profile 创建了一个新的 DLL
  2. 使用强名称密钥签署程序集
  3. 将程序集标记为 COM-Visible

这是我写的测试代码

using System;

namespace CSharpCOM
{
    public class CSharpCOMClass
    {
        public string Base64(string s)
        {
            return Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(s));
        }
    }
}

我编译了程序集,然后在 GAC ( gacutil /if fullpath\CSharpCOM.dll) 中注册。
如果我使用gacutil /l CSharpCOM我看到

La cache di assembly globale contiene gli assembly seguenti:
csharpcom,Version=1.0.0.0,Culture=neutral,PublicKeyToken=beb607ae770f5750,processorArchitecture=MSIL

元素数 = 1

所以一切似乎都很好。
然后写了这个基本的php:

<?php
try{
    $csclass = new DOTNET("CSharpCOM, Version=1.0.0.0, Culture=neutral, " .
                          "PublicKeyToken=beb607ae770f5750",
                          "CSharpCOM.CSharpCOMClass");
    echo $csclass->Base64("Test string"),"\n";
} catch (Exception $e) {
    echo 'Caught exception: ',  $e->getMessage(), "\n";
}
?>

无论我尝试什么,加载托管在 Apache ( http://localhost/test01/dotnet.php) 中的页面我总是得到

捕获的异常:无法实例化 .Net 对象 [CreateInstance] [0x80070002] 不可能的 trovare il 文件规范。
翻译可能是:找不到指定的文件

还有一件事:使用一些例子(这里是一个非常基本的例子)我读到我的程序集(注册时)应该在 上找到%windir%\assembly,但我只能在%windi%\Microsoft.NET\assembly\GAC_MSIL\CSharpCOM\v4.0_1.0.0.0__beb607ae770f5750: 这是正确的吗?为什么我的第一个目录没有它?

更多:如果我创建另一个框架项目并尝试添加 .NET 引用,我找不到我的程序集:这与我无法从 PHP 加载此程序集有关吗?

最后一点:我在 Windows XP Professional SP3 32bit 和 Windows Seven Enterprise 64bit 上试过

更新:
这有效:

$form = new DOTNET('System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089', 'System.Windows.Forms.Form');

但是这个没有:

$form = new DOTNET('System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089', 'System.Windows.Forms.Form');`  

PHP 是否有可能只加载框架 2.0 程序集?

4

2 回答 2

7

根据这个错误报告,DOTNET 类没有加载 .NET 4.0 DLL。如果您没有使用 .NET 4.0 中的任何新库,您可以通过打开项目属性并在“应用程序”选项卡上将“目标框架”更改为“.NET Framework 3.5 客户端”来定位到 .NET 3.5 或更低版本轮廓”

现在,当您将 DLL 安装到 GAC 中时,它将安装到 CLR 2.0 GAC 中,并且应该能够使用 PHP 中的 DOTNET 类进行加载。

于 2012-04-18T14:50:45.177 回答
6

有一个名为 NetPhp ( https://github.com/david-garcia-garcia/netphp ) 的库可以让你:

  • 使用任何 .Net 二进制文件(即使没有 COM 可见性)和任何版本的 .Net 框架,包括 CLR4
  • 转储 PHP 类模型
  • 直接从 PHP PHP 类模型生成迭代 .Net 集合,以使用 PHP 类,就像在 .Net 中一样 将 .Net 错误自动传播到可以正确处理的原生 PHP 异常中
  • 访问本机枚举和静态方法
  • 使用带参数的类构造函数
  • 同时调试 .Net 和 PHP 代码,就好像它是一个应用程序一样。

这里有一个带有代码示例的项目:

https://github.com/david-garcia-garcia/netphp-sample

这是一段带有 NetPhp 的代码的样子:

$datetime = $runtime->TypeFromName("System.DateTime");
$datetime->Instantiate();

echo $datetime->ToShortDateString()->Val(); // Outputs 01/01/0001

// We can only use Int32 from native PHP, so parse
// an Int64 that is equivalent to (long) in the DateTime constructor.
$ticks = $runtime->TypeFromName("System.Int64")->Parse('98566569856565656');
$ticks = \ms\System\netInt64::_Parse('98566569856565656');

$datetime->Instantiate($ticks);
echo $datetime->ToShortDateString()->Val(); // Outputs 07/05/0313

$now = $runtime->TypeFromName("System.DateTime")->Now;
echo $now->ToShortDateString()->Val(); // Outputs "23/10/2015"

$now = $runtime->TypeFromName("System.DateTime")->Now();
echo $now->ToShortDateString()->Val(); // Outputs "23/10/2015"

$timer = $runtime->TypeFromName("System.Timers.Timer")->Instantiate();
$timer->AutoReset(TRUE);
$timer->AutoReset = TRUE;
于 2016-01-10T16:50:55.063 回答