从PHP使用DOTNET时遇到问题。
我一直在尝试通过com(使用DOTNET())从PHP调用.net程序集。看起来php正在查找DLL并正确初始化,但由于某些原因,我无法查看/使用这些方法。有人知道我该怎么解决这个问题吗 下面是我用来调用.net类的php代码。当我叫它时,输出是“hello1 hello2”。当我试图通过执行$csclass->ModelBuilder(“,”)直接调用该函数时,我得到一个500服务器错误,指定它找不到该函数从PHP使用DOTNET时遇到问题。,php,.net,iis-7,windows-server-2008,Php,.net,Iis 7,Windows Server 2008,我一直在尝试通过com(使用DOTNET())从PHP调用.net程序集。看起来php正在查找DLL并正确初始化,但由于某些原因,我无法查看/使用这些方法。有人知道我该怎么解决这个问题吗 下面是我用来调用.net类的php代码。当我叫它时,输出是“hello1 hello2”。当我试图通过执行$csclass->ModelBuilder(“,”)直接调用该函数时,我得到一个500服务器错误,指定它找不到该函数 <?php echo "hello1"; try{ $csclass = new
<?php
echo "hello1";
try{
$csclass = new DOTNET("ModelBuilder, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1208136d23b48dc5",
"ModelBuilder.ModelBuilder2");
$class_methods = get_class_methods($csclass);
foreach ($class_methods as $method_name) {
echo "$method_name\n";
}
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
echo "hello2";
?>
get\u class\u methods()。这是一个代理,它的行为与普通php对象不同
如果您真的专注于列出对象的方法,那么您需要研究在.NET对象上实现IDispatch。但是,如果您的主要目标是简单地使用.NET对象,而您尝试列出这些方法只是为了诊断为什么不起作用,那么我有一些建议给您
<> >而不是使用<代码> GACUTIL < /C> >,考虑是否可以将所需的DLL插入PHP目录中,PHP.EXE所在的位置。如果php.exe
位于c:\php5\php.exe
,则
将程序集复制到c:\php5
中
如果遵循上述建议,则无需对.NET程序集进行强命名。如果您计划对其进行GAC,则需要对其进行强烈命名。正如我所说的,为了用php加载它,不需要对其进行GAC。如果将程序集复制到PHP目录中,则可以使用未签名的程序集
对于这方面的早期开发和探索,请使用命令行中的php.exe
程序,而不是使用IIS通过web请求启动php。这使您可以直接看到错误消息,而不用担心来自IIS的500个错误
例子
假设这是C代码:
从命令行编译它,如下所示:
c:\net3.5\csc.exe /t:library /out:Ionic.MathEx.dll MathEx.cs
将程序集复制到包含php.exe的目录:
copy Ionic.MathEx.dll \php
1 file(s) copied.
然后,假设我有一个名为mathex.php的php脚本,其中包含以下内容:
<?php
$my_assembly = 'Ionic.MathEx'; // name of the dll without the .dll suffix
$clz = new DOTNET($my_assembly, 'Ionic.MathEx');
for ($i=0; $i<5; $i++) {
echo $i . " " . $clz->RandomEven() . "\n";
}
?>
…然后我得到以下结果:
0 -1083602762
1 1535669896
2 -86761710
3 -1204365564
4 459406052
Nota Bene
我尝试使用.NET 4.0编译的程序集执行此操作,但它不起作用,给我一条关于.NET运行时不匹配的错误消息。像这样:
Fatal error: Uncaught exception 'com_exception' with message 'Failed to instantiate .Net object
[CreateInstance] [0x8013101b] ' in C:\dev\php\mathEx.php:6
Stack trace:
#0 C:\dev\php\mathEx.php(6): dotnet->dotnet('Ionic.MathEx', 'Ionic.MathEx')
#1 {main}
thrown in C:\dev\php\mathEx.php on line 6
0x801310B
表示运行时不匹配-程序集的运行时版本与尝试加载程序集的应用程序的运行时版本不匹配
由此我得出结论,php5的编译是为了支持.NET2.0(包括3.0和3.5)。.NET 4.0的运行时版本已更改,因此使用.NET 4.0编译器(包括VS2010)编译的程序集将无法与php5.exe一起使用。解决方法是只使用.NET2.0或3.5编译器(VS2005、vs2008)进行编译 您是否尝试过var\u dump
ing$classmethods
?var\u dump()生成数组(0){}。。。因此,出于某种原因,这些方法似乎是看不见的。知道吗?也许我遗漏了什么,但它不起作用。我在php文件夹中有DLL,并调用php.exe example.php。它似乎没有使用DLL(没有错误,但如果我更改DLL的名称,则不会引发错误,并且当我调用该DLL中存在或不存在的函数时,不会出现错误)。(1) 还有什么我需要做的吗?(2) DLL可以执行的操作类型是否有限制?(除了要使用哪个版本的.net之外)(添加到上面的注释):当我调用example.php时,它会在DOTNET()函数行停止生成HTML,但不会抛出任何错误。不确定出了什么问题。你使用我提供的代码了吗?完全按照我的建议编译?我认为你需要简化。只要做些基本的工作就行了。向自己证明它是有效的。然后增加复杂性。似乎是使用默认的“调试”配置而不是visual studio中默认的“发布”配置生成的DLL导致了问题。PHP一定不喜欢调试标志之类的东西。嗯,听起来好像你解决了问题。我怀疑引起问题的仅仅是构建的调试配置。我刚刚尝试了/debug+
,效果很好。它可能是平台(MSIL vs x86)。使用4.0运行时版本(VS2.0)肯定会导致问题。使用错误的目标平台也可能导致问题。不管怎样,很高兴你解决了。
\php\php.exe mathex.php
0 -1083602762
1 1535669896
2 -86761710
3 -1204365564
4 459406052
Fatal error: Uncaught exception 'com_exception' with message 'Failed to instantiate .Net object
[CreateInstance] [0x8013101b] ' in C:\dev\php\mathEx.php:6
Stack trace:
#0 C:\dev\php\mathEx.php(6): dotnet->dotnet('Ionic.MathEx', 'Ionic.MathEx')
#1 {main}
thrown in C:\dev\php\mathEx.php on line 6