Ver Mensaje Individual
  #1 (permalink)  
Antiguo 22/03/2006, 11:02
gnfrs
 
Fecha de Ingreso: abril-2004
Ubicación: Rosario, Argentina
Mensajes: 124
Antigüedad: 20 años
Puntos: 11
Extensiones de PHP

Esto lo posteo dentro de POO porque es un tema bastante avanzado a mi parecer...

Logré compilar una extensión para PHP.
Ví cómo hacerlo en muchos lugares y siempre tenía errores, pero esta vez logré compilarla satisfactoriamente y probarla.

Voy a explicar paso por paso cómo lo hice, para que sea fácil para todos un buen comienzo.

Aquí hay material que saqué de otros sitios como PHP.NET, zend.com y devnewz.com.

Yo tengo instalado Apache 1.3 y PHP 4.4.1 como servicios en la plataforma NT.

Primero que nada voy a mencionar las herramientas que utilizé para hacer esto:
* Microsoft Visual C++ 6.0
* Código fuente de PHP descargado de http://ar.php.net/get/php-4.x.x.tar.gz/from/a/mirror

Los principales pasos los obtuve de:
http://www.devnewz.com/2002/0909.html y el código en C de:
http://www.zend.com/php/internals/ex...6&open=1#notes

Aunque hice algunas modificaciones al código para que funcione correctamente.

==============================

1. Archivos necesarios.
1.1 Descargar el código fuente de PHP (deben descargar el código fuente que corresponda a la versión de PHP para la que quieran hacer la extensión), en mi caso la versión 4.4.1.

1.2 Descomprimir el código fuente en una carpeta, por ejemplo C:\PHP\Source\.

2. Configuración inicial.
2.1 Abrir MS VC++ 6.0 y en el menú File seleccionar New.
2.2 En el asistente para un nuevo proyecto seleccionar el tipo de proyecto Win32 Dynamic-Link Library.
2.3 En la casilla de nombre de proyecto escriban el nombre de la librería que van a crear, por ejemplo "hello".
2.4 En la casilla de ubicación del proyecto escriban el path hacia la carpeta "ext" dentro del directorio en donde descomprimieron el código fuente de PHP.
2.5 La opción Win32 que está debajo de "Plataforas" yo la dejé tildada, no sé en qué afectará esto a la extensión creada.
2.6 Una vez establecido todo esto hay que dar click en Ok, en la próxima ventana del asistente hay que dajar tildado "An empty DLL proyect" y dar click en Finish, aparecerá otra ventana de confirmación, hagan click en Ok.

3. Configuración de compilación.
3.1 Hagan click en Proyect -> Configurations y en la ventana que se abre seleccionen "Config for" Win32 Release, después seleccionen la solapa "C/C++" y la categoría "General". Agreguen las definiciones del preprocesador siguientes:
ZEND_DEBUG=0,COMPILE_DL_HELLO,ZTS=1,ZEND_WIN32,PHP _WIN32.
Pueden ver una imagen aquí: http://images.ientrymail.com/phpc_2.gif.
3.2 Seleccionen la categoría "Code Generation" y cambien la propiedad "run-time Library" a "Multithreaded DLL".
3.3 En la categoría "Preprocessor" agreguen la siguiente cadena al campo "Additional include directories":
..\..,..\..\main,..\..\Zend,..\..\TSRM,..\..\win32.
Estos directorios son relativos a la ubicación del proyecto con respecto a la ubicación del código fuente de PHP, por lo que si cambian alguna de estas ubicaciones van a necesitar modificar esta directiva.
3.4 En la solapa Link y en la categoría General cambien el nombre del archivo DLL de salida a php_hello.dll, esto puede ser omitido pero debido a que es una norma que las extensiones de PHP en Windows tengan el prefijo php_, deberíamos hacerlo así.
3.5 En el campo "Object/library modules" agregen php4ts.dll.
3.6 En la categoría "Input" agreguen a "Additional library path" la cadena siguiente: Release
3.7 Den click en Ok para confirmar los cambios.
3.8 Dentro de "Build" hagan click en "Set active configuration", seleccionen Win32 Release y hagan click en Ok.
3.9 Debido a que PHP fue contruido en el lenguaje C, sería un error escribir código en C++ para esta extensión, por lo que es conveniente agregar la directiva /Tc en el campo "Proyect Options" dentro de la categoría "Preprocessor" en la solapa "C/C++" en la misma ventana de configuración que se mencionó anteriormente. Asegurense de que esté activado el campo "Win32 Release" en "Config for" de la misma ventana. Se puede ver el ejemplo aquí: http://images.ientrymail.com/phpc_4.gif.


Si llegaron bien hasta aquí es porque tienen todo bien configurado para empezar a escribir código en C y crear una extensión para PHP.


4. Escribiendo el código.
4.1 Creen el archivo de cabecera hello.h, para ello hagan click en "File", "New" y en el asistente seleccionen "C/C++ Header File", en el campo "File Name" escriban "hello.h" por ejemplo. A continueación ingresen el siguiente código y graben todo el proyecto.

Código:
#ifndef PHP_HELLO_H
#define PHP_HELLO_H 1

#define PHP_HELLO_WORLD_VERSION "1.0"
#define PHP_HELLO_WORLD_EXTNAME "hello"

PHP_FUNCTION(hello_world);

extern zend_module_entry hello_module_entry;
#define phpext_hello_ptr &hello_module_entry

#endif
4.2 Hagan exactamente el mismo paso que con el archivo anterior, pero esta vez dejen seleccionada la opción "C++ Source File", en el campo "File Name" escriban "hello.c" por ejemplo. A continueación ingresen el siguiente código y graben todo nuevamente.

Código:
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "php.h"
#include "hello.h"

static function_entry hello_functions[] = {
    PHP_FE(hello_world, NULL)
    {NULL, NULL, NULL}
};

zend_module_entry hello_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
    STANDARD_MODULE_HEADER,
#endif
    PHP_HELLO_WORLD_EXTNAME,
    hello_functions,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
#if ZEND_MODULE_API_NO >= 20010901
    PHP_HELLO_WORLD_VERSION,
#endif
    STANDARD_MODULE_PROPERTIES
};

#ifdef COMPILE_DL_HELLO
ZEND_GET_MODULE(hello)
#endif

PHP_FUNCTION(hello_world)
{
    RETURN_STRING("Hello World", 1);
}
5.3 Copien el archivo php4ts.lib que se encuentra en el ROOT de PHP hacia la carpeta del proyecto ("ext/hello/"), creo que este archivo debería ir en otro lugar pero sólo aquí andubo en mi caso (supongo que se debería modificar la lína de configuración del compilador que carga este archivo).

=========


Listo, eso es todo sólo queda compilar el proyecto y poner el archvo DLL que quedó en la carpeta Release dentro de la carpeta de las extensiones de PHP, después hay que modificar PHP.INI (si no poseen permisos para ejecutar la función dl) para que cargue la extensión y reiniciar el servicio de Apache.

El código siguiente puede comprobar que la librería se cargó satisfactoriamente:

Código:
<?
echo hello_world();
?>
Espero que les sirva.

Saludos.

Última edición por gnfrs; 22/03/2006 a las 11:57