Класс dotnet

(PHP 4 >= 4.1.0, PHP 5, PHP 7, PHP 8)

Введение

Класс dotnet позволяет создавать объекты из сборок .Net, вызывать их методы и использовать их свойства, если класс, методы и свойства » видимы для COM.

Ни создание экземпляров статических классов, ни вызов статических методов не поддерживаются. Создание экземпляров универсальных классов, таких как System.Collections.Generic.List, также не поддерживается.

Некоторые классы в .Net не реализуют IDispatch, поэтому, хотя их объекты можно создавать, вызов методов или доступ к свойствам этих классов не поддерживается.

Замечание:

Вам нужно установить библиотеки времени исполнения .Net на ваш веб-сервер, чтобы воспользоваться этой функцией.

Замечание:

До PHP 8.0.0 .Net framework 4.0 и более поздние версии не поддерживаются классом dotnet. Однако если сборки были зарегистрированы с помощью regasm.exe, классы могут быть созданы как объекты com. Начиная с PHP 8.0.0, .Net framework 4.0 и более поздние версии поддерживаются с помощью директивы php.ini com.dotnet_version.

Обзор классов

class dotnet extends variant {
/* Методы */
public __construct(string $assembly_name, string $datatype_name, int $codepage = CP_ACP)
}

Перегруженные методы

Возвращаемый объект является перегруженным, то есть PHP не видит каких-либо фиксированных методов, как это происходит с обычными классами; вместо этого свойства и доступ к методам передаётся через COM, а оттуда в DOTNET. Другими словами, объект .Net отображается через уровень взаимодействия COM, предоставляемый библиотекой времени исполнения .Net.

Как только вы создали объект dotnet, PHP обрабатывает его идентично любому другому объекту COM; применяются все те же правила.

Примеры dotnet

Пример #1 Пример использования dotnet

<?php
$stack
= new dotnet("mscorlib", "System.Collections.Stack");
$stack->Push(".Net");
$stack->Push("Привет ");
echo
$stack->Pop() . $stack->Pop();
?>

Содержание

add a note add a note

User Contributed Notes 12 notes

up
9
ricardopsj at gmail dot com
10 years ago
Create an Excel Workbook using DOTNET.

<?php

$full_assembly_string
= 'Microsoft.Office.Interop.Excel, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c';
$full_class_name = 'Microsoft.Office.Interop.Excel.ApplicationClass';

$e = new DOTNET($full_assembly_string, $full_class_name);
$wb = $e->workbooks->add();
$Precios = $wb->Worksheets(1);
$Precios->Name = 'Precios';
$Venta = $wb->Worksheets(2);
$Venta->Name = 'Venta';
$Tons = $wb->Worksheets(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 (
$Meses as $Numero => $Mes) {
  
$Precios->Range("A" . ($Numero+1))->Value = $Mes;
}

$wb->SaveAs('c:\temp\Meta.2014.05.xlsx');
$wb->Close();

?>

Go to c:\windows\assembly to know what value to put in $full_assembly_string.

If you don't know the assembly, use http://www.red-gate.com/products/dotnet-development/reflector/ to browse it, use what you learn there to fill $full_class_name.

Enjoy,

Ricardo.
up
7
juan156_elias at gmail dot com
9 years ago
Using COM and DOTNET directly is quite a nightmare. DOTNET only allows you to target .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 get code like this:

$manager = new \NetPhp\Core\NetManager();
$manager->RegisterAssembly('mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089', 'mscorlib');
$manager->RegisterClass('mscorlib', 'System.IO.File', 'File');
$manager->RegisterClass('mscorlib', 'System.IO.FileOptions', 'FileOptions');
$file = $manager->Create('mscorlib', 'File');
$fileoptions = $manager->Create('mscorlib', 'System.IO.FileOptions')->Enum('Encrypted');

$file->Create("C:\\www\\prueba.tres", 2048, $fileoptions);
up
1
Bitterblue
6 years ago
I worked with this the last few days and figured it out.
On stack overflow: https://stackoverflow.com/a/51541801/1442225
up
3
jan dot zahradnik at data3s dot com
10 years ago
PHP searches only GAC for .NET 2.0 runtime, so your DLL has to be targeted 2.0 - 3.5 framework.

Also it recognize only classes, not stucts, so you can't instantiate DateTime for example.
up
1
jcastromail at yahoo dot es
7 years ago
using dotnet with visual studio 2015 (and net framework 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 click in the project -> build events -> post build

"C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6 Tools\gacutil.exe"  /i "$(TargetPath)"

When the project its compiled, it adds to the GAC automatically. Please changes the bin folder according your installation.

3) in tools -> External tools, add the next external tool
Title: Get Qualified Assembly Name
Command: Powershell.exe
Arguments: -command "[System.Reflection.AssemblyName]::GetAssemblyName(\"$(TargetPath)\").FullName"
User Output Windows : checks

4) run tools -> Get qualified Assembly Name and checks the output windows

5) Creates the next class (Class1 may be its already creates)

namespace ClassLibrary2 // <-- changes it.
{
    public class Class1
    {
        public string Ping(string t1,string t2)
        {
            return "pong "+t1+t2;
        }
    }
}

6) in php

$full="ClassLibrary2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=746927f9726d7222"; // its from the output windows
$class = 'ClassLibrary2.Class1'; // its the namespace and the class.

$stack = new DOTNET($full,$class);
$r1="hello";
$r2="world";
echo $stack->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.
up
1
m dot atifmajeed at gmail dot com
9 years ago
How to use donet class for creating object of parameterized constructor

http://php.net/manual/en/class.dotnet.php

private SGF ingerPrintManager m_FPM; //member variable
SGFPMDeviceName device_name = SGFPMDeviceName.DEV_ FDU02 ;
m_FPM = new SGF ingerPrintManager (device_name);
up
0
sandips (yardi)
13 years ago
exercise to try different type of method signature and calling them in php.

VB.net Code
Public Class Class1
    Public Function SayHello(ByVal input As String) As String
        Return "Php input: " & input & "</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 work 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,"
             
."Version=1.0.0.0,"
                         
."Culture=neutral,"
                     
."PublicKeyToken=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;
?>
up
0
Anonymous
14 years ago
As suggested before, you'll likely have to use a full assembly string including the assembly name, the assembly version (not the dll file version), the culture, and the public key token.  Otherwise, you'll get a 'file not found' catchable error.  To quickly find this on your own system to get 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 work with, hover the mouse over it, and the tooltip shows the exact string to use (though processcorArchitecture 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 hierarchy 'System.Windows.Forms.Form'.  Otherwise you'll get 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 blank form from php-cli, which can be used in leu of many Windows GUI PHP extensions out there.  Replace Version with your local version, and PublicKeyToken with your own local key token.

<?php

$full_assembly_string
= 'System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=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 events

 
}
?>
up
0
murat at muratyaman dot co dot uk
14 years ago
First, I hit 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 change 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
up
0
kschroeder at mirageworks dot com
15 years ago
In order to find out what the PublicKeyToken value is, open up Explorer and go to c:\windows\assembly.  In that directory you will see all of the registered assemblies along with their PublicKeyToken value.
up
-1
m holmes at windowlogic dot com dot au
15 years ago
For strongly-named NET assemblies that are registered 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 registered in the GAC, you need to use the full assembly string
e.g. $x = new DOTNET('myAssembly, Version=X.X.X.X, Culture=neutral, PublicKeyToken=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 click the 'sign the assembly' box and choose a key file name.

To register 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 registering dragged files).
up
-5
sam at bitopia dot co dot uk
16 years ago
If you want to load any other assembly apart from mscorlib, you'll need to include it like the following

$x = new DOTNET('The.Assembly.Name, Version=X.X.X.X, Culture=neutral, PublicKeyToken=ZZZZZZZZZZZZ', 'The.Class.Name');

Replace all relevant details.
To Top