Problem using DOTNET with PHP.

I tried to call the .net assembly with PHP via com (using DOTNET ()). It seems that php finds the DLL and initializes correctly, but for some reason I do not see / use the methods. Does anyone know how I can fix this?

Here is the php code that I use to call the .net class. When I call this, "hello1 hello2" is issued. When I try to directly call a function by executing $ csclass-> ModelBuilder ("," "), I get a 500 server error indicating that it cannot find this function.

<?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"; ?> 

Here is the class in the assembly I'm trying to call (built using .net 3.5, signed with a strong name and registered with gacutil):

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using OfficeOpenXml; using System.Runtime.InteropServices; namespace ModelBuilder { [ClassInterface(ClassInterfaceType.AutoDual)] [ComVisible(true)] public class ModelBuilder2 { [ComVisible(true)] public Boolean BuildModel(String outputFileLoc,String excelTemplateFile) { try { //do stuff return true; } catch (Exception e) { return false; } } } 
+4
source share
1 answer

get_class_methods() will not work with an object of the Dotnet class. This thing is a proxy server and it does not behave like a regular php object does.

If you are really focused on listing the methods of an object, you need to study the implementation of IDispatch on your .NET object. If, however, your main goal is simply to use a .NET object, and your attempt to list the methods was just a side effort to diagnose why this does not work, then I have some suggestions for you.

  • rather than using gacutil , think about whether you can insert the desired DLL into the php directory where php.exe is located. If php.exe is located in c:\php5\php.exe , then copy your assembly to c:\php5 .

  • If you follow the suggestion above, the .NET assembly does not have to be strongly named. It should be strongly named if you plan to use it. As I said, you do not need to use the GAC to download it using php. If you copy the assembly to the PHP directory, you can use an unsigned assembly.

  • For early development and research with this, use the php.exe program from the command line, instead of using IIS to run php through a web request. This allows you to see error messages directly, rather than worry about 500 errors from IIS.


Example

Suppose this is C # code:

 using System; namespace Ionic { public class MathEx { System.Random rnd; public MathEx () { rnd = new System.Random(); } public int RandomEven() { return rnd.Next()*2; } } } 

Compile it from the command line as follows:

 c:\net3.5\csc.exe /t:library /out:Ionic.MathEx.dll MathEx.cs 

copy the assembly to the directory containing the php.exe file:

 copy Ionic.MathEx.dll \php 1 file(s) copied. 

Then suppose I have a php script called mathex.php with this content:

 <?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"; } ?> 

... and if I ran it from the command line as follows:

 \php\php.exe mathex.php 

... then I get the following results:

 0 -1083602762 1 1535669896 2 -86761710 3 -1204365564 4 459406052 

Nota bene

I tried to do this using an assembly compiled with .NET 4.0, but this did not work by reporting me a .NET runtime mismatch error message. Like this:

 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 

0x8013101b indicates a run-time mismatch - the build version of the assembly does not match the version of the runtime of the application that is trying to load the assembly.

From this, I conclude that php5 is compiled to support .NET 2.0 (including 3.0 and 3.5). The runtime version has changed for .NET 4.0, so the assemblies that you compile using the .NET 4.0 compiler (including VS2010) will not be used with php5.exe. The workaround is to compile with the .NET 2.0 or 3.5 compiler (VS2005, vs2008).

+8
source

Source: https://habr.com/ru/post/1415772/


All Articles