Esta sección se encuentra bastante desactualizada y demuestra
el modo de extender PHP 3. Si está interesado en PHP 4, por
favor lea la sección sobre la interfaz
de programación Zend. Asà mismo, usted
querrá leer varios archivos encontrados en el código
fuente de PHP, archivos como
README.SELF-CONTAINED-EXTENSIONS y
README.EXT_SKEL.
Los argumentos son siempre de tipo pval. Este tipo posee una
unión que contiene el tipo real del argumento. AsÃ
que, si su función recibe dos argumentos, usted
harÃa algo como lo siguiente al comienzo de su
función:
Ejemplo F-1. Recuperación de argumentos de
función
Si recibe un argumento de un tipo y quisiera usarlo como otro, o
si tan sólo desea obligar al argumento a que sea de un
cierto tipo, puede usar una de las siguientes funciones de
conversión:
convert_to_long(arg1);
convert_to_double(arg1);
convert_to_string(arg1);
convert_to_boolean_long(arg1); /* Si la cadena es "" o "0" se convierte a 0, 1 de lo contrario */
convert_string_to_number(arg1); /* Convierte una cadena a un LONG o DOUBLE, dependiendo de la cadena */
Estas funciones todas realizan conversión en-el-lugar. No
devuelven nada.
El argumento como tal es almacenado en una unión; los
miembros son:
Cualquier segmento de memoria necesitado por una función
debe ser reservado ya sea con emalloc() o estrdup(). Estas son
funciones que abstraen la gestión de memoria y lucen y
huelen como las funciones normales malloc() y strdup(). La memoria
debe ser liberada con efree().
Para cualquier segmento de memoria temporal/permanente que
necesite en sus funciones/bibliotecas, usted deberÃa usar
las tres funciones emalloc(), estrdup(), y efree(). Éstas
se comportan EXACTAMENTE como sus contrapartes. Cualquier cosa que
reserve con emalloc() o estrdup() debe liberarla con efree() en
alguno u otro punto, a menos que espere que permanezca hasta el
final del programa; de otro modo, habrá una fuga de
memoria. El significado de "las funciones se comportan exactamente
como sus contrapartes" es: si usted usa efree() sobre algo que no
fue reservado con emalloc() ni estrdup(), puede que reciba un
fallo de segmentación. De modo que, por favor, tenga
cuidado y libere toda su memoria desperdiciada.
Si compila con "-DDEBUG", PHP imprimirá una lista de toda
la memoria que fue reservada usando emalloc() y estrdup() y nunca
liberada con efree() una vez termina la ejecución el script
especificado.
Un número de macros se encuentra a su disposición
para facilitar la definición de una variable en la tabla de
sÃmbolos:
SET_VAR_STRING(nombre,valor)
SET_VAR_DOUBLE(nombre,valor)
SET_VAR_LONG(nombre,valor)
Aviso
Tenga cuidado con SET_VAR_STRING. La parte del valor debe ser
reservada manualmente con malloc, ya que el código de
gestión de memoria intentará liberar este apuntador
más adelante. No pase memoria reservada
estáticamente a un llamado a SET_VAR_STRING.
Los siguientes ejemplos usan 'active_symbol_table'. Debe
reemplazar este valor con &symbol_table si desea trabajar
especÃficamente con la tabla de sÃmbolos
'principal'. Asimismo, las mismas funciones pueden ser aplicadas
sobre matrices, como se explica más adelante.
Ejemplo F-3. Chequear si $foo existe en la tabla de
sÃmbolos
if (hash_exists(active_symbol_table,"foo",sizeof("foo"))) { existe... }
else { no existe }
Ejemplo F-4. Encontrar el tamaño de una variable en una tabla de
sÃmbolos
Por supuesto, si la adición no es realizada correctamente
luego de la inicialización de la matriz, probablemente
tenga que verificar la existencia de la matriz primero:
pval *arr;
if (hash_find(active_symbol_table,"foo",sizeof("foo"),(void **)&arr)==FAILURE) { no se pudo encontrar... }
else { use arr->value.ht... }
Note que hash_find recibe un apuntador a un apuntador pval, y no
un apuntador pval.
Prácticamente toda función de matriz asociativa
devuelve SUCCESS o FAILURE (excepto por hash_exists(), que
devuelve un valor booleano de verdad).
Posiblemente, registre funciones para este objeto. Para obtener
valores del objeto, la función tendrÃa que
recuperar "this" desde active_symbol_table. Su tipo debe ser
IS_OBJECT, y es básicamente una tabla asociativa regular
(esto quiere decir, puede usar las funciones de matrices
asociativas regulares sobre .value.ht). El registro como tal de
la función puede realizarse usando:
php3_list_delete(id) - eliminar el recurso con el id especificado
php3_list_find(id,*tipo) - devuelve el apuntador del recurso
con el id especificado, actualiza 'tipo' al tipo del recurso
TÃpicamente, estas funciones son usadas para gestores de
SQL, pero pueden ser usadas para cualquier otra cosa; por ejemplo,
mantener descriptores de archivo.
Un listado de código tÃpico lucirÃa de la
siguiente forma:
Ejemplo F-7. Adición de un nuevo recurso
RESOURCE *recurso;
/* ...reservar memoria para el recurso y adquirirlo... */
/* agregar un nuevo recurso a la lista */
valor_retorno->value.lval = php3_list_insert((void *) recurso, LE_RESOURCE_TYPE);
valor_retorno->type = IS_LONG;
Ejemplo F-8. Uso de un recurso existente
pval *id_recurso;
RESOURCE *recurso;
int tipo;
convert_to_long(id_recurso);
recurso = php3_list_find(id_recurso->value.lval, &tipo);
if (tipo != LE_RESOURCE_TYPE) {
php3_error(E_WARNING,"el indice de recurso %d tiene el tipo equivocado",id_recurso->value.lval);
RETURN_FALSE;
}
/* ...usar el recurso... */
Ejemplo F-9. Eliminar un recurso existente
pval *id_recurso;
RESOURCE *recurso;
int tipo;
convert_to_long(id_recurso);
php3_list_delete(id_recurso->value.lval);
Los tipos de recurso deberÃan estar registrados en
php3_list.h, en enum list_entry_type. Adicionalmente, debe
procurarse la implementación de código de
finalización para cada nuevo tipo de recurso definido, en
list_entry_destructor() ubicado en list.c (incluso si no tiene
nada que hacer en la finalización, debe agregar un caso
vacÃo).
PHP posee una forma estándar de almacenar recursos
persistentes (es decir, recursos que son conservados entre
peticiones). El primer módulo en usar esta
caracterÃstica fue el módulo MySQL, y mSQL a
continuación, de modo que puede obtener una idea general de
cómo debe ser usado un recurso persistente leyendo
mysql.c. Las funciones que debe consultar son:
php3_mysql_do_connect
php3_mysql_connect()
php3_mysql_pconnect()
La idea general de los módulos de persistencia es la
siguiente:
Escriba todo el código de su módulo para que
trabaje con la lista de recursos normales mencionada en la
sección (9).
Hasta que sea documentado más a fondo, deberÃa
echarle un vistazo a mysql.c o msql.c para ver cómo pueden
usarse las capacidades de tabla asociativa de una lista plist.
Una cosa importante a notar: los recursos que van a la lista de
recursos persistentes *NO* debe ser reservada con el gestor de
memoria de PHP, es decir, NO debe ser creada con emalloc(),
estrdup(), etc. En su lugar, deben ser usadas las funciones
normales malloc(), strdup(), etc. La razón de esto es
simple - al final de la petición (final de cada visita),
cada trozo de memoria que fue ubicado usando el gestor de memoria
de PHP es eliminado. Ya que la lista persistente no se supone que
deba ser eliminada el final de cada petición, no debe
utilizarse el gestor de memoria de PHP para reservar recursos que
vayan a la lista.
Muchas de las caracterÃsticas de PHP pueden ser
configuradas en tiempo de ejecución. Estas directivas de
configuración pueden aparecer en el archivo php3.ini
designado, o, en el caso de la versión módulo de
Apache, en los archivos .conf de Apache. La ventaja de tenerlas en
los archivos .conf de Apache es que pueden ser configuradas por
cada directorio. Esto quiere decir que un directorio puede tener
cierto valor para safemodeexecdir, por ejemplo, mientras que otro
directorio puede tener otro. Esta especificidad en la
configuración es especialmente útil cuando un
servidor soporta múltiples hosts virtuales.
Los pasos requeridos para agregar una nueva directiva:
Agregar la directiva a la estructura php3_ini_structure en
mod_php3.h.
En main.c, editar la función php3_module_startup y
agregar la llamada apropiada a cfg_get_string() o
cfg_get_long().
Agregar la directiva, restricciones y un comentario a la
estructura php3_commands en mod_php3.c. FÃjese en la
parte de restricciones. RSRC_CONF son directivas que pueden
estar presentes sólo en las archivos .conf de Apache,
Cualquier directiva OR_OPTIONS puede estar presente en
cualquier parte, incluyendo archivos .htaccess normales.
Agregue la entrada apropiada para su directiva en
php3take1handler() o en php3flaghandler().
En la sección de configuración de la
función _php3_info() en functions/info.c necesita
agregar su nueva directiva.
Y, por último, debe por supuesto usar su directiva en
alguna parte. Esta será asequible como
php3_ini.directiva.
Atención técnica y comercial: (54)-11-5031-1111 las 24 hs. los 365 días del año. ToWebs, (c) 2008
Virtucom Networks S.A Av. Belgrano 1586, piso 10 (C1093AAQ) Cap. Fed. Bs. As, Argentina.