lunes, 18 de julio de 2011

Detectar IP desde PHP

En algunos momentos me siento tonto escribiendo este blog, pensando será que a alguien alguna vez le servirá esta información, pero luego pensé que somos muchos los consumidores de internet entramos a bajar música, videos, información, tareas (bueno yo no bajo tareas) pero pocos se dan a la tarea de contribuir con información, quien luego de hacer una buena tarea la sube por si a alguien más le sirve? la mayoridad dirá "NO si a mí me costo que les cueste", como opinión personal pienso que entre mas información compartamos seremos una mejor sociedad digital.

En fin, aquí otro caso, hace poco que estoy haciendo un sistema tipo HELP DESK y se me ocurrió que a los técnicos les interesaría mucho saber la ip de la maquina en donde se puso el caso que en la mayor parte de las veces es la maquina que tiene el problema así que probando funciones y código, termine con la siguiente función espero les sirva:

function obtenerIP() {
    if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
       $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
    }
    elseif (isset($_SERVER['HTTP_VIA'])) {
       $ip = $_SERVER['HTTP_VIA'];
    }
    elseif (isset($_SERVER['REMOTE_ADDR'])) {
       $ip = $_SERVER['REMOTE_ADDR'];
    }
    else {
       $ip = "0.0.0.0";
    }
    return $ip;
}

//De esta forma llamamos a la funcion y obtenemos la IP

$ip=obtenerIP();

martes, 12 de julio de 2011

Dimencionar una imagen en PHP


Voy a tratar de escribir pequeños ejemplos de cómo resolver problemas que a veces se nos presentan mientras programamos, lo hará lo más simple posible, pues en mi caso aprendo mejor de simple a complejo.

Supongamos que queremos mostrar N numero de imágenes que se encuentran dentro de un directorio pero dichas imágenes tienen dimensiones diferentes (alto y ancho) pero queremos que al menos coincidan en una de esas dimensiones por ejemplo que todas tengan 80 pixeles de alto no importa el ancho.

Lo que necesitamos hacer es primero crear la ruta de la imagen:
$link_foto="fotos/nombre_del_archivo.jpg";

Luego verificamos que exista dicho archivo con la sentencia file_exists de este modo 
if (file_exists($link_foto)){

Creamos el objeto de la imagen del tipo jpeg
$img = ImageCreateFromJpeg($link_foto);

Obtenemos su dimensión X
$x = ImageSX($img);

Obtenemos su dimensión Y
$y = ImageSY($img);

Definimos por ejemplo el ancho que queremos en todas las imágenes en pixeles, voy a decirle que quiero 60px de ancho
$ancho=60;

Obtenemos el porcentaje que 60 px de ancho representa en $x con una regla de 3 simple si $x es el 100% de la imagen cuanto representa $ancho;
$por_ancho=(60*100)/$x;

Con este porcentaje podemos obtener el alto en relación al ancho
$alto=round($y*($por_ancho/100));
Cerramos el IF
}

El Código quedaría de la siguiente forma

<?php

$link_foto="fotos/nombre_del_archivo.jpg";
               
if (file_exists($link_foto)){
                               $img = ImageCreateFromJpeg($link_foto);
                               $x = ImageSX($img);
                               $y = ImageSY($img);
                               $ancho=60;
                               $por_ancho=(60*100)/$x;
                               $alto=round($y*($por_ancho/100));
}
?>

Y para mostrar la imagen en HTML lo haríamos así

<img src="<?php echo $link_foto; ?>" width="<?php echo $ancho; ?>" height="<?php echo $alto; ?>" />

martes, 21 de junio de 2011

Compilador en PHP

Creo que llamar a este post compilador me parece un poco presumido de mi parte por lo que la palabra compilador significa y lo que conlleva pero la historia es esta, se nos pidió crear un sistema simulador de un compilador que interpretara un lenguaje de programación en español con esta estructura:

[inicio]
[entradas]
              [variables] [constantes] [ingresos]
[calculos]
              [variable]=[variable/termino] [ + - * / ] [variable]
[decisiones]
             si [condicion] entonces [calculos] sino [calculos]
[salidas]
            mostrar [variable/termino]
[fin]


A dicho lenguaje se le podía aplicar las reglas que nosotros consideráramos necesarias (reglas están en la portada del proyecto) y se dio libertad de escoger el lenguaje en el cual debía ser programado este  compilador, obviamente yo escogí PHP porque PHP? pues por tiempo, por experiencia en el lenguaje,  por que me gusta y porque todos obviamente lo harían en JAVA o C, debo aclarar si el proyecto fuera hacer un compilador real que llegue al nivel más bajo escogería C.

Que etapas consideramos en el proyecto:
1. Análisis Léxico
2. Análisis Sintáctico
3. Análisis Semántico
4. Generación de código intermedio
5. Código objeto

Acá les dejo un diagrama de flujo que un compañero realizo de cómo funciona este compilador y más abajo les dejo el link de acceso a un hosting temporal que tengo mientras recaudo fondos para reactivar mi host personal.


Cualquier duda con gusto escriban un post, el código fuente no puedo subirlo pero si ayudarles con alguna duda.

Link de acceso al proyecto http://bit.ly/jzaugE

Colaboradores de este proyecto ( Jose Jonfe, Erick Mencu)

viernes, 3 de junio de 2011

Envio de correos desde PHP

El envió de correos desde php puede ser una de las tareas mas fáciles hasta una de las más complicadas, todo depende de la configuración y donde este corriendo nuestro código.

Problemas: Si estamos en un ambiente de desarrollo y pruebas como nuestra PC personal, lo más probable es que nos de un error al tratar de enviar un correo con esta función. Porque? pues porque necesitaríamos montar nuestra PC como un Mail Server con los puertos de salida abiertos para que funcione.

Ahora montar un Mail Server son otros 20 centavos que necesitaría varios post y lo cual no hago desde hace mucho tiempo pero si se animan les recomiendo leer este articulo que muestra un SMTP gratuito http://www.desarrolloweb.com/articulos/1624.php

Si por ejemplo estamos trabajando en una red interna donde tenemos acceso a un servidor que si funciona como Mail Server y no requiere autenticación podemos cambiar la configuración de php en el archivo php.ini de la siguiente forma:

Tienes que abrir php.ini luego localizar estas líneas:

[mail function]
; For Win32 only.
SMTP = localhost

En SMTP tienes que indicar el servidor SMTP que vas a utilizar para enviar el mensaje. Si la maquina donde corre el código tiene un servidor SMTP, se deja como "localhost", si no tiene que poner la dirección del servidor a utilizar como smtp.loscorreos.com o 200.35.36.7

Normalmente cuando se compra un servicio de hosting o según me han contado no me consta en algunos casos en hosting gratuitos ya viene incluido el servidor SMTP por lo que se dejaría como localhost.
Existe otra opción que es utilizar PEAR http://pear.php.net/ tiene unas funciones para enviar correo especificando servidor con las credenciales necesarias, usuario, clave, etc. pero si se requiere un poco de experiencia utilizando librerías.

Ahora un ejemplo de cómo sería el código para enviar el correo en php es el siguiente:

<?
$destinatario = "elingeniero@yahoo.com"; //quien lo envia
$asunto = "Mensaje es de prueba"; // asunto del mensaje
$cuerpo = "
<html>
<head>
   <title>Prueba de envio de Correo desde PHP</title>
</head>
<body>
<p>
Aca podria incluirse todo el mensaje que quieran poner con variables de php si fuera necesario ejemplo $nombre $clave
</p>
</body>
</html>
";

//para el envío en formato HTML se define lo que yo llamo cabecera (en español me gusta mas) con todo los datos de envio y configuracion
$cabecera = "MIME-Version: 1.0\r\n";
$cabecera .= "Content-type: text/html; charset=iso-8859-1\r\n";
$cabecera .= "From: Edsson Noe Gonzalez <edssongonzalez@gmail.com>\r\n"; //dirección del remitente
$cabecera .= "Reply-To: edsson_kln@hotmail.com\r\n"; //dirección de respuesta, si queremos que sea distinta que la del remitente
$cabecera .= "Cc: mijefe@concuidado.com\r\n"; //esto se pone si queremos copiar el correo a otra direccion

//Con esta funcion enviamos el correo
mail($destinatario,$asunto,$cuerpo,$cabecera);
?>

Una vez mas lo digo yo no soy experto no me considero para nada experto y puedo tener uno o muchos errores en esto, si alguien encuentra uno y me lo dice en hora buena, asi se aprende mas.

miércoles, 11 de mayo de 2011

Manejo de Buffers de Entrada - Compiladores


Esta sección trata algunos aspectos de la eficiencia relacionados con el manejo de los buffers de entrada, esto toma importancia cuando se busca un esquema de un pre análisis en la entrada para identificar los componentes léxicos, la finalidad de esto es utilizar técnicas que aumenten la velocidad de analizador léxico.

1.    DEFINICION DE TERMINOS

Analizador  léxico
 Lee  la secuencia de caracteres del programa fuente, carácter a carácter, y los agrupa para formar unidades con significado propio, ósea componentes léxicos  o tokens en ingles. Estos componentes léxicos representan: palabras reservadas: if, while, do,  identificadores  asociados a variables, nombres de funciones,  operadores: = * + - / == > < & ! =. . ., etc.

Buffer de datos
Un buffer en informática es un espacio de memoria, en el que se almacenan datos para evitar que el programa o recurso que los requiere, ya sea hardware o software, se quede sin datos durante una transferencia.


Un ejemplo de esto último ocurre en una comunicación telefónica, en la que al realizar una llamada esta se almacena, se disminuye su calidad y el numero de bytes a transferidos, y luego se envían estos datos modificados al receptor.

Pueden ser implementados por software o hardware, aunque la gran mayoría son del primer tipo. Normalmente se usan cuando la frecuencia de transferencia de datos es distinta a la de procesado. Estas diferencias temporales de transmisión son normalmente ajustadas mediante la implementación de un algoritmo con cola (o estructura de tipo FIFO) en memoria, para así escribir datos en la cola a una frecuencia y leerlos a otra.

Se puede ejemplificar la función de un buffer utilizando ésta metáfora: Un buffer es como tener dinero en el banco (buffer), un trabajo (entrada) y unos gastos fijos (salida). Si tienes un trabajo inestable, mientras tengas ciertos ahorros, puedes mantener tus gastos fijos sin problemas, e ir ingresando dinero cuando puedas según vas trabajando. Si los ahorros son pequeños, en seguida que no tengas trabajo, no vas a poder acometer los gastos fijos.


Diferencias con la caché:
Una caché puede ser usada a veces como un buffer, y viceversa. Sin embargo, una caché opera con el supuesto de que los mismos datos van a ser utilizados múltiples veces, que los datos escritos serán leídos en un periodo corto de tiempo, o teniendo en cuenta la posibilidad de múltiples lecturas o escrituras para formar un único bloque más grande. Su premisa básica es reducir los accesos a los almacenamientos de nivel más bajo, los cuales son bastante lentos.

Una caché de disco o archivo de caché guarda las estadísticas de los datos almacenados en él y proporciona datos con un tiempo máximo de espera en modos de escritura en diferido. Un buffer, por el contrario, no hace nada de esto, sino que es utilizado normalmente en entrada, salida y a veces, almacenamiento temporal de datos que se enrutan entre distintos dispositivos o que van a ser modificados de manera no secuencial antes de ser escritos o leídos de manera secuencial.


2.       MANEJO DE LOS BUFFERS DE ENTRADA

Hay tres métodos generales de implantación de un analizador léxico:

1. Utilizar un generador de analizadores léxicos, como el compilador LEX, para producir el analizador léxico a partir de una especificación basada en expresiones regulares. En este caso, el generador proporciona rutinas para leer la entrada y manejarla con buffers.

Nota Personal:
LEX y FLEX no son lo mismo LEX es un software utilizado para generar componentes léxicos para UNIX y como sobran UNIX es un sistema operativo no libre por lo tanto este LEX se convierte en un programa licenciado, FLEX es la versión libre de este sistema ,  FLEX estas desarrollado bajo licencia GNU la cual lo hace un software libre pero con  restricciones, GNU es una licencia orientada  a proteger la libre distribución modificación y uso del software pero a su vez lo protege de intentos de apropiación que lleguen a quitar libertades. GNU es juego de palabras que al final significa IS NOT UNIX su creador recomienda pronunciarlo como ÑU igual que el animal por eso el logo es la cabeza de este animal los que usaron FLEX la pudieron ver, pero al final todos lo pronunciamos como queramos.

2. Escribir el analizador léxico en un lenguaje convencional de programación de sistemas, utilizando las posibilidades de entrada y salida para leer la entrada.

3. Escribir el analizador léxico en lenguaje ensamblador y manejar explícitamente la lectura de la entrada.

Estas tres opciones se relacionan en orden de dificultad reciente para el encargado de la implantación. Aunque los enfoques más difíciles de implementar se convierten en los más rápidos y ya que el analizador léxico no es la más complicada pero si es la única etapa que lee el código fuente esto se puede traducir en tiempo.

3.       PAREJAS DE BUFFERS

Como se puede consumir mucho tiempo moviendo caracteres, se han desarrollado técnicas especializadas en el manejo de buffers para reducir el número de operaciones necesarias para procesar un carácter de entrada.

Se utiliza un buffer dividido en dos mitades de N caracteres cada una (por lo general N es el número de caracteres en un bloque de disco, por ejemplo, 1024 ó 4096). Se leen N caracteres de entrada en cada mitad del buffer con una orden de lectura, en vez de invocar una instrucción de lectura para cada carácter de entrada. Si quedan menos de N caracteres en la entrada, entonces se lee un carácter especial eof, que marca el final del archivo fuente. 

Se mantienen dos apuntadores al buffer de entrada.  La cadena de caracteres entre los dos apuntadores es el lexema en curso.
Al principio, los dos apuntadores apuntan al primer carácter del próximo lexema que hay que encontrar.
Uno de ellos, llamado apuntador delantero, examina hacia delante hasta encontrar una concordancia con un patrón. Una vez determinado el siguiente lexema, el apuntador delantero se coloca en el carácter de su extremo derecho. Después de haber procesado el lexema, ambos apuntadores se colocan en el carácter situado inmediatamente después del lexema.
Cuando el apuntador delantero está a punto de sobrepasar por la marca intermedia del buffer, se llena la mitad derecha con N nuevos caracteres de entrada.
Cuando el apuntador delantero está a punto de sobrepasar el extremo derecho del buffer, se llena la mitad izquierda con N nuevos caracteres de entrada y el apuntador delantero se regresa al principio del buffer.

(Este y el siguiente algoritmo lo escribí interpretando la información que encontré no se puede tomar como base porque no está probado y creo que hasta se puede mejorar en mucho)

If (delantero = final de la primera mitad){
                Recargar la segunda mitad;
                Delantero = delantero + 1;
}
If (delantero = final de la segunda mitad){
                Recargar la primera mitad;
                Pasar delantero al principio de la primera mitad;
}
If(delantero!= final de la primera mitad  &&  delantero!=final de la segunda mitad){
                Delantero=delantero+1;
}

4.       CENTINELAS

El centinela se define como un carácter especial que no puede ser parte del programa fuente. una elección natrual es eof (fin de archivo en ingles), lo que se hace es poner un carácter eof al final de cada mitad para evitar estar haciendo la comprobación con cada lexema, como se encuentran N caracteres de entrada entre los simbolos eof, el promedio de pruebas por cada carácter de entrada es próximo a 1

Delantero=delantero +1;
If (delantero = eof){
                If (delantero = final de la primer mitad){
                               Recargar la segunda mitad;
                               Delantero=delantero+1;
                }
                If(delantero=final de la segunda mitad){
                               Recargar la segunda mitad;
                               Delantero=delantero+1;
                }
                If(delantero!= final de la primera mitad  &&  delantero!=final de la segunda mitad){
                                //eof;
                               Terminar el análisis léxico
                }
}

Fuente de informacion: Wikipedia y  Libro Compiladores Principios Tecnicas Y Herramientas - Aho Sethi Ullman Pearson