Feb 15

Seis días después de la nueva versión 5.2.1 que corregía varios bugs de seguridad hoy ya tenemos disponible el equivalente para la serie 4.x, la versión 4.4.5.

Al igual que con la serie 5.x la actualización es muy recomendable ya que, a pesar de que no paras de encontrarte post y comentarios de gente que piensa que por usar la versión 4 del PHP están libres de bugs de seguridad, no es así ni mucho menos.

Ah, y… un pequeño fallo en el anuncio. Lo de:

Prevent search engines from indexing the phpinfo() page.

en la home de php.net está puesto como una mejora de seguridad sólo para la 5.2.1 pero aparece listado en el changelog de la 4.4.5, ¿en qué quedamos? :)

Tagged with:
Feb 11

Aunque voy un poco tarde no podía dejar de comentar esto en mi blog. Desde el 8 de Febrero tenemos disponible una nueva versión del PHP, la 5.2.1. A parte de pocas novedades lo más importante de esta versión es q corrige varios de los bugs que Stefan Esser pensaba publicar en Marzo, aunque no todos. Si ya trabajas con la extensión Suhosin varios de los bugs q se corrigen no te afectan.

Stefan Esser autor de la extensión Suhosin era desarrollador del PHP desde el 2001 y formaba parte del Security Response Team. En diciembre anunciaba en su blog q se retiraba del equipo de PHP oficialmente ya q ya hacía tiempo q no le gustaba la dirección que había tomado el proyecto. (si eres un BSDero te sonará la historia). Es por esto q ya hace meses q decidió montar el mes del los bugs del PHP en Marzo al igual q ya se había hecho con el mes de los bugs del browser o el mes de los bugs del kernel.

Como respuesta al anuncio de la neva versión del PHP Stefan publica en su blog “otra” dura crítica al equipo del PHP. Como no, Ilia Alshanetsky q es el desarrollador encargado de escribir la notas de release le contesta y… ya la tenemos liada :) (ver los comentarios del post).

Como recomendación rápida: Actualizarse a la 5.2.1 y utilizar Suoshin antes de q empiece la fiesta en Marzo.

Tagged with:
Feb 09

Dado que ya he hecho un post acerca de como realizar peticiones cURL y otro relacionado con el formateo de XML, sólo me falta lo evidente, un post acerca de como leer y trabajar con los datos XML recibidos. Desde que tenemos la versión 5 del PHP disponemos de la extensión SimpleXML la cual nos proporciona una forma muy rápida y fácil de leer datos XML. Si has programado parsers XML usando librerías como expat encontrarás que esta extensión es una auténtica maravilla, aunque como siempre, a costa de consumir más recursos (básicamente más memoria… pero lo vale).

Con SimpleXML consigues muy fácilmente convertir un archivo XML en un objeto. Para representar la estructura de elementos del documento XML se construye un objeto con atributos q pueden contener directamente valores o arrays de objetos q también tendrán más atributos, más arrays de objetos, etc. (el número de arrays de arrays de objetos depende de los niveles de anidación de los elementos). Se puede trabajar con estos objetos como con cualquier otro en PHP.

Se entiende mucho mejor su uso con un ejemplo sencillo. Imaginemos el siguiente documento XML:

[xml]


Hola
Hola, que tal?


Re: Hola
Bien, gracias.

[/xml]

Asumiendo que en $data tenemos el XML a leer con un código PHP como:

[php] $xml = simplexml_load_string($data);
foreach ($xml->mensaje as $mensaje)
echo $mensaje->texto.’ ‘; [/php]

Obtendremos el resultado:

Hola, que tal? Bien, gracias.

SimpleXML nos puede devolver errores de todo tipo, documentos malformados, problemas de encodings, etc. Si estás en un entorno donde sólo te interesan los documentos válidos y quieres descartar el resto resulta útil algo como:

[php] function loadXML($data) {
$xml = @simplexml_load_string($data);
if (!is_object($xml))
throw new Exception(‘Error en la lectura del XML’,1001);
return $xml;
} [/php]

Si queremos volver a obtener el documento XML dado un objeto SimpleXML es tan fácil como:

[php] echo $xml->asXML(); [/php]

En ocasiones tenemos XML con muchos niveles de elementos y se hace especialmente engorroso ir recorriendo con “foreach” todo el documento. En estas situaciones, como en muchas otras, es necesario poder buscar dentro de los XML. Esto lo conseguimos con el soporte XPath que ofrece SimpleXML. Por ejemplo para acceder a todos los elementos “asunto” del ejemplo anterior:

[php] foreach ($xml->xpath(‘//asunto’) as $asunto)
echo $asunto.”\n”; [/php]

Existen dos consideraciones a tener en cuenta con el uso de SimpleXML:

[1] Si quieres acceder a un elemento que tiene un guión “-” en su nombre debes hacerlo así:

[php] foreach ($xml->{‘mensaje-personal’} as $mensaje)
echo $mensaje->texto.’ ‘; [/php]

Si suponemos que en el ejemplo anterior sustituimos “mensaje” por “mensaje-personal”.

[2] Es recomendable hacer cast a string siempre que obtenemos datos de los objetos SimpleXML. En ocasiones (unexpected :) en lugar de devolver directamente el valor de un elemento devuelve otro objeto SimpleXML, se soluciona con:

[php] $texto = (string) $data_o->mensaje[0]->texto; [/php]

Antes de terminar comento otra característica interesante y es que podemos convertir un objeto SimpleXML en un objeto DOM y viceversa usando las funciones simplexml_import_dom() y dom_import_simplexml(), incluso en las últimas versiones del PHP se le han añadido métodos para poder modificar y crear desde cero documentos XML trabajando directamente con el objeto SimpleXML (al estilo DOM).

Tagged with:
Feb 06

Si estamos metidos en la “divertida” tarea de programar intérpretes de protocolos XML nos puede ayudar un poco el paquete XML_Beautifier de las PEAR. Se trata de un embellecedor de código que se encarga de limpiar y dejar leíbles los datos XML.

Normalmente en las transacciones XML los datos se transfieren sin saltos de linea, ni espacios extra, etc. Esto, dependiendo de la complejidad del XML, hace casi imposible la lectura por un humano. La clase XML_Beautifier nos ayudará a separar en distintas líneas, tabular correctamente el código entendiendo los tags, simplificar los comentarios, cambiar mayúsculas por minúsculas, reemplazar caracteres por su entidad HTML, etc. Si no quieres estar copiando constantemente los XML en un navegador para poder leer algo te puede ayudar bastante.

Su uso es el siguiente:

[php] require_once ‘XML/Beautifier.php’;
$fmt = new XML_Beautifier();
$resultado = $fmt->formatString($archivo);
if (PEAR::isError($resultado))
echo $resultado->getMessage(); [/php]

En $archivo tenemos el contenido del archivo XML, por ejemplo la respuesta de una petición cURL, y en $resultado obtendremos el XML formateado. También disponemos de la alternativa a formatString() q es:

[php] $resultado = $fmt->formatFile(‘original.xml’, ‘formateado.xml’); [/php]

Con esto se trabaja sobre archivos en disco y no variables. Dispone de distintas opciones de configuración q nos permitirán fijar el número de espacios de los tabs y demás.

Una advertencia acerca de esta clase… Consume bastante memoria y tiempo para realizar la transformación. Es por esto que si estás soportando muchas transacciones XML es aconsejable sólo usar XML_Beatufier en el momento de leer los XML y no siempre.

Ah! por cierto, de momento está sin maintainer, ten controlado donde la usas pq quizás has de dejar de hacerlo… aunque funciona perfectamente.

Tagged with:
Feb 04

En el desarrollo de aplicaciones PHP es muy frecuente encontrarse con la necesidad de enviar algún tipo de email: bonitos en HTML a los usuarios, de debug, alertas, etc. Para enviar un correo electrónico en PHP disponemos de varias formas de hacerlo, lo más rápido es con las funciones incorporadas en el mismo lenguaje aunque también disponemos de una gran cantidad de clases y librerías ya hechas, como las PEAR Mail. Como siempre el uso de librerías externas con muchas líneas de código empeoran el rendimiento y mantenimiento de nuestro software. Pero las PEAR Mail son bastante ligeras y, en mi opinión, muy útiles en los casos en que queremos enviar emails “bonitos” con HTML enviando también la versión texto, con attachments, imágenes, vídeos, y demás, así nos olvidamos de tener que gestionar todo lo necesario manualmente (cabeceras, codificaciones, extensiones MIME, etc.). Aunque siempre se ha de valorar el uso que le vamos a dar de lo q ofrece y el número y tipo de emails q necesitamos enviar. A continuación detallo brevemente algunos métodos para enviar distintos tipos de email desde PHP.

Función mail()

Para enviar emails sencillos en modo texto el uso de la función mail() es sin lugar a dudas lo más cómodo. Su uso es el siguiente:

[php] mail(‘direccion@del.destinario.com’,’Asunto’,’Mensaje’); [/php]

Devuelve TRUE en caso de éxito y FALSE en caso contrario. También podemos pasarle cabeceras adicionales como cuarto parámetro, esto puede ser útil, por ejemplo, para enviar mensajes HTML usando mail() pero a la mínima q necesites enviar emails un poco más complejos es recomendable usar las PEAR.

Función error_log()

Para todos aquellos emails de debug o alertas internas de nuestro software podemos usar error_log(). Con esta función podemos hacer log a distintos destinos: el log del sistema, un archivo, la conexión de debug y también enviar por email. Por ejemplo para enviarnos por email información acerca de una exception q nos salta en nuestro código:

[php] try {
// código con posibles errores
} catch (Exception $e) {
$msg = ‘ERROR #’.$e->getCode().”\n”;
$msg .= $e->getMessage().”\n”;
$msg .= print_r($e->getTrace(),true);
@error_log($msg, 1, ‘direccion@del.destinario.com’);
} [/php]

Clase PEAR Mail_mime

Como comentaba esta es una de las clases existentes para el envío de emails con soporte de extensiones MIME, lo que permite enviar HTML con imágenes, vídeo, archivos adjuntos, etc. Este es un ejemplo sencillo de como enviar un email HTML con su versión texto y con un archivo adjunto:

[php] require_once ‘Mail.php’;
require_once ‘Mail/mime.php’;
$destinario = ‘direccion@del.destinario.com’;
$from = ‘direccion@del.from.com’;
$asunto = ‘Asunto del mensaje’;
$mensaje = ‘‘.$asunto.’‘.”\n”;
$mensaje .= ‘

Hola

‘;
$mime = new Mail_mime(“\n”);
$mime->setTXTBody(strip_tags($mensaje));
$mime->setHTMLBody($mensaje);
$mime->addAttachment(‘fichero_adjunto.zip’, ‘application/zip’);
$body = $mime->get();
$hdrs = array(‘From’ => $from, ‘Subject’ => $asunto);
$hdrs = $mime->headers($hdrs);
$mail =& Mail::factory(‘mail’);
$res = $mail->send($destinario, $hdrs, $body);
if (PEAR::isError($res)) echo ‘error enviando el email’; [/php]

Todos los métodos anteriormente descritos necesitan de un servidor de correo funcionando y las directivas de configuración del PHP correctamente fijadas. Si tienes un ISP un poco decente casi seguro q no tendrás ningún problema.

Una técnica alternativa a todos estos métodos y que no necesita de servidor de correo es usar sockets (función fsockopen()) para mandar nosotros mismos los mensajes desde nuestro código. Se trata de hacer desde PHP el trabajo q antes nos hacía el servidor. Esto, en general, no es recomendable ya q puede presentar serios problemas d rendimiento y gestión de errores (nunca funcionará mejor nuestro código PHP q un Qmail :) y la única ventaja destacable q presenta, a parte de no necesitar d un servidor d correo, es disponer de un mayor control de lo que pasa cuando se envía el email. Podemos por ejemplo saber en el momento si el servidor del destinatario del correo existe y nos acepta el mensaje, etc… Aunque con los métodos descritos y leyendo los mensajes devueltos por el servidor de correo también puedes saber si todo va bien… como consejo, si tienes un servidor de correo úsalo.

Tagged with:
preload preload preload