PHP DOTNET地狱

时间:2012-04-18 14:06:56

标签: c# php .net

我是PHP的新手,今天我发现了DOTNET类 所以我学习了手册,浏览网页找到一些例子,最后编写了我的测试应用程序:

  1. 使用Framework 4.0 Client Profile
  2. 创建了一个新DLL
  3. 使用强名称密钥签署程序集
  4. 将标记的程序集标记为COM-Visible
  5. 这是我写的测试代码

    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,版本= 1.0.0.0,文化=中立,   PublicKeyToken = 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";
    }
    ?>
    

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

      

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

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

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

    最后注意:我在Windows XP Professional SP3 32位和Windows 7 Enterprise 64位

    上尝试过

    更新
    这有效:

    $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程序集?

2 个答案:

答案 0 :(得分:6)

根据这个bug report,DOTNET类没有加载.NET 4.0 DLL。如果您没有使用.NET 4.0中的任何新库,则可以通过打开项目属性将目标指向.NET 3.5或更低版本,并在“应用程序”选项卡上将“目标框架”更改为“.NET Framework 3.5客户端”简介“

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

答案 1 :(得分:5)

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

  • 使用任何.Net二进制文件(即使没有COM可见性)和任何版本的.Net框架,包括CLR4
  • 转储PHP类模型
  • 直接从PHP迭代.Net集合 PHP类的模型生成,使用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;