2012-04-18 13 views
8

Jestem dość początkujący w PHP i dziś odkryłem DOTNET klasy.
więc uczyłem obsługi, nadmiar w internecie, aby znaleźć jakiś przykład i wreszcie napisałem aplikację testową:PHP DOTNET piekło

  1. Utworzony DLL przy użyciu Framework 4.0 Client Profile
  2. Signed zespół z silną nazwę klucza
  3. Oznaczono zespół COM-Visible

jest to kod testu napisałem

using System; 

namespace CSharpCOM 
{ 
    public class CSharpCOMClass 
    { 
     public string Base64(string s) 
     { 
      return Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(s)); 
     } 
    } 
} 

Kompilowałem zespół, a następnie zarejestrowałem w GAC (gacutil /if fullpath\CSharpCOM.dll).
Jeśli używam gacutil /l CSharpCOM widzę

La cache di montaż globale contiene montaż gli seguenti:
csharpcom, Version = 1.0.0.0, Culture = neutral, TokenKluczaPublicznego = beb607ae770f5750, processorArchitecture = MSIL

Numero di elementi = 1

Wszystko wydaje się więc w porządku.
Potem napisał tę podstawową 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"; 
} 
?> 

Cokolwiek staram, Ładowanie strony hostowane w Apache (http://localhost/test01/dotnet.php) zawsze dotrzesz

Caught wyjątku: Nie można utworzyć wystąpienia obiektu .NET [CreateInstance] [ 0x80070002] Impossibile trovare il fileatonato.
Tłumaczenie może być: nie można odnaleźć określonego pliku

Kolejna sprawa: korzystając jakiś przykład (bardzo prosty jeden here) Czytałem, że mój zespół (po zarejestrowaniu) powinny znajdować się na %windir%\assembly, ale jestem jest tylko w stanie go znaleźć w %windi%\Microsoft.NET\assembly\GAC_MSIL\CSharpCOM\v4.0_1.0.0.0__beb607ae770f5750: czy to prawda? Dlaczego nie mam go w pierwszym katalogu?

Więcej: jeśli utworzę inny projekt ramowy i spróbuję dodać odniesienie do .NET, nie mogę znaleźć mojego zestawu: czy jest to związane z tym, że nie mogę załadować tego zestawu z PHP?

Ostatnia uwaga: Próbowałem go na Windows XP Professional SP3 32bit i Windows Seven Enterprise 64bit

UPDATE:
to działa:

$form = new DOTNET('System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089', 'System.Windows.Forms.Form'); 

ale ten nie:

$form = new DOTNET('System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089', 'System.Windows.Forms.Form');` 

Czy to możliwe, że PHP może załadować tylko moduł 2.0? es?

+1

kontrola negatywna: można załadować klas z istniejący montaż, np mscorlib? Wygląda na to, że problemem nie jest PHP, ale raczej to, że twój zespół nie został poprawnie zarejestrowany. –

+0

tak, mogę użyć '$ stack = new DOTNET (" mscorlib "," System.Collections.Stack ");' – Marco

+0

OK, pytanie uzupełniające: czy można wczytać istniejący, podpisany zespół, podając jego pełną nazwę w PHP (w tym klucz publiczny)? –

Odpowiedz

6

Zgodnie z tym bug report klasa DOTNET nie ładuje bibliotek DLL .NET 4.0. Jeśli nie używasz żadnej z nowych bibliotek w .NET 4.0, możesz skierować ją do .NET 3.5 lub niższej, otwierając właściwości projektu, a na karcie "Aplikacja" zmień "Ramę docelową" na "Klient .NET Framework 3.5" Profil "

Teraz po zainstalowaniu biblioteki DLL w GAC zostanie ona zainstalowana w CLR 2.0 GAC i powinna być ładowana przy użyciu klasy DOTNET w PHP.

+0

Wielkie dzięki: kompilacja za pomocą framework 3.5 rozwiązała mój problem !! Dzięki :) – Marco

5

Jest biblioteka tam nazywa NetPhp (https://github.com/david-garcia-garcia/netphp), który pozwoli Ci:

  • używać żadnych binarne NET (nawet bez COM widoczność) i dowolnej wersji .NET Framework tym CLR4
  • Zrzuć model klasy PHP
  • Iteracja kolekcji .Net bezpośrednio z PHP Generowanie modelu klasy PHP, użycie klas PHP tak, jakby to było gdzie .Net Automatyczne propagowanie błędów .Net do natywnych wyjątków PHP, które mogą być poprawnie obsługiwane
  • Acces rodzime teksty stałe i metody statyczne
  • użyć klasy konstruktorzy z parametrami
  • Debug .NET oraz kodu PHP w tym samym czasie, tak jakby to była pojedyncza aplikacja.

Jest projekt z próbkami kod tutaj:

https://github.com/david-garcia-garcia/netphp-sample

To właśnie kawałek kodu z NetPhp wygląda następująco:

$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; 
Powiązane problemy