Frases interesantes

Personal September 22nd, 2007

    No existe mayor signo de demencia que hacer lo mismo una y otra vez y esperar resultados diferentes.

Albert Einstein

    No tiene sentido contratar a personas inteligentes y después decirles lo que tienen que hacer. Nosotros contratamos a personas inteligentes para que nos digan que tenemos que hacer.

Steve Jobs, fundador de Apple Computer

    Señores, han confundido el objetivo: Nuestros clientes no quieren taladros.
Nuestros clientes quieren agujeros.

Presidente de Black & Decker.

    Caminar sobre el agua y desarrollar software a partir de unas especificaciones es fácil ... si ambas están congeladas.

Desconocido.

PHP básico (parte 1)

Desarrollo de software, Web September 15th, 2007

Etiquetas de sección PHP

Las secciones de código PHP deben enmarcarse entre ciertas etiquetas que hacen explícito su contenido, estas etiquetas pueden ser de los siguientes tipos.

Estilo convencional <?php ... ?>
Etiquetas cortas <? ... ?>
<?= $variable; ?>
Etiquetas de script <script language="php"> ... </script>
Etiquetas estilo ASP <% ... %>

Las etiquetas cortas provocan algunas veces problemas con la interpretación XML de algunos navegadores, sin embargo incluyen la funcionalidad abrevidada de <?= $variable; ?> la cual es expandida automáticamente por el intérprete de PHP a <?php echo $variable; ?>.

Las etiquetas cortas, de script y estilo ASP son ahora obsoletas y se recomienda sólo utilizar las etiquetas del estilo convencional.

Saltos de línea

Los saltos de línea son ignorados por el intérprete de PHP y de HTML, sin embargo en casos específicos separan la sección de la cabecera de la sección de los datos en una respuesta HTTP de un servidor web, por este motivo el intérprete PHP remueve siempre el primer salto de línea después de la etiqueta ?>.

Una forma de eliminar posibles problemas de este estilo es el de omitir cerrar el script, lo cual es perfectamente legal para el intérprete de PHP.

Comentarios

// Comentarios de una sóla línea estilo C.

# Comentarios de una sóla línea.

/*
Comentarios multi línea
estilo C++.
*/

/**
* Comentarios estilo documentación.
*/

Los comentarios de una sóla línea deben terminar en un salto de línea (\n, \r o \n\r según sea el caso) o en una etiqueta de cierre ?>. Por este motivo la etiqueta de cierre tendrá significado aunque se encuentre dentro de un comentario.

Por lo anterior, el siguiente código es válido:

<?php
echo "hola "; // No incluir esta ?> etiqueta

El resultado impreso en salida estándar será: hola etiqueta.
Espacios en blanco.

PHP ignora el exceso de espacios en blanco en la mayoría de los casos. Existen algunas limitaciones.

  • No puede haber espacios entre <? y php.
  • No es posible separar las palabras clave (Ej: func tio, whi le, etc.).
  • No es posible separar los nombre de identificadores: variables y funciones (ej: $var iable, imp rimir()).

Bloques de código

Los bloques de código son sentencias encerradas entre llaves. Son un conjunto de lineas que deben ser todas ejecutadas bajo ciertas circunstancias.

{

// Líneas de código.

}

Los bloques pueden anidarse entre si, es decir, un bloque de código puede contener otros bloques de código a su vez.

Construcciones propias del lenguaje

Las construcciones son elementos que se encuentran incluidos directamente por el lenguaje. Estas construcciones no son funciones convencionales, por lo tanto no retornan un valor.

Ejemplo: echo, die y exit.

Tipos de datos

PHP maneja internamente los tipos de datos en dos grandes categorías: escalares y compuestos.

Una variable escalar contiene un único valor en un instante de tiempo. Los tipos escalares pueden ser de las siguientes clases.

boolean su valor puede ser true o false.
int valores numéricos, con signo y enteros
float valores numéricos, con signo y de punto flotante
string colección de valores binarios

Valores numéricos

Como se mencionó anteriormente, los valores numéricos pueden ser de dos clases: enteros y de punto flotante. Los valores numéricos tienen signo, es decir, pueden representar un valor positivo o uno negativo.

Pueden ser expresados utilizando diferentes notaciones.

Decimales Notación decimal estándar sin separador de miles.
Octales Notación octal. Identificada por un cero como prefijo al valor.
Hexadecimales Notación base 16. Identificada por un 0x como prefijo al valor. Los valores
hexadecimales y el prefijo 0x son insensibles a las mayúsculas.

Los valores de punto flotante son llamados en otros lenguajes de programación como float o double.

Pueden ser expresados bajo dos diferentes notaciones.

Decimal Notación decimal estándar sin separador de miles utilizando el punto como
separador decimal.
Exponencial Compuesto por los dígitos significativos (mantisa), la letra E (insensible a mayúsculas)
y un exponente.Ejemplo: 2E3 equivale a 2 x 10^3 que es igual a 2000.

Al trabajar con valores numéricos se deben tener en cuenta los siguientes aspectos.

  • La precisión y el rango de los valores es dependiente de la plataforma en la que se está ejecutando el intérprete de PHP.
  • PHP no verifica desbordamientos (overflows).

Ejemplo:

Considere la siguiente expresión: $x = (int) ((0.1 + 0.7) * 10);

El valor esperado de $x sería 8, el cual es el realmente obtenido si se obvia la conversión a entero. Sin embargo la expresión se almacena internamente como 7.999999 en lugar de 8, así que al solicitar su parte entera se obtendrá paradójicamente el valor de 7.

Cuando se necesite precisión en las operaciones matemáticas en un programa PHP se recomienda utilizar las funciones de la extensión BCMath en lugar de las nativas.

Cadenas.

Las cadenas son el tipo de datos equivalente al texto en PHP. En realidad almacenan colecciones ordenadas de información binaria, que a su vez puede ser texto, sin embargo también puede ser un archivo de imagen, una hoja electrónica o un archivo MP3.

Booleanos.

El dominio de datos de este tipo sólo cobija los posibles valores true y false.

La conversión de tipos de datos desde y hacia el tipo boolean sigue estas reglas.

  1. Un número se convierte en false si su valor es cero, en cualquier otro caso será true.
  2. Una cadena se convierte en false si es vacía o si contiene un cero como unico caracter. Si contiene otra información, incluyendo múltiples ceros, será convertida a true.
  3. Cuando se convierte un booleano a un número o una cadena, este será 1 si el valor original era true o 0 en caso contrario.

Tipos de datos compuestos

PHP tiene soporte para dos tipos de datos compuestos.

  • Arreglos: son contenedores ordenados de información.
  • Objetos: son contenedores de información y de código.

Otros tipos de datos

El lenguaje define los siguientes tipos de datos particulares para ser utilizados en situaciones especiales.

NULL. Indica que una variable no tiene valor. El valor de una variable es NULL cuando se le asignó explícitamente este valor o si aún no se le ha asignado un valor específico.

Tipo de datos resource. Referencia una fuente de datos externa que no se encuentra representada nativamente por PHP. Ejemplos de esto son las referencias a archivos y a imágenes.

Conversión entre tipos de datos.

A pesar de que PHP maneja la conversión de datos de manera transparente es posible forzarla utilizando los operadores de conversión de tipo, los cuales son simplemente el tipo de datos requerido encerrado entre paréntesis. Este procedimiento es conocido como promoción de tipos (casting).

Ejemplo:

$x = 77.23;

$y = (int) $x;

El valor de $y será el de 77, es decir, la parte entera del valor real contenido en $x.

Con respecto a los valores de tipo resource se debe tener en cuenta las siguientes consideraciones.

  • Ningún tipo de datos puede convertirse en resource.
  • Los valores de tipo resource pueden convertirse en valores de tipo entero o cadena cuya representación será el identificador del recurso o la cadena "Resource ID #" seguida del identificador del recurso respectivamente.

Variables

Son entidades computacionales para el almacenamiento temporal de información, pueden contener cualquier tipo de datos como cadenas, enteros, reales, objetos y arreglos, ya que el lenguaje no define tipos de datos específicos rígidos para sus variables (loosely typed). Implícitamente se realizan las operaciones necesarias para realizar la conversión de tipos según se necesite basado en las operaciones realizadadas sobre los valores.

  • Los identificadores de las variables deben empezar con el símbolo de pesos ($).
  • El identificador debe estar compuesto por letras (a - z, A - Z), números (0 - 9) y guión bajo (_).
  • La primera letra después del símbolo de pesos debe ser una letra o un guión bajo.
  • Los identificadores de las variables son sensibles a mayúsculas.

Ejemplo:

$valido = 1;
$_valido = 1;
$5invalido = 0;

Las variables de variables son variables cuyo nombre es el valor almacenado en otra variable.

$nombre = "edad";
$$nombre = 30;

echo $edad; // 30

Siguiendo este procedimiento, es posible crear variables cuyos nombres no respeten las reglas mencionadas anteriormente.

Ejemplo:

$nombre = "2variable";
$$nombre = "valor";

echo ${'2variable'}; // valor

Otra construcción que es posible realizar gracias a la flexibilidad del lenguaje es la de almacenar nombres de funciones en una variable y a partir de ella realizar el correspondiente llamado.

Ejemplo:

$func = "miFuncion";
$func(); //ejecuta a miFuncion()

Sabiendo que PHP no es un lenguaje declarado, es decir, no es necesario declarar las variables antes de utilizarlas, se hace necesario poder determinar si una variable determinada existe en un momento preciso de la ejecución de un programa. Para eso se utiliza la construcción isset().

Ejemplo:

$x = 1;
isset($x); // true
isset($y); // false

Constantes

Son entidades computacionales cuyo valor es inmutable, es decir, no cambia durante la ejecución del programa.

  • Las constantes pueden ser accedidas desde cualquier ámbito del programa.
  • Sólo pueden contener valores escalares.
  • Sus identificadores son sensibles a mayúsculas y tienen las mismas restricciones que los identificadores de las variables, exceptuando el hecho que su nombre no empieza por el signo de pesos ($).
  • Como buena práctica de programación se sugiere que su identificador debe ser en mayúsculas.
  • Su definición se realiza a través de la construcción define.

Ejemplos:

define ('DEBUG', true); // Constante DEBUG = true

define ('EDAD', 30); // Constante EDAD = 30

asdf

Tags:

Estado vegetativo asistido

Humor September 13th, 2007

Anoche mi mamá y yo estábamos sentados en la sala
hablando de las muchas cosas de la vida... entre otras...
estábamos hablando de la idea de vivir o morir.
Le dije: 'Nunca me dejes vivir en estado vegetativo,
dependiendo de máquinas y líquidos de una botella.
Si me ves en ese estado, desenchufa los artefactos que
me mantienen vivo, prefiero morir.'
Entonces, mi mamá se levantó con una cara de admiración...
Y me desenchufó el televisor, el DVD, el computador, el ipod
y me botó todas las cervezas!! ju3put4 ...CASI ME MUERO!!!

Problemas entre (PHP) XML-RPC, Apache y mod_security

Linux/Unix/FreeBSD, Web, Windows September 5th, 2007

Cuando subí mi segundo demo de PHPXMLRPC al hosting encontré un problema. Apache me decía que la ruta como estaba referenciando al servidor desde el cliente era inválida. Esto era totalmente extraño porque localmente funcionaba e imprimiendo la ruta generada y probándola verifiqué que era correcta.

Buscando (gracias Dios por Internet) encontré que probablemente se deba esto a mod_security, aquel módulo de Apache que nos ayuda a asegurar los servidores web filtrando cierta información de las aplicaciones web no necesariamente bien construidas, que algunas veces como en esta ocasión, genera problemas de configuración.

Para solucionarlo desactivé la utilización de mod_security en el directorio donde se ubica el proyecto. Para esto se debe crear el siguiente .htaccess.

<IfModule mod_security.c>
SecFilterEngine Off
SecFilterScanPOST Off
</IfModule>

Tags: , ,

Encriptando cositas con MCrypt

Desarrollo de software, Web September 5th, 2007

La fase final de mi experimento con XML-RPC suponía poder encriptar la solicitud que iba del cliente al servidor así como la respuesta de este último hacia el cliente. Como se sobreentiende, esta encriptación debería ser de dos vías. Para esto estuve revisando la API de PHP y encontré que la utilización de la librería mcrypt es bastante útil y que por suerte hasta el hosting mas antiguo de todos la soporta en PHP.

Para esto entonces desarrolle dos procedimientos: encriptar y desencriptar para separar su funcionalidad.

Encriptar.

Para encriptar información se requieren los siguientes parámetros.

  • El nombre del algoritmos de encriptación (Ej. blowfish).
  • El modo de encriptación (Ej. cfb).
  • El orígen del azar (Ej. MCRYPT_RAND).
  • La contraseña de encriptación (secreta).
  • Los datos a encriptar.
  • El vector de encriptación (IV) que actúa como semilla (opcional).

Se abre el módulo del algoritmo de encriptación y se especifica su definición.

$td = mcrypt_module_open($encryption_algorithm, '', $encryption_mode, '');

Se crea el vector de encriptación y se determina la longitud de la llave.

$client_iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), $random_source);
$ks = mcrypt_enc_get_key_size($td);

Se crea la llave basada en la contraseña de encriptación especificada por el usuario (mayor seguridad).

$key = substr(md5($encryption_key), 0, $ks);

Se inicializa la encriptación con la información establecida anteriormente.

mcrypt_generic_init($td, $key, $client_iv);

Se encriptan los datos.

$encrypted_data = mcrypt_generic($td, $raw_data);

Se termina el proceso de encriptación.

mcrypt_generic_deinit($td);

Al final se obtiene el vector de encriptación ($client_iv) y la información encriptada ($encrypted_data), ambos son necesarios para realizar el proceso inverso.

Desencriptar.

Para desencriptar la información se requiere la siguiente información.

  • El nombre del algoritmos de encriptación (Ej. blowfish).
  • El modo de encriptación (Ej. cfb).
  • La contraseña de encriptación (secreta).
  • El vector de encriptación (IV).
  • Los datos encriptados.

Se abre el módulo del algoritmo de desencriptación y se especifica su definición.

$td = mcrypt_module_open($encryption_algorithm, '', $encryption_mode, '');

Se determina la longitud de la llave.

$ks = mcrypt_enc_get_key_size($td);

Se crea la llave basada en la contraseña de encriptación especificada por el usuario (mayor seguridad).

$key = substr(md5($encryption_key), 0, $ks);

Se inicializa la desencriptación con la información establecida anteriormente.

mcrypt_generic_init($td, $key, $client_iv);

Se desencriptan los datos.

$decrypted_data = mdecrypt_generic($td, $encrypted_data);

Se termina el proceso de encriptación y se cierra el módulo.

mcrypt_generic_deinit($td);
mcrypt_module_close($td);

Al final se obtiene la información desencriptada ($decrypted_data) la cual debe corresponder con la información original. Algunas veces la desencriptación deja espacios en blanco a los lados de la cadena desencriptada por lo que puede ser de utilidad pasar la información por un trim() como último paso.

La demostración de este código se encuentra siguiendo este enlace Demo #0. Este cuenta con los archivos config.php (variables necesarias), security.php (funciones para encriptar y desencriptar) y demo1.php (ejemplo funcional).

Tags:

Eudora ahora es ‘Open Source’

Software, Windows September 5th, 2007

A partir del primero de mayo pasado, Eudora uno de los primeros paquetes de software de correo electrónico que conocí se convirtió en un proyecto de código abierto. Qualcomm, la empresa que lo desarrollaba mantenía dos lineas de licenciamiento: una comercial y otra gratuita apoyada en la presentación de propagandas (sponsored) al usuario.

Mozilla por su parte dice que va a continuar con el proyecto de manera paralela a Thunderbird sin que estos proyectos compitan entre si. Imagino que algún día se fusionarán en un mismo producto.

Mas información respecto del proyecto Penélope en ... http://wiki.mozilla.org/Penelope

Tags:

Planeación MS

Humor September 4th, 2007

Planeación MS FreeBSD

Primer ejemplo de XML-RPC

Desarrollo de software, Web September 3rd, 2007

Estimando que probablemente uno de los proyectos de la Fundación requiera la consulta de información de uno de los proyectos anteriores ubicado en uno de los servicios de hosting, decidí realizar algunos experimientos con XML-RPC para determinar la viabilidad de utilizarlo para esta tarea en caso de que sea realmente necesaria. Debido a que el hosting en el que se encuentra el proyecto tiene una versión bastante antigua de PHP4 se decidió utilizar la librería de http://phpxmlrpc.sourceforge.net/.

Este es mi primer contacto con XML-RPC. Había leido un poco del tema en la documentación del framework CodeIgniter que planeo utilizar dentro de poco en mis próximos proyectos, sin embargo como está basado en PHP5 y el hosting soporta únicamente PHP4 decidí probar con la librería mencionada anteriormente, la cual es bastante mas enrredada, pero por suerte bien documentada, aunque hacen falta ejemplos.

En este pequeño demo que implementé se envían por parte del cliente un nombre ("Pepe") y la solicitud de ejecución de un procedimiento remoto ("HelloWorld.show"). El servidor relaciona este método remoto con un procedimiento local ("show") que retorna la cadena resultante ("Hello Pepe").

El Cliente.

Se realiza el include de la librería de XML-RPC.

include_once ("../lib/xmlrpc-2.2/lib/xmlrpc.inc");

Se define la ubicación del servidor y se instancia un objeto de la clase cliente.

$host = "localhost";
$location = "xmlrpc/d1";
$server = "ServerHello.php";

$client = new xmlrpc_client("http://{$host}/{$location}/{$server}");

Se prepara el mensaje que enviará el cliente. El mensaje define cual es el procedimiento remoto a ejecutarse y la información relacionada con este (parámetros). Para el ejemplo se invocará al procedimiento HelloWorld.show y se le enviará "Pepe" que es de tipo string.

$message = new xmlrpcmsg("HelloWorld.show", array(new xmlrpcval("Pepe", "string")));

Si se desea consultar los mensajes de depuración se debe activar la siguiente expresión.

// $client -> setDebug(3);

Con todo listo, se envía la solicitud al servidor y se captura su respuesta.

$response = $client -> send($message);

Si la respuesta referencia a un error, este viene con su respectivo código de fallo, en caso contrario se puede consultar su contenido.

if ($response -> faultCode())
echo "<br>KO. Error: " . $response -> faultString();
else
echo "<br>OK. got ... " . $response -> value() -> scalarVal();

El Servidor.

Se realiza el include de la librería de XML-RPC, se incluyen los dos archivos inc: cliente y servidor.

include_once ("../lib/xmlrpc-2.2/lib/xmlrpc.inc");
include_once ("../lib/xmlrpc-2.2/lib/xmlrpcs.inc");

Se instancia un objeto de clase servidor en la que se especifica la siguiente información de los procedimientos remotos expuestos como disponibles:

  • Relación entre nombre de procedimiento remoto y función PHP a ejecutarse en su llamado.
  • La firma de la función (signature): tipo de retorno y de parámetros requeridos. Una función puede tener varias firmas.
  • Documentación de la función (docstring).

$server = new xmlrpc_server(array(
"HelloWorld.show" => array("function" => "show",
"signature" => array(array($xmlrpcValue, $xmlrpcString)),
"docstring" => "Shows a greeting message with the specified name.")
), false);

Si se desea consultar los mensajes de depuración se debe activar la siguiente expresión.

// $server -> SetDebug(3);

Cuando todo está listo se envía la respuesta al cliente.

$server -> service();

Como siguiente paso se debe definir la función PHP show que será ejecutada cuando el procedimiento remoto HelloWorld.show sea solicitado.

La función recibe la información enviada por el cliente ($xmlrpcmsg) y tiene acceso a la variable $xmlrpcerruser la cual indica el número del error a partir del cual se encuentran disponibles para los errores definidos por el usuario.

function show($xmlrpcmsg)
{
global $xmlrpcerruser;

Verifico que el número de parámetros enviados por el cliente sea de uno, en caso contrario envío un código de error.

if ($xmlrpcmsg -> getNumParams() != 1)
{
return new xmlrpcresp(0, $xmlrpcerruser+1, "I am expecting a parameter for the name!");
}

Obtengo el valor del parámetro disponible.

$val0 = $xmlrpcmsg -> getParam(0);

if($val0 -> kindOf() != "scalar")
{
return new xmlrpcresp(0, $xmlrpcerruser+2, "I am expecting a string as parameter for the name!");
}

$name = $val0 -> scalarval();

Compongo la cadena resultante: "Hello " + valor del parámetro y la empaqueto en un mensaje de respuesta (xmlrpcresp) el cual es de tipo string y es enviado hacia el cliente.

return new xmlrpcresp(new xmlrpcval("Hello " . $name, "string"));
}

El demo #1 en ejecución puede ser consultado en http://demo.jorgeivanmeza.com/PHP/XMLRPCDemo/0.1/ClientHello.php

La documentación en línea de XML-RPC for PHP puede ser consultada en http://phpxmlrpc.sourceforge.net/doc-2/.