PHP DOTNET地狱

Mar*_*rco 8 .net php c#

我是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));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

拉高速双组装globale contiene GLI装配seguenti:
csharpcom,版本= 1.0.0.0,文化=中性公钥= beb607ae770f5750,ProcessorArchitecture用于= MSIL

Numero di elementi = 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";
}
?>
Run Code Online (Sandbox Code Playgroud)

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

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

另一件事:使用一些例子(这里是一个非常基本的例子)我读到我的装配(注册时)应该找到%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');
Run Code Online (Sandbox Code Playgroud)

但这个没有:

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

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

hea*_*vyd 6

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

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


小智 5

有一个名为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;
Run Code Online (Sandbox Code Playgroud)