Hosting de Calidad
  • Inicio
  • Precios y servicios
  • F.a.q y ayudas
  • Realizar pedido
  • Webs alojadas
  • Quienes somos
  • Foro HyD
  • Contacto

    Zona Dominios

    Entrar
    registro de dominios


    Zona Hosting

    Entrar
    alojamiento web


    5 Métodos de Pago
    Tarjeta de crédito
    Domiciliación
    Transferencia
    Soporte Epagado
    Soporte Paypal

    Liberalización .es

    Ver mas
    dominios .es


  •  
     
     
    Desarrollo en PHP

    Apéndice E_ Desarrollo en PHP

    Añadiendo funciones al PHP3

    Prototipo de Función

    Todas las funciones son como esta:
    void php3_algo(INTERNAL_FUNCTION_PARAMETERS) {
    
    }
    Incluso si su función no lleva argumentos, es así como se le llama_

    Argumentos de Función

    Los argumentos son siempre de tipo pval_ Este tipo contiene una unión que es el tipo actual del argumento_ Así, si su función tiene dos argumentos, deberá hacer algo como lo que sigue al principio de la misma:

    Ejemplo E_1_ Extrayendo argumentos de función

    pval *arg1, *arg2;
    if (ARG_COUNT(ht) != 2 || getParameters(ht,2,&arg1,&arg2)==FAILURE) {
       WRONG_PARAM_COUNT;
    }
    NOTA: Los argumentos pueden pasarse tanto por valor como por referencia_ En ambos casos, necesitará pasar &(pval *) a getParameters_ Si desea comprobar si el enésimo parámetro le ha sido enviado o no por referencia, puede utilizar la función ParameterPassedByReference(ht,n)_ Esta devolverá 1 ó 0, según corresponda_

    Cuando cambie alguno de los parámetros pasados, tanto si son enviados por referencia o por valor, puede volver a comenzar con éste llamando la función pval_destructor sobre el mismo, o, si es una ARRAY a la que quiere añadir algo, puede utilizar funciones similares a las incluídas en internal_functions_h, que manipulan el valor return_value como si fuera de tipo ARRAY_

    Además, si cambia un parámetro a IS_STRING, asegúrese primero de asignar el valor y el tamaño a la cadena creada por estrdup() y sólo entonces cambiar su tipo a IS_STRING_ Si modifica la cadena de un parámetro que ya es IS_STRING o IS_ARRAY, deberá primero aplicarle la función pval_destructor_

    Argumentos de Función Variables

    Una función puede tomar un número variable de argumentos_ Si su función puede tomar tanto 2 como 3 argumentos, utilice el siguiente código:

    Ejemplo E_2_ Argumentos de función variables

    pval *arg1, *arg2, *arg3;
    int arg_count = ARG_COUNT(ht);
    
    if (arg_count < 2 || arg_count > 3 ||
        getParameters(ht,arg_count,&arg1,&arg2,&arg3)==FAILURE) {
        WRONG_PARAM_COUNT;
    }

    Usando los Argumentos de Función

    El tipo de cada argumento se guarda en el campo type del pval_ Este tipo puede ser:

    Tabla E_1_ Tipos Internos de PHP

    IS_STRINGCadena
    IS_DOUBLEComa flotante de doble precisión
    IS_LONGEntero largo
    IS_ARRAYMatriz
    IS_EMPTYNada
    IS_USER_FUNCTION??
    IS_INTERNAL_FUNCTION?? (N_D_: si alguno de estos no se puede pasar a una función, bórrese)
    IS_CLASS??
    IS_OBJECT??

    Si obtiene un argumento de un tipo y desea utilizarlo como si fuera de otro, o si quiere forzar a que un argumento sea de un tipo determinado, 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" pasa a ser 0; si no, vale 1 */
    convert_string_to_number(arg1);  /* Convierte la cadena a LONG o a DOUBLE, dependiendo de su contenido */

    Estas funciones convierten el valor in_situ_ No devuelven nada_

    El argumento real es almacenado en una unión cuyos miembros son:

    • IS_STRING: arg1_>value_str_val

    • IS_LONG: arg1_>value_lval

    • IS_DOUBLE: arg1_>value_dval

    Manejo de Memoria en las Funciones

    La memoria necesitada por una función deberá ser asignada usando emalloc() o estrdup()_ Estas son funciones abstractas de manejo de memoria que son similares a las funciones normales malloc() y strdup()_ La memoria deberá liberarse con efree()_

    Hay dos tipos de memoria en este programa: la memoria que se devuelve al troceador (parser) en una variable, y la memoria que se necesita para almacenamiento temporal de datos en sus funciones_ Cuando asigne una cadena a una variable que se devolverá al troceador deberá asegurarse previamente de asignar la memoria con emalloc() o con estrdup()_ Esta memoria NUNCA debe ser liberada por usted, salvo si más adelante, en la misma función, sobreescribe la asignación original (aunque este hábito de programación no es bueno)_

    Para cada trozo de memoria temporal/permanente que precise en sus funciones/librería deberá utilizar las funciones emalloc(), estrdup(), y efree()_ Estas se comportan EXACTAMENTE como sus funciones equivalentes_ Cualquier cosa que asigne con emalloc() o estrdup() deberá liberarla con efree() en uno u otro momento, salvo que se suponga que deba permanecer activa hasta el final del programa; de otro modo, se producirá una fuga de memoria_ El significado de "estas se comportan exactamente como sus funciones equivalentes" es: si llama a efree() sobre algo que no ha sido asignado previamente con emalloc() o con estrdup(), puede provocar un fallo de segmentación_ Por ello debe tener cuidado y liberar toda la memoria desperdiciada_

    Si compila con "_DDEBUG", el PHP3 mostrará una lista de toda la memoria que fue asignada usando emalloc() y estrdup(), pero que nunca fue liberada con efree(), al terminar de ejecutar el guión especificado_

    Asignando Variables en la Tabla de Símbolos

    Están disponibles una serie de macros que hacen más fácil el asignar una variale en la tabla de símbolos:

    • SET_VAR_STRING(nombre,valor) [1]

    • SET_VAR_DOUBLE(nombre,valor)

    • SET_VAR_LONG(nombre,valor)

    [1]

    Las tablas de símbolos en PHP 3_0 se implementan como tablas hash (con extracto)_ En todo momento, &symbol_table es un puntero a la tabla de símbolos 'principal', mientras que active_symbol_table apunta a la tabla de símbolos activa (pueden ser idénticas, al principio de todo, o diferentes, si se está dentro de una función)_

    Los ejemplos siguientes utilizan 'active_symbol_table'_ Deberá reemplazarla por &symbol_table si desea trabajar específicamente con la tabla de símbolos 'principal'_ También se pueden aplicar las mismas funciones a matrices, como se explica más abajo_

    Ejemplo E_3_ Comprobando si $algo existe en una tabla de símbolos

    if (hash_exists(active_symbol_table,"algo",sizeof("algo"))) { existe___ }
    else { no existe }

    Ejemplo E_4_ Hallando el tamaño de una variable en una tabla de símbolos

    hash_find(active_symbol_table,"algo",sizeof("algo"),&valptr);
    check(valptr_type);
    Las matrices en PHP 3_0 se implementan utilizando las mismas tablas hash que para las tablas de símbolos_ Ello quiere decir que las dos funciones anteriores se pueden usar también para comprobar variables dentro de matrices_

    Si desea definir un nuevo símbolo de matriz en una tabla de símbolos, deberá hacer lo que sigue_

    Primero, deberá comprobar si ya existe usando hash_exists() o hash_find() y abortar la ejecución de forma apropiada_

    Luego inicialice la matriz:

    Ejemplo E_5_ Inicializando una nueva matriz

    pval matriz;
      
    if (array_init(&matriz) == FAILURE) { falló___ };
    hash_update(active_symbol_table,"algo",sizeof("algo"),&matriz,sizeof(pval),NULL);
    Este código declara una nueva matriz, llamada $algo, en la tabla de símbolos activa_ Esta matriz está vacía_

    Ahora se muestra cómo añadirle elementos:

    Ejemplo E_6_ Añadir entradas a una nueva matriz

    pval elemento;
      
    elemento_type = IS_LONG;
    elemento_value_lval = 5;
      
    /* define $algo["bar"] = 5 */
    hash_update(matriz_value_ht,"bar",sizeof("bar"),&elemento,sizeof(pval),NULL); 
    
    /* define $algo[7] = 5 */
    hash_index_update(matriz_value_ht,7,&elemento,sizeof(pval),NULL); 
    
    /* define el siguiente puesto libre en $algo[],
     * $algo[8], como 5 (funciona como en php2)
     */
    hash_next_index_insert(matriz_value_ht,&elemento,sizeof(pval),NULL);
    Si desea modificar un valor que ha insertado en una matriz asociativa, deberá primero extraerlo de ella_ Para evitar esa sobrecarga, puede pasarle un puntero pval ** a la función para insertar en una matriz asociativa, y será actualizada con la dirección pval * del elemento insertado dentro de la matriz_ Si dicho valor es NULL (como en todos los ejemplos anteriores), el parámetro se ignora_

    hash_next_index_insert() usa más o menos la misma lógica que "$algo[] = bar;" en el PHP 2_0_

    Si está preparando una matriz como valor devuelto por una función, puede inicializar la misma como antes, haciendo:

    if (array_init(return_value) == FAILURE) { falló___; }

    ___ y luego añadiéndole valores con las funciones auxiliares:

    add_next_index_long(return_value,val_long);
    add_next_index_double(return_value,val_double);
    add_next_index_string(return_value,estrdup(val_cadena));

    Por supuesto, si la adición no se realiza justo después de inicializar la matriz, probablemente tenga que buscarla antes:
    pval *matriz;
      
    if (hash_find(active_symbol_table,"algo",sizeof("algo"),(void **)&matriz)==FAILURE) { no se hayó___ }
    else { usar matriz_>value_ht___ }

    Nótese que hash_find recibe un puntero a un puntero a pval, y no un puntero a pval_

    Casi cualquier función de matrices asociativas devuelve SUCCESS o FAILURE (excepto por hash_exists(), que devuelve un valor lógico de certeza)_

    Devolviendo valores simples

    Están disponibles varias macros para facilitar la devolución de valores de una función_

    Todas las macros RETURN_* fijan el valor y retornan de la función:

    • RETURN

    • RETURN_FALSE

    • RETURN_TRUE

    • RETURN_LONG(l)

    • RETURN_STRING(s,dup) Si dup es TRUE, duplica la cadena

    • RETURN_STRINGL(s,l,dup) Devuelve la cadena (s) especificando el largo (l)_

    • RETURN_DOUBLE(d)

    Las macros RETVAL_* fijan el valor, pero no retornan_

    • RETVAL_FALSE

    • RETVAL_TRUE

    • RETVAL_LONG(l)

    • RETVAL_STRING(s,dup) Si dup es TRUE, duplica la cadena

    • RETVAL_STRINGL(s,l,dup) Devuelve la cadena (s) especificando el largo (l)_

    • RETVAL_DOUBLE(d)

    Las macros anteriores harán un estrdup() del argumento 's', de modo que puede liberar con seguridad el argumento después de llamar a la macro, o, alternativamente, utilizar memoria asignada estáticamente_

    Si su función devuelve respuestas lógicas de éxito/error, use siempre RETURN_TRUE y RETURN_FALSE respectivamente_

    Devolviendo valores complejos

    Su función también puede devolver un tipo de datos complejo, tal como un objeto o una matriz_

    Devolviendo un objeto:

    1. Llame a object_init(return_value)_

    2. Rellénela con valores_ Las funciones disponibles para ello son listadas más abajo_

    3. Posilemente registre funciones para este objeto_ Para obtener valores del objeto, la función deberá de obtener "this" desde la active_symbol_table_ Su tipo deberá ser IS_OBJECT, y básicamente se trata de una matriz asociativa estándar (es decir, que podrá usar funciones de matriz asociativa sobre _value_ht)_ El registro en sí de la función se puede hacer utilizando:
      add_method( return_value, nombre_func, puntero_func );

    Las funciones utilizadas para rellenar un objeto son:

    • add_property_long( return_value, nombre_propiedad, l ) _ Añade una propiedad llamada 'nombre_propiedad', de tipo long, y con valor 'l'

    • add_property_double( return_value, nombre_propiedad, d ) _ Igual, pero añadiendo un double

    • add_property_string( return_value, nombre_propiedad, cad ) _ Igual, pero añadiendo una cadena

    • add_property_stringl( return_value, nombre_propiedad, cad, l ) _ Igual, pero añadiendo una cadena de longitud 'l'

    Devolviendo una matriz:

    1. Llame a array_init(return_value)_

    2. Rellénela con valores_ Las funciones disponibles para ello son listadas más abajo_

    Las funciones utilizadas para rellanar una matriz son:

    • add_assoc_long(return_value,clave,l) _ añade un elemento asociativo con clave 'clave' y valor long 'l'

    • add_assoc_double(return_value,clave,d)

    • add_assoc_string(return_value,clave,cad,duplicar)

    • add_assoc_stringl(return_value,clave,cad,largo,duplicar) _ especifica el largo de la cadena

    • add_index_long(return_value,indice,l) _ añade un elemento en la posición 'indice' con valor long 'l'

    • add_index_double(return_value,indice,d)

    • add_index_string(return_value,indice,cad)

    • add_index_stringl(return_value,indice,cad,largo) _ especifica el largo de la cadena

    • add_next_index_long(return_value,l) _ añade un elemento a la matriz en la próxima posición libre con valor long 'l'

    • add_next_index_double(return_value,d)

    • add_next_index_string(return_value,cad)

    • add_next_index_stringl(return_value,cad,largo) _ especifica el largo de la cadena

    Usando la lista de recursos

    El PHP 3_0 tiene una forma estandarizada de tratar con distintos tipos de recursos_ Esto sustituye a las listas enlazadas locales del PHP 2_0_

    Funciones disponibles:

    • php3_list_insert(ptr, tipo) _ devuelve el 'id' del recurso recién insertado

    • php3_list_delete(id) _ borra el recurso con el id especificado

    • php3_list_find(id,*tipo) _ devuelve el puntero al recurso con el id especificado, y actualiza 'tipo' al tipo del mismo

    Estas funciones se utilizan típicamente para controladores SQL, pero pueden utilizarse para cualquier otra cosa, como, por ejemplo, para mantener descriptores de archivo_

    El código típico de un lista sería como este:

    Ejemplo E_7_ Añadiendo un nuevo recurso

    RESOURCE *recurso;
    
    /* ___asignar memoria para el recurso y adquirirlo___ */
    /* añadir un recurso a la lista */
    return_value_>value_lval = php3_list_insert((void *) recurso, LE_RESOURCE_TYPE);
    return_value_>type = IS_LONG;

    Ejemplo E_8_ Utilizando 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 recurso número %d tiene el tipo equivocado",id_recurso_>value_lval);
    	RETURN_FALSE;
    }
    /* ___usar recurso___ */

    Ejemplo E_9_ Borrando un recurso

    pval *id_recurso;
    RESOURCE *recurso;
    int tipo;
    
    convert_to_long(id_recurso);
    php3_list_delete(id_recurso_>value_lval);
    Los tipos de recursos deben registrarse en php3_list_h, en la enumeración list_entry_type_ Además, hay que añadir código de desconexión para cada tipo de recurso definido en la función list_entry_destructor() de list_c (incluso si no hay nada que hacer para la desconexión, deberá añadir un caso vacío)_

    Utilizando la tabla de recursos persistentes

    El PHP 3_0 tiene una forma estándar de almacenar recursos persistentes (es decir, recursos que se mantienen entre accesos)_ El primer módulo que utilizó esta característica fue el MySQL y tras él fue el mSQL, así que uno puede hacerse una buena idea de cómo utilizar un recurso persistente leyendo mysql_c_ Las funciones a revisar son:

    php3_mysql_do_connect
    php3_mysql_connect()
    php3_mysql_pconnect()

    La idea general de los módulos persistentes es:

    1. Codifique todos sus módulos para que funcionen con la lista regulares de recursos mencionadas en la sección (9)_

    2. Codifique funciones extra de conexión que comprueben si el recurso ya está en la lista de recursos persistentes_ Si ya está, regístrelo en la lista regular como un puntero a la lista de recursos persistentes (debido a 1_, el resto del código deberá funcionar de inmediato)_ Si no está en la lista, créelo, añádalo a la lista de recursos persistentes Y añada un puntero al mismo desde la lista regular de recursos_ Así todo el código funcionará porque está en la lista regular, pero en la siguiente conexión el recurso ya estará en la lista persistente y podrá ser usado sin re_crearlo_ Deberá registrar estos recursos con un tipo diferente (por ejemplo, LE_MYSQL_LINK para el enlace no persistente y LE_MYSQL_PLINK para un enlace persistente)_

    Si se leyera mysql_c, notaría que, salvo por que hay una función de conexión más compleja, no hay que cambiar nada más del resto del módulo_

    Existe exactamente la misma interfaz para la lista de recursos regular y para la lista de recursos persistente, pero cambiando únicamente 'lista' por 'listap':

    • php3_plist_insert(ptr, tipo) _ devuelve el 'id' del recurso recién insertado

    • php3_plist_delete(id)_ borra el recurso con el id especificado

    • php3_plist_find(id,*tipo) _ devuelve el puntero al recurso con el id especificado, y actualiza 'tipo' al tipo del mismo

    Sin embargo, es más que probable que estas funciones se muestren inútiles cuando intente implementar un módulo persistente_ Típicamente usted querrá usar el hecho de que la tabla de recursos persistentes es en realidad una matriz asociativa_ Por ejemplo, en los módulos MySQL/mSQL, cuando hay una llamada a pconnect() (conexión persistente), la función combina en una cadena el servidor/usuario/clave que se pasaron a la función y codifica el enlace SQL con esta cadena como clave_ La siguiente vez que alguien llame a pconnect() con el mismo servidor/usuario/clave, se generará la misma clave, y la función hayará el enlace SQL en la lista persistente_

    Hasta que se documente mejor, deberá mirar en mysql_c o en msql_c para ver como utilizar las capacidades de matriz asociativa de la listap_

    Una cosa importante: a los recursos que van a parar a la lista de recursos persistentes *NO* se les debe asignar memoria usando el gestor de memoria del PHP, es decir, que NO deben ser creados utilizando emalloc() o estrdup(), etc_ En este caso se debe usar las funciones habituales malloc(), strdup(), etc_ La razón para esto es simple: al final de la petición (final del acceso), se borran todos los trozos de memoria asignados con el gestor de memoria del PHP_ Como la lista persistente se supone que no se debe borrar al final de una petición, no se debe utilizar el gestor de memoria del PHP para asignar memoria a los recursos de la misma_

    Cuando registre un recuros que vaya a estar en la lista persistente, deberá añadir destructores tanto a la lista persistente como a la no persistente_ El destructor de la lista no persistente no deberá hacer nada_ El de la lista persistente deberá liberar adecuadamente los recursos obtenidos por dicho tipo (por ejemplo, memoria, enlaces SQL, etc_)_ Tal y como pasa para los recursos no persistentes, DEBERÁ añadir destructores para cada recurso aunque no sean necesarios y estén vacíos_ Recuerde que como no se pueden usar emalloc() y similares en conjunción con la lista persistente, tampoco podrá utilizar efree() aquí_

    Añadiendo directivas de configuración en tiempo de ejecución

    Muchas de las características del PHP3 pueden ser configuradas en tiempo de ejecución_ Estas directivas de configuración pueden aparecer tanto en el fichero php3_ini o, en el caso de la versión de módulo del Apache, en los archivos _conf del propio Apache_ La ventaja de tenerlos en los archivos _conf del Apache es que se puden configurar directorio por directorio_ Esto quiere decir que cada uno puede tener un cierto safemodeexecdir, por ejemplo, mientras otro directorio puede tener otro_ Esta granularidad en la configuración es especialmente útil cuando un servidor soporta múltiples servidores virtuales_

    Los pasos necesarios para añadir una nueva directiva:

    1. Añada la directiva a la estructura php3_ini_structure en mod_php3_h_

    2. En main_c, edite la función php3_module_startup y añada la llamada a cfg_get_string() o a cfg_get_long() según se requiera_

    3. Añada la directiva, las restricciones y un comentario a la estructura php3_commands en mod_php3_c_ Cuidado con la parte de restricciones_ Las de tipo RSRC_CONF sólo puede aparecer en los archivos _conf del Apache_ Las directivas de tipo OR_OPTIONS pueden aparecer en cualquier parte, incluso en los habituales archivos _htaccess_

    4. Añada el elemento apropiado para su directiva, bien en php3take1handler(), bien en php3flaghandler()_

    5. Necesita añadir su nueva directiva a la sección de configuración de la función _php3_info() en functions/info_c_

    6. Y finalmente, por supuesto, deberá utilizar su nueva directiva en algún sitio_ Estará accesible como php3_ini_directiva_

    Notas

    [1]

    Tenga cuidado aquí_ El valor a usar se debe asignar dinámicamente y de forma manual, pues el código de manejo de memoria intentará liberar este puntero más adelante_ Nunca pase memoria asignada de forma estática a SET_VAR_STRING_

     
       



    registro de dominios | alojamiento web | hosting por publicidad

       

     

    Manual de linux Manual de apache Manual de php Manual de mysql Manual de SQL Manual del Plesk Como funciona Paypal Manual de html