2012-04-18 9 views
8

Soy bastante novato en PHP y hoy descubrí DOTNET clase.
Así que estudiaron manual, navegado por la web para encontrar algún ejemplo y finalmente escribió mi aplicación de prueba:PHP DOTNET hell

  1. Creado un nuevo archivo DLL usando Framework 4.0 Client Profile
  2. Firmado el ensamblado con un nombre fuerte clave
  3. Asamblea marcado como COM-Visible

Este es el código de prueba que escribí

using System; 

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

Compilé el ensamblaje y luego me registré en GAC (gacutil /if fullpath\CSharpCOM.dll).
Si uso gacutil /l CSharpCOM veo

La caché di ensamblaje globale montaje gli Contiene seguenti:
csharpcom, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = beb607ae770f5750, processorArchitecture = MSIL

Numero di elementi = 1

Así que todo parece estar bien.
Luego escribió este php básica:

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

Cualquiera que sea lo intento, carga de la página alojada en Apache (http://localhost/test01/dotnet.php) siempre me dan

excepción capturada: No se pudo crear una instancia de objeto de .NET [CreateInstance] [ 0x80070002] Imposibile trovare il file specificato.
traducción podría ser: no se puede encontrar el archivo especificado

Sólo otra cosa: el uso de algún ejemplo (a uno muy básico here) leí que mi montaje (al ser registrados) se debe encontrar en %windir%\assembly, pero estoy solo puede encontrarlo en %windi%\Microsoft.NET\assembly\GAC_MSIL\CSharpCOM\v4.0_1.0.0.0__beb607ae770f5750: ¿es correcto? ¿Por qué no lo tengo en el primer directorio?

Más: si creo otro proyecto de framework y trato de agregar una referencia .NET no puedo encontrar mi ensamblado: ¿está relacionado con el hecho de que no puedo cargar este ensamblado desde PHP?

Última nota: Lo probé en Windows XP Professional SP3 de 32 bits y en Windows Siete empresas de 64 bits

ACTUALIZACIÓN:
Esto funciona:

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

pero éste no lo hace:

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

Es posible que PHP solo pueda cargar framework 2.0 assembli es?

+1

Control negativo: ¿Se puede cargar las clases de un conjunto existente, por ejemplo mscorlib? Parece que el problema aquí no es PHP, sino que su ensamblaje no está registrado correctamente. –

+0

sí, puedo usar '$ stack = new DOTNET (" mscorlib "," System.Collections.Stack ");' – Marco

+0

OK, pregunta de seguimiento: puede cargar un ensamblaje existente y firmado, proporcionando su nombre completo en PHP (incluida la clave pública)? –

Respuesta

6

Según este bug report, la clase DOTNET no está cargando .NET 4.0 DLLs. Si no está utilizando ninguna de las nuevas bibliotecas en .NET 4.0, puede orientarlo a .NET 3.5 o inferior abriendo las propiedades del proyecto y en la pestaña "Aplicación" cambiar el "Marco de destino" a ".NET Framework 3.5 Client Perfil "

Ahora, cuando instale su archivo DLL en el GAC, se instalará en CLR 2.0 GAC y se podrá cargar utilizando la clase DOTNET en PHP.

+0

Muchas gracias: compilar usando framework 3.5 resolvió mi problema !! Gracias :) – Marco

5

hay una biblioteca por ahí llamado NetPhp (https://github.com/david-garcia-garcia/netphp) que le permitirá:

  • utilizar todos los binarios .Net (COM incluso sin visibilidad) y cualquier versión de .NET Framework incluyendo CLR4
  • volcar un modelo de clases PHP
  • iterar sobre colecciones .Net directamente desde PHP PHP generación de modelos de clase, utilizar clases PHP como si en .Net propagación automática de errores en .Net excepciones nativas de PHP que puede ser manejada adecuadamente
  • Acces enumeraciones nativas y métodos estáticos
  • constructores Uso de clase con parámetros
  • depuración .Net y código PHP al mismo tiempo, como si se tratara de una sola aplicación.

Hay un proyecto con ejemplos de código aquí:

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

Esto es lo que un pedazo de código con NetPhp parece:

$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; 
Cuestiones relacionadas