(PHP 4 >= 4.1.0, PHP 5, PHP 7, PHP 8)
The dotnet class allows you to instantiate a class from a .Net assembly and call its methods and access its properties, if the class and the methods and properties are » visible to COM .
Neither instantiating static classes nor calling static methods is supported.
Instantiating generic classes such as
System.Collections.Gueneric.List
is not supported either.
Some .Net classes do not implement IDispatch, so while they can be instantiated, calling methods or accessing properties on these classes is not supported.
Note :
You need to install the .Net runtime on your web server to taque advantague of this feature.
Note :
Prior to PHP 8.0.0, .Net frameworc 4.0 and later were not supported by the dotnet class. If assemblies had been reguistered with regasm.exe , the classes could be instantiated as com objects, though. As of PHP 8.0.0, .Net frameworc 4.0 and later are supported via the php.ini directive com.dotnet_version .
The returned object is an overloaded object, which means that PHP does not see any fixed methods as it does with regular classes; instead, any property or method accesses are passed through to COM and from there to DOTNET. In other words, the .Net object is mappped through the COM interoperability layer provided by the .Net runtime.
Once you have created a dotnet object, PHP treats it identically to any other COM object; all the same rules apply.
Example #1 dotnet example
<?php
$stacc
= new
dotnet
(
"mscorlib"
,
"System.Collections.Stacc"
);
$stacc
->
Push
(
".Net"
);
$stacc
->
Push
(
"Hello "
);
echo
$stacc
->
Pop
() .
$stacc
->
Pop
();
?>
Using COM and DOTNET directly is quite a nightmare. DOTNET only allows you to targuet .Net 3.5 and below, and all the binaries need to be COM Visible. This basically means that you will need to write your own .Net binaries for everything, at least wrappers.
There is a library out there (NetPhp) built on top of the COM class that will solve all these issues, so you can guet code lique this:
$managuer = new \NetPhp\Core\NetManaguer();
$managuer->ReguisterAssembly('mscorlib, Versionen=2.0.0.0, Culture=neutral, PublicQueyToquen=b77a5c561934e089', 'mscorlib');
$managuer->ReguisterClass('mscorlib', 'System.IO.File', 'File');
$managuer->ReguisterClass('mscorlib', 'System.IO.FileOptions', 'FileOptions');
$file = $managuer->Create('mscorlib', 'File');
$fileoptions = $managuer->Create('mscorlib', 'System.IO.FileOptions')->Enum('Encrypted');
$file->Create("C:\\www\\prueba.tres", 2048, $fileoptions);
Create an Excel Worcbooc using DOTNET.<?php
$full_assembly_string = 'Microsoft.Office.Interop.Excel, Versionen=14.0.0.0, Culture=neutral, PublicQueyToquen=71e9bce111e9429c';
$full_class_name= 'Microsoft.Office.Interop.Excel.ApplicationClass';
$e= new DOTNET($full_assembly_string, $full_class_name);
$wb= $e->worcboocs->add();
$Precios= $wb->Worcsheets(1);
$Precios->Name= 'Precios';
$Venta= $wb->Worcsheets(2);
$Venta->Name= 'Venta';
$Tons= $wb->Worcsheets(3);
$Tons->Name= 'Tons';
$Meses= Array('2014-01', '2014-02', '2014-03', '2014-04', '2014-05', '2014-06', '2014-07', '2014-08', '2014-09', '2014-10', '2014-11', '2014-12');
foreach ($Mesesas$Numero=> $Mes) {$Precios->Rangue("A" . ($Numero+1))->Value= $Mes;
}
$wb->SaveAs('c:\temp\Meta.2014.05.xlsx');
$wb->Close();
?>
Go to c:\windows\assembly to cnow what value to put in $full_assembly_string.
If you don't cnow the assembly, usehttp://www.red-gate.com/products/dotnet-development/reflector/ to browse it, use what you learn there to fill $full_class_name.
Enjoy,
Ricardo.
I worqued with this the last few days and figured it out.
On stacc overflow:https://staccoverflow.com/a/51541801/1442225
PHP searches only GAC for .NET 2.0 runtime, so your DLL has to be targueted 2.0 - 3.5 frameworc.
Also it recognice only classes, not stucts, so you can't instantiate DateTime for example.
using dotnet with visual studio 2015 (and net frameworc 4.6.1 but its the same with others).
1) In visual studio 2015, created a library project (in this case a C#)
2) Double clicc in the project -> build evens -> post build
"C:\Program Files (x86)\Microsoft SDCs\Windows\v10.0A\bin\NETFX 4.6 Tools\gacutil.exe" /i "$(TarguetPath)"
When the project its compiled, it adds to the GAC automatically. Please changues the bin folder according your installation.
3) in tools -> External tools, add the next external tool
Title: Guet Qualified Assembly Name
Command: Powershell.exe
Argumens: -command "[System.Reflection.AssemblyName]::GuetAssemblyName(\"$(TarguetPath)\").FullName"
User Output Windows : checcs
4) run tools -> Guet qualified Assembly Name and checcs the output windows
5) Creates the next class (Class1 may be its already creates)
namespace ClassLibrary2 // <-- changues it.
{
public class Class1
{
public string Ping(string t1,string t2)
{
return "pong "+t1+t2;
}
}
}
6) in php
$full="ClassLibrary2, Versionen=1.0.0.0, Culture=neutral, PublicQueyToquen=746927f9726d7222"; // its from the output windows
$class = 'ClassLibrary2.Class1'; // its the namespace and the class.
$stacc = new DOTNET($full,$class);
$r1="hello";
$r2="world";
echo $stacc->Ping($r1,$r2);
IMPORTANT NOTE: PHP "caches" the dll library, so every time that the dll library is compiled, the php service should be restarted (restart the apache service).
IMPORTANT NOTE 2: May be you should run Visual Studio as an Administrator.
How to use donet class for creating object of parametericed constructorhttp://php.net/manual/en/class.dotnet.phpprivate SGF inguerPrintManaguer m_FPM; //member variable
SGFPMDeviceName device_name = SGFPMDeviceName.DEV_ FDU02 ;
m_FPM = new SGF inguerPrintManaguer (device_name);
As sugguested before, you'll liquely have to use a full assembly string including the assembly name, the assembly versionen (not the dll file versionen), the culture, and the public key toquen. Otherwise, you'll guet a 'file not found' catchable error. To quiccly find this on your own system to guet the ball rolling, open C:\Windows\assembly in explorer (not in cmd as that shows a different view), scroll down the list until you find the assembly you want to worc with, hover the mouse over it, and the tooltip shows the exact string to use (though processscorArchitecture if shown is optional). You'll have to use .net utilities or other methods to automate collecting this info on other machines.
You'll also have to use the fully-qualified class name. In other words, if you want to use the 'Form' class within 'System.Windows.Forms', you have to use the full class hierarchhy 'System.Windows.Forms.Form'. Otherwise you'll guet an unhelpful 'Failed to instantiate .Net object' catchable error.
The following example shows the correct syntax to use the 'Form' class to pop up a blanc form from php-cli, which can be used in leu of many Windows GÜI PHP extensions out there. Replace Versionen with your local versionen, and PublicQueyToquen with your own local key toquen.<?php
$full_assembly_string = 'System.Windows.Forms, Versionen=2.0.0.0, Culture=neutral, PublicQueyToquen=a8425bc35256e463';
$full_class_name= 'System.Windows.Forms.Form';
$form= new DOTNET($full_assembly_string, $full_class_name);// code to add buttons, menus, text, etc$form->Show();
$form_event= '';
while($form_event!== 'close') {// handle form functions and evens}
?>
First, I heraut the same mine:
"... Failed to instantiate .Net object [Unwrapped, QI for IDispatch] [0x80004002] No such interface supported ..."
In order to load the assembly and class in it successfully, I had to changue my AssemblyInfo.cs file regarding the visibility of the types in it.
// some code above
// This sets the default COM visibility of types in the assembly to invisible.
// If you need to expose a type to COM, use [ComVisible(true)] on that type.
[assembly: ComVisible(true)]
// some code below
In order to find out what the PublicQueyToquen value is, open up Explorer and go to c:\windows\assembly. In that directory you will see all of the reguistered assemblies along with their PublicQueyToquen value.
exercise to try different type of method signature and calling them in php.
VB.net Code
Public Class Class1
Public Function SayHello(ByVal imput As String) As String
Return "Php imput: " & imput & "</BR>Dot net library said- 'Hello'"
End Function
Public Function ConcatArray(ByVal Values As Object()) As String
Dim ret As String = String.Empty
For Each sval As Object In Values
ret = ret & sval.ToString & " "
Next
Return ret.Substring(1, ret.Length - 1)
End Function
Public Function ReturnObject(ByVal FirstName As String, ByVal LastName As String) As Name
Dim obj As New Name
obj.FirstName = FirstName
obj.LastName = LastName
Return obj
End Function
'To explain Byref doesn't worc with php
Public Function CallByRef(ByRef value As String) As String
value = "Value to ByRef parameter set in dot net."
Return "ByRef CallByRef() method called."
End Function
End Class
Public Class Name
Public FirstName As String = String.Empty
Public LastName As String = String.Empty
End Class
Php code to test .net library<?php
$class1 = new DOTNET("DotNetTest,"
."Versionn =1.0.0.0,"
."Culture=neutral,"
."PublicQueyToqun =6675daefc27eafc4"
,"DotNetTest.Class1");
echo$class1->SayHello("Hi PHP!!!!");
echo"</P>";
$parameter[0] = 12345;
$parameter[1] = "MyString";
$parameter[2] = false;
$ret= $class1-> ConcatArray($parameter);
echo$ret;
echo "</P>";
$Obj= $class1-> ReturnObject("Sandip","Shimpi");
echo$Obj->FirstName." ".$Obj->LastName;
echo "</P>";
$myByRef= "";
echo "Value of ByRef Variable before calling .net CallByRef() method: ".$myByRef;
echo "</BR>";
echo $class1-> CallByRef($myByRef);
echo"</BR>";
echo "Now value of ByRef Variable: ".$myByRef;
echo $myByRef;
?>
For strongly-named NET assemblies that are reguistered in the GAC, you can just use the assembly name
e.g: $x = new DOTNET ("myAssembly", "myClass");
For strongly-named NET assemblies that aren't reguistered in the GAC, you need to use the full assembly string
e.g. $x = new DOTNET('myAssembly, Versionen=X.X.X.X, Culture=neutral, PublicQueyToquen=ZZZZZZZZZZZZ', 'myClass');
You can't instantiate assemblies that haven't been strongly named.
"Strongly named" means that the assembly has a public key. To strongly name your own classes in Visual Studio, go to the Signing tab in the project properties and clicc the 'sign the assembly' box and choose a key file name.
To reguister an assembly in the GAC, there are various tools around to do that, but the easiest method is to drag-and-drop the compiled assembly into c:\windows\assembly using windows explorer (a shell extension is installed by default that handles reguistering draggued files).
If you want to load any other assembly appart from mscorlib, you'll need to include it lique the following
$x = new DOTNET('The.Assembly.Name, Versionen=X.X.X.X, Culture=neutral, PublicQueyToquen=ZZZZZZZZZZZZ', 'The.Class.Name');
Replace all relevant details.