Concurrencia, bloqueo de código y semáforos en php

PHP

En ciertas ocasiones necesitamos que una parte de nuestro código se ejecute por solo un usuario a la vez.
Estos bloqueos de código los utilizamos para evitar problemas de concurrencia.
En php es posible implementar estos bloqueos mediante semáforos. (Ver semáforos en el manual de php)

El problema es que no siempre nuestro hosting viene con una versión estilo System V (–enable-sysvsem) compilada de php.

Si esto es así, podemos resolver el problema ejecutando el siguiente código:

if ( !function_exists('sem_get') ) {
    function sem_get($key) { return fopen(__FILE__.'.sem.'.$key, 'w+'); }
    function sem_acquire($sem_id) { return flock($sem_id, LOCK_EX); }
    function sem_release($sem_id) { return flock($sem_id, LOCK_UN); }
}

Con esto, ahora ya podemos usar las funciones de php para semáforos (sem_get(), sem_acquire(), sem_release())

Aquí os dejamos un ejemplo práctico de cómo usar los semáforos para obtener el siguiente número de pedido disponible y actualizar el pedido actual:

$sem_key = 12;
$sem_id = sem_get($sem_key, 1);
if (! sem_acquire($sem_id)) die ('Error esperando al semaforo.');


$ref = $model->getNextPedidoReference();
$pedido->referencia = $ref;
if (!$model->Update($pedido)){
    handle_error("Error guardando el pedido");
    return;
}


if (! sem_release($sem_id)) die ('Error liberando el semaforo');

De esta forma ya podemos estar seguros de que no se podrá dar el caso de que dos usuarios obtengan el siguiente número de pedido disponible a la vez y acabes teniendo dos pedidos con la misma referencia.

Happy coding!

Sustituir función eregi por preg_match

PHP

La funcion ‘eregi‘ está obsoleta desde PHP 5.3.

Ahora debemos usar la función ‘preg_match‘ que es compatible con ‘Perl‘.

Para la sustitución, tenemos que tener en cuanta lo siguiente:

1. Es necesario añadir delimitadores a la expresión regular.
2. Algunas expresiones las tendremos que cambiar por sus equivalentes en PCRE (Perl Compatible Regular Expressions).
3. La ‘i’ de ‘eregi’ viene de case-insensitive, que en PCRE equivale a usar el flag ‘i’.

Sabiendo esto, vamos a un caso práctico:

Utilizando Joomla 1.5 con el editor JCE, nos podemos encontrar con el siguiente error:

Deprecated: Function eregi() is deprecated in XXX\plugins\editors\jce\libraries\classes\editor.php on line 236

En este caso, solo tenemos que ir a la línea en cuestión, y cambiar el código:

if( eregi( $key, $param ) ){

Por

if( preg_match( '/'.$key.'/i', $param ) ){

Esperamos que os sea de ayuda.

Problemas en la salida cuando usamos include en php

PHP

Para volverse loco!
Resulta que realizando un código en php muy sencillo, veía que el código generado no se visualizaba correctamente.
Se creaban unos espacios extraños, y viendo el código fuente de forma normal y viéndolo con el Firebug, veía que no se correspondía.

El código fuente parecía estar bien, pero en el firebug las cosas me salían de una forma muy extraña, por ejemplo, algunas referencias a css y js del head, me las ponía debajo de body.

Un auténtico misterio.

A base de ir comentando a trozos el código para detectar donde estaba el problema, me di cuenta de que el error estaba cuando utilizaba la función ‘include’.

Después de utilizar include, include_once, require, require_once, con comillas dobles, con comillas simples, con paréntesis… al final, leyendo los comentarios del include de php.net, vi que un usuario comentaba que había un ‘security flaw’ y que para solucionarlo, usaba los métodos ‘ob_start()’ y ‘ob_end_clean()’ antes y después de hacer los includes.

Con la mayor parte del código comentado, al poner estas funciones, el problema parecía haberse solucionado… pero en cuanto descomenté el resto… otra vez la cosa estaba mal.

Después de muchas pruebas, frustraciones, y búsquedas en google, di con esta página: http://bugs.php.net/bug.php?id=40072

Ahí estaba la solución! El puto BOM del utf-8!! (con perdón)

Había probado el tema de la codificación de los archivos, pero no se me había ocurrido usar la codificación “utf-8 sin BOM”.

Lo peor de todo, es que entonces recordé… que esto ya me había pasado antes!!

Ayyyy… que malo es el Alzeimer…

Pues nada.
Espero que si algún día os pasa algo así, encontréis este post y os ayude a resolver rápidamente el problema.

Recordar que en notepad++ en español tenemos las opciones “utf-8” y “utf-8 sin BOM” pero que en otros editores o versiones podemos encontrarnos con “utf-8” y “utf-8 with signature”. En este último caso, habría que utilizar el “utf-8”.

Para los que tengáis la curiosidad de saber que es el BOM, que sepáis que es el ‘Byte Order Mark’ y podéis leer más en la wikipedia.

Problemas al enviar boletines con Acymailing

Joomla/PHP

Hoy me he encontrado con un problema un tanto extraño con el componente de envíos de boletines de joomla Acymailing. La cuestión es que al enviar un email de prueba me devolvió el siguiente error:

could not instantiate mail function

He probado a enviar un correo masivo desde herramientas de joomla y este si que se enviaba, por lo que la función mail de PHP funcionaba correctamente (¿porque no lo iba a hacer?).

Buscando por google he dado con la solución en el foro de los desarrolladores de este componente (aquí). Hay una opción en la zona de configuración. En la primera pestaña, la última opción de información del Remitente pone Agregar Nombres. Por defecto está marcado que sí. Le pones No y se soluciona el problema.

Debe ser un Bug del componente y quizá habría que depurarlo, ¿quién se anima? Si sabéis para que sirve esa opción seria de ayuda.