Posts etiquetados ‘Programación’


You can read the English version of this post in http://phpsblog.agustinvillalba.com/objects-and-references-in-memory-in-php/

Hoy vamos a hablar sobre cómo PHP crea los objetos en memoria cuando realizamos una instrucción del tipo $a = new Foo(); y sobre cómo son gestionadas las referencias en memoria, dado que este es un tema que puede generar debate y diferencia de opiniones. Para ello hablaremos de lo qué NO son las referencias en PHP. Por último, veremos cómo funciona el recolector de basura (o garbage collector) en PHP.

Objetos y referencias en PHP

Una afirmación que está muy extendida en los libros de PHP, y en la red en general, es que en PHP los objetos, por defecto, se pasan por referencia. También hay quienes dicen que los objetos en PHP se asignan por copia. Estas afirmaciones no son completamente ciertas, y para comprobarlo primero hemos de analizar qué son (y qué NO son) las referencias en PHP.

Qué NO son las referencias en PHP

Creo que más importante que saber qué son las referencias en PHP, hemos de aclarar qué NO son las referencias en PHP. En PHP las referencias no son punteros al estilo C, no podemos realizar operaciones aritméticas con las referencias como se puede hacer en C. ¿Por qué? Porque en PHP las referencias no son en realidad direcciones de memoria como en C, no son números que indican una posición de memoria. Pero entonces… ¿qué son en realidad las referencias?

Qué son las referencias en PHP

En PHP, las referencias son «alias» que permiten que 2 variables distintas puedan escribir sobre un mismo valor. O visto de otra manera, son un mecanismo que nos permiten acceder un mismo valor desde nombre de variables distintos y que se comporten como si fueran la misma variable. Hay que tener en cuenta que, en PHP, el nombre de la variable y el contenido de esa variable son 2 cosas totalmente distintas que se enlazan en lo que se llama la tabla de símbolos. De forma que cuando creamos una referencia, simplemente se está añadiendo un alias de dicha variable en la tabla de símbolos de PHP. Veámoslo con un ejemplo, supongamos que tenemos el siguiente código:

$a = new Foo();

Cuando se ejecuta la instrucción anterior, realmente lo que está sucediendo es que se crea una variable «a» en memoria, se crea un objeto de tipo Foo en memoria y se añade una entrada en la tabla de símbolos de PHP en la que se indica que la variable $a «referencia» (o se relaciona, o «apunta», o como se quiera llamar) al objeto Foo, pero NO es un puntero a dicho objeto. Si a continuación ejecutamos la instrucción:

$b = $a;

Lo que ocurre no es que se $b se convierta en una referencia de $a, tampoco se puede decir que $b sea una copia de $a. Lo que realmente ha sucedido es que se ha creado una nueva variable «b» en memoria y luego se ha añadido una nueva entrada en la tabla de símbolos indicando que la variable $b, también «referencia» al mismo objeto Foo que $a. Si a continuación ejecutamos la instrucción:

$c = &$a;

Lo que ocurre es que en memoria se habrá creado una tercera variable «c» pero NO se añade una nueva entrada en la tabla de símbolos para «c», sino que en la tabla de símbolos se indica que «c» es un alias de «a», por lo tanto se comportará de forma idéntica que esta, pero no es que «c» sea un puntero a «a» (lo que en C se conoce como punteros a punteros).
Veamos un ejemplos más completo:

<?php

class myClass {
    public $var;
		
    function __construct() {
	$this->var = 1;
    }

    function inc() { return ++$this->var; }
}

$a = new myClass(); // $a "referencia" a un objeto Foo
$b = $a; //b también referencia al mismo objeto Foo que a
//($a) == ($b) == <id> del objeto Foo, pero a y b son entradas distintas en la tabla de símbolos

echo "\$a = ";var_dump($a);
echo "\$b = ";var_dump($b);

$c = &$a; //$c es un alias de $a
//($a, $c) == <id> del objeto Foo, c es un alias de a en la tabla de símbolos
echo "\$c = ";var_dump($c);

$a = NULL;
//Se elimina la entrada en la tabla de símbolos donde se relacionaba a "$a" con el objeto Foo
//Al eliminarse esta entrada, $c también deja de estar relacionado con Foo
//A todos los efectos, Foo sigue existiendo en memoria, y sigue estando relacionado con $b
echo "\$a = ";var_dump($a);
echo "\$b = ";var_dump($b);
echo "\$c = ";var_dump($c);
echo "\$b->var: ".$b->inc();
echo "\$b->var: ".$b->inc();

$b = NULL;
//Se elimina la entrada en la tabla de símbolos donde se relacionaba a "$b" con el objeto Foo
//Ya no hay más entradas en la tabla de símbolos que se relacionen con Foo,
//Por lo que Foo ha dejado de estar referenciado y puede ser eliminado por el garbage collector

echo "\$b = ";var_dump($b);

Las salidas que produce la ejecución del script anterior son:

$a = object(myClass)#1 (1) { ["var"]=> int(1) } 
$b = object(myClass)#1 (1) { ["var"]=> int(1) } 

$c = object(myClass)#1 (1) { ["var"]=> int(1) } 
$a = NULL 
$b = object(myClass)#1 (1) { ["var"]=> int(1) } 
$c = NULL 
$b->var: 2
$b->var: 3

$b = NULL

Garbage collector en PHP

Por último, veamos cómo funciona el garbage collector (o recolector de basura) en PHP. Un objeto o una variable en PHP podrá ser eliminada de memoria por el garbage collector cuando no exista ninguna referencia a dicho objeto en la tabla de símbolos. Es decir, PHP mantiene un contador de referencias a un objeto desde el momento en que éste es creado, de forma que durante la ejecución del script PHP va incrementando y decrementando dicho contador de referencias en función de las variables que le van «apuntando». Una vez ese contador de referencias llega a 0 (es decir, nadie está relacionado con ese objeto y por lo tanto, no se está utilizando dicho objeto), PHP marca ese objeto como basura o eliminable, de forma que en la siguiente pasada del garbage collector, éste eliminará dicho objeto de memoria y esa posición de memoria será utilizable por PHP nuevamente.

De esta forma esperamos haber aclarado un poco más cómo gestiona PHP los objetos y variables en memoria y cómo se «seleccionan» los objetos que han de ser eliminados por el recolector de basura en PHP.

You can read the English version of this post in http://phpsblog.agustinvillalba.com/objects-and-references-in-memory-in-php/


You can read the English version of this post in http://phpsblog.agustinvillalba.com/javascript-difference-null-undefined/

Programando en JavaScript, seguramente todos alguna vez nos hemos encontrado en la situación de tener que ejecutar un bloque de código u otro dependiendo de si una variable es «null» o «undefined». Hoy vamos a analizar la diferencia que existe en JavaScript entre «null» y «undefined«, dado que hemos de ser muy cuidadosos a la hora de compararlos.

«undefined» en Javascript

En primer lugar, para poder hablar de null y undefined en Javascript hemos de tener claro que «undefined» es un tipo de dato, al igual que lo son el Number, String, Boolean, Object o el Array. En Javascript, a diferencia de otros lenguajes de programación con fuerte tipado, podemos tener variables de tipo «undefined». A priori puede sonar un poco extraño, pero si lo pensamos un momento, tiene sentido dado que Javascript, al ser un lenguaje débilmente tipado, nos permite declarar variables sin especificar de qué tipo serán los valores que contenga. De esa forma, Javascript considerará a la variable de un tipo de dato u otro en función de su contenido, por ejemplo:

var number1 = 123; // Tipo Number
var number2 = "123" // Tipo String
var number3;

En vista de que la variable «number3» no tiene un valor asignado, ¿de qué tipo es? Dado que todas las variables han de tener siempre un tipo, en este caso Javascript considera la variable «number3» de tipo undefined.

En resumen, en Javascript, todas aquellas variables que no han sido definidas (por lo tanto, no existen) o que han sido definidas sin asignárseles un valor, son siempre de tipo undefined.
(más…)


Después de tanto tiempo escribiendo código PHP ya es hora de revisar nuestro código y nuestra forma de programar para, a partir de ahora, hacerlo de una forma más elegante y compatible con el resto de programadores. Aquí presentamos una guía de estilos de programación para PHP 5.2 o superior. Por supuesto estas no son reglas de obligado cumplimiento, pero sí nos ayudan a estandarizar un poco la forma de programar de todos, haciendo más fácil leer código de otro programador si todos seguimos estas sencillos consejos en la medida de lo posible. Repito, estos no son más que consejos, no leyes.

Apertura y cierre del tag php

Utilizar siempre el tag de apertura completo (<?php) y nunca la versión corta (<?). También es recomendable utilizar el constructor del lenguaje echo y no su versión abreviada (<?= … ?>). Esto nos ahorrará futuros errores si en la configuración del intérprete PHP en el servidor está deshabilitada la variable short_open_tag.

El uso del tag de cierre php (?>) en un documento PHP es opcional para el intérprete de PHP. Sin embargo, si se utiliza, cualquier espacio en blanco introducido a continuación del tag de cierre de php, ya sea por el desarrollador, el cliente FTP, administrador de sistemas, etc, puede provocar una salida inesperada, errores PHP, o incluso si éste es ignorado por el servidor, una página en blanco. Por esta razón, todos los archivos PHP que únicamente contienen código PHP deben omitir el tag de cierre php y en su lugar utilizar un comentario de bloque indicando que se ha llegado al final del archivo y, si se quiere, su ubicación en el sistema de ficheros relativa a la raíz de la aplicación. Este comentario también permite señalar un archivo como completo y que no está truncado.

Correcto

<?php
        echo "Here is my code!";
/* End of file myfile.php */
/* Location: /path/to/myfile.php */

Incorrecto

<?= "Here's my code!"; ?>

Globales, Constantes y Defines

Para nombrar constantes, valores globales y valores definidos mediante la estructura define, han de utilizarse nombres con todas las letras en mayúsculas, separados por guiones bajos si contienen más de una palabra y procurar que sean nombres descriptivos y con sentido, facilitando así su lectura en el futuro, tanto para el propio desarrollador como para otros desarrolladores.

Correcto

MI_CONSTANTE
define('VALOR_FIJO',1);

Incorrecto

miConstante // Evitemos utilizar camelCase
N // Constantes de una sola letra no nos dicen nada
S_C_VER // Este nombre no es descriptivo

Nombres de clases y métodos

Los nombres de clases han de comenzar siempre con una letra en mayúsculas. Los nombres con varias palabras han de separarse con guión bajo y no utilizar el estilo camelCase. Los nombres de los métodos de la clase han de escribirse siempre en minúsculas y procurar ser autodescriptivos, es decir, dejar bastante claro cuál es la funcionalidad del método, preferiblemente incluyendo un verbo. Por supuesto, los nombres de métodos de clase también han de utilizar guiones bajos para separar las palabras que lo componen. Hemos de evitar utilizar nombres de métodos excesivamente largos o con palabras redundantes.

Los nombres de métodos que únicamente son accedidos internamente por nuestra clase (métodos privados) deben ir precedidos por un guión bajo.

Los constructores de clase han de utilizar el estilo PHP5 (public function __constructor()) y no utilizar el estilo de PHP4, es decir, utilizar el nombre de la clase como constructor. Hemos de utilizar destructores de clase cuando sea apropiado.

Se recomienda declarar explícitamente la visibilidad de variables miembro de clase así como de los métodos.

Correcto

class Super_class
public function get_file_properties() //descriptivo, separado por guiones bajos, todas las letras en minúsculas y visibilidad declarada
private function _parse_string() //Igual que los métodos públicos pero precedido por guión bajo

Incorrecto

class superclass
class SuperClass
function fileproperties() // no descriptiva y sin guiones bajos
function get_the_file_properties_from_the_file() // demasiado larga y con palabras redundantes

Nombres de variables

Los estilos usados para los nombres de variables son muy similares a los utilizados para los métodos y miembros de clases. Las variables únicamente han de contener letras en minúsculas, separadas por guiones bajos y procurar ser autodescriptivas, es decir, tener un nombre que permita conocer cuál es la funcionalidad de dicha variable. Las variables con un nombre muy corto o con nombres que no sean palabras han de reservarse exclusivamente para los bucles for().

Correcto

for($j = 0; $j < 10; $j++)
$buffer
$group_id
$last_city

Incorrecto

$j = 'This a string'; // Variables de una sola letra han de reservarse para bucles for
$Str // no utilizar letras mayusculas en variables
$name_of_the_last_city // demasiado largo con palabras innecesarias

True, False y Null

Las palabras claves TRUE, FALSE y NULL han de escribirse siempre con todas sus letras en mayúsculas, dado que al ser valores propios de PHP se pueden considerar constantes, y por lo tanto, escribirse como tales.

Correcto

if (TRUE == $foo)
$bar = FALSE;
function foo( $bar = NULL)

Incorrecto

if( $foo == true)
$bar = false;

Estructuras de control

Con esto nos referimos a las estructuras if, for, while, switch, etc. Las estructuras de control han de tener un espacio en blanco entre la palabra clave de control y la apertura del paréntesis, para distinguirlo así de las llamadas a funciones.

Se recomienda utilizar siempre los abre y cierra llaves, incluso en situaciones donde son técnicamente opcionales. Si los ponemos aunque no sean necesarios, aumentamos la legibilidad del código y reducimos el riesgo de errores lógicos cuando queremos añadir nuevas líneas al bloque de control.

Se recomienda colocar el abre llaves del bloque a ejecutar en una línea nueva tras las condiciones a cumplir, delimitando así claramente cada bloque a ejecutar.

Correcto

if ((condicion1) || (condicion2))
{
    accion1;
}

Separar largas condiciones if en varias lineas

Las condiciones de bloques if se pueden separar en varias líneas si se excede el número límite de caracteres por línea. Las condiciones tiene que ser colocadas en una nueva línea e indentadas 4 caracteres. Los operadores lógicos (&&, ||, etc) deben colocarse al comienzo de cada nueva línea, facilitando así el comentar (y excluir) dicha condición. El cierre del paréntesis y de la llave han de colocarse en una nueva línea al final de las condiciones.

El colocar los operadores al comienzo de cada nueva línea tiene 2 ventajas:

  1. Es extremadamente fácil comentar y exlcuir una condición durante el desarrollo y prueba del código manteniendo bloque sintácticamente correcto.
  2. Revisar cada una de las condiciones es muy sencillo dado que todas están alineadas una debajo de otra.

Correcto

if (($condition1)
    || ($condition2)
    || ($condition3)
) {
    accion1
}

Comparación de variables y literales

Cuando se hacen comparaciones lógicas, ha de colocarse siempre la variable en el lado derecho del comparador. De esta forma, si olvidamos un signo de igual (=) en el comparador se lanzará un error en el intérprete de PHP en lugar de asignar el literal a la variable y que se cumpla como verdadera la asignación, procediendo a ejecutar el contenido del bloque. Realmente no cuesta nada hacerlo así y nos ahorraremos muchos dolores de cabeza de depuración de errores.

Correcto

if ('rock' == $music)
if (NULL == $name)

Incorrecto

if ($music == 'rock') // corremos el riesgo de hacer if ($music = 'rock')

Arrays

La asignación de los valores de un array han de estar alineadas cuando es necesario separarla en varias líneas. Así mismo, cada nueva línea ha de comenzar con una coma (,) separando este nuevo valor del anterior. Esto nos permite comentar dicha línea (y evitar la inclusión de ese par clave/valor) y mantener el bloque del array sintácticamente correcto. El cierre del paréntesis ha colocarse también en una nueva línea al final del array.

Correcto

$un_array = array (
    'foo'   => 'bar'
    ,'spam' => 'ham'
    ,'you'  => 'me'
);

Con esta guía simplemente pretendemos ayudarles a darle un formato más homogéneo a tu código PHP y facilitar la compartición y lectura de código entre varios programadores PHP. Por supuesto, los estilos son como los colores, cuestión de gustos, pero al menos sobre estilos de programación sí hay algo escrito.


Hoy escribo para comunicar que, después de bastante tiempo, por fin está terminado y funcionando mi nuevo portfolio en http://www.agustinvillalba.com. Allí pueden encontrar información acerca de mí y algunos de los trabajos que he realizado hasta ahora.

Espero que les guste y espero aquí sus comentarios y/o sugerencias sobre la web si lo desean!


You can read the English version of this post in http://phpsblog.agustinvillalba.com/parallelize-processes-php/

Hoy vamos a explicar cómo poder lanzar múltiples hilos en nuestros scripts PHP, pudiendo así paralelizar aquellos procesos que tengan una gran carga de procesador o que simplemente puedan lanzarse en paralelo dado que no tienen dependencias entre ellos y todos resuelven de forma parcial un problema común.

¿Por qué paralelizar procesos?

Cuando se programa un algoritmo, según el lenguaje en el que lo hagamos, podemos resolver las partes del algoritmo de forma secuencial o paralela. Si tenemos una parte del algoritmo que tiene una gran carga y requiere mucho tiempo para su resolución, podríamos ir resolviendo las demás partes mientras se resuelve la parte más lenta. De forma que el tiempo total de ejecución de nuestro algoritmo pasa de ser la suma de las partes a solamente la parte más lenta. Es cierto que la paralelización realmente se aprovecha cuando disponemos de recursos redundados, por ejemplo procesadores, pero en la gran mayoría de los servidores actuales disponemos de varios núcleos, por lo que tiene bastante utilidad aprender a paralelizar nuestros procesos.

La base teórica de la paralelización nos dice que cuando proceso padre lanza un proceso hijo, se crea en memoria un proceso idéntico al padre, con un identificador de proceso (pid) propio (diferente al del padre) y ejecutándose a partir de la instrucción siguiente a la que creó al propio proceso hijo.

Lanzando multiples hilos en PHP

Antes que nada hemos de tener en cuenta que para poder paralelizar procesos en PHP necesitamos tener instalada la extensión de control de procesos (Process Control Extension [http://www.php.net/manual/en/refs.fileprocess.process.php] en inglés). Dentro de esta extensión, los módulos que nos permitirán paralelizar nuestros procesos son el propio de Control de Procesos (PHP PCNTL [http://www.php.net/manual/en/book.pcntl.php] en inglés) y el de memoria compartida entre procesos (PHP Shared Memory [http://www.php.net/manual/en/book.shmop.php] en inglés). Para poder explicar la paralelización de procesos vamos a poner un ejemplo (bastante simple) en el que un proceso (padre) lanzará 10 hilos en paralelo (hijos) los cuales generarán un número aleatorio, colocarán en una zona de memoria compartida con su padre, éste recogerá cada número generado por sus hijos y devolverá la suma de todos ellos.

Veamos el código:

<?php
function multiple_forks()
{
    $array_pids = array();
    $sumatorio = 0;
    //Almacenamos el process id del proceso padre
    $parent_pid = getmypid();
    for($i=0;$i<10;$i++)
    {
        if(getmypid() == $parent_pid)
        {//Estamos en el proceso padre, asi que lanzamos el proceso hijo y guardamos si pid
            $array_pids[] = pcntl_fork(); //pcntl_fork nos permite lanzar un proceso hijo en paralelo
        }
    }

    //Una vez hemos lanzado los 10 hijos pasamos a generar los números aleatorios (en los hijos)
    //o ir sumandolos si estamos en el padre
    if(getmypid() == $parent_pid)
    {//Estamos en el proceso padre
        while(count($array_pids) > 0)
        {//Mientras queden hijos en ejecución, quedamos a la espera de que terminen
            $pid = pcntl_waitpid(-1,$status);
            //Abrimos la memoria compartida con nuestro hijo $pid
            $shared_id = shmop_open($pid,"a",0,0);
            $share_data = shmop_read($shared_id,0,shmop_size($shared_id));
            $sumatorio += $share_data;
            //Marcamos el bloque para que sea eliminado y lo cerramos
            shmop_delete($shared_id);
            shmop_close($shared_id);
            //Eliminamos el proceso de la cola de hijos en ejecucion
            foreach($array_pids as $key => $hijo)
            {
                if($pid == $hijo) unset($array_pids[$key]);
            }
        }
    }
    else
    {//Estamos en el hijo
        $num = rand(0,100);
        $shared_id = shmop_open(getmypid(),"c",0644,strlen($num));
        if(!$shared_id)
        {//No se pudo crear la memoria compartida
            echo "Error al crear la memoria compartida en el hijo ".getmypid()."\n";
        }
        else
        {
            if(strlen($num) != shmop_write($shared_id,$num,0))
            {
                echo "Error al intentar escribir el numero $num en el hijo ".getmypid()."\n";
            }
            else
            {
                shmop_close($shared_id);
            }
         }
         //Salimos indicando al padre que todo ha ido bien
         exit(0);
    }
    return $sumatorio;
}
?>

Muy probablemente el código se pueda optimizar aun más, pero no es el objetivo de este artículo. Veamos las funciones de control de procesos y memoria compartida que hemos utilizado en el código:

  • pcntl_fork. Nos permite lanzar hijos de un proceso padre, devolviendo el pid del hijo lanzado. (pcntl_fork en PHP)
  • pcntl_waitpid. Nos permite poner al padre en espera de que un hijo suyo termine su ejecución. El parámetro -1 indica que queda a la espera de que algún hijo termine, el primero que lo haga. (pcntl_waitpid en PHP).
  • shmop_open. Nos permite crear o abrir un bloque de memoria. El primer parámetro es a modo de identificador, nada mejor que usar el pid del hijo como identificador, así el padre podrá conocer el identificador con el que se creó dicho bloque de memoria y acceder a los datos compartidos. (shmop_open en PHP)
  • shmop_read. Nos permite leer un bloque de memoria compartida. (shmop_read en PHP)
  • shmop_delete. Marca el bloque de memoria para ser liberado. El bloque será liberado automáticamente por el sistema cuando todos los procesos concurrentes asociados con el bloque se desvinculen del bloque. (shmop_delete en PHP)
  • shmop_close. Cierra un bloque de memoria, indicandole al sistema que el proceso se desvincula del bloque. (shmop_close en PHP)
  • shmop_size. Nos permite conocer el tamaño que ocupa un bloque de memoria compartida. (shmop_size en PHP)
  • shmop_write. Nos permite escribir datos en un bloque de memoria compartida. (shmop_write en PHP)

Con esto tenemos la base necesaria para poder crear procesos paralelos en nuestros controladores y lanzar así tantos hilos como procesadores dispongamos en nuestro servidor.

You can read the English version of this post in http://phpsblog.agustinvillalba.com/parallelize-processes-php/


Hoy vamos a hablar de los Microformats, un conjunto de «buenas costumbres» apliamente aceptadas y extendidas y que posiblemente acaben convirtiéndose en un estándar en Internet, que nos permiten remarcar datos de contacto, eventos de calendario, etc, entendible por humanos y robots de búsquedas.

¿Qué son los Microformats?

Los Microformats son un conjunto de formatos, simple y apliamente aceptados, construido sobre las normas existentes de HTML. En lugar de deshechar aquello que hoy en día funciona y está firmemente implantado, los Microformats intentan solucionar problemas nuevos utilizando las herramientas existentes.

Los Microformats NO SON un nuevo lenguaje de programación web. Simplemente añaden una nueva funcionalidad al lenguaje existente utilizando sus propiedades.

¿Para qué sirven los Microformats?

Los Microformats nos permiten remarcar o destacar dentro del contenido de nuestra web aquellos datos de contacto, eventos de calendario o descripciones de productos de forma sencilla, no intrusiva para el usuario que lee la información y muy clara para los robots de buscadores como Google, el cual lo reconoce a la perfección en incluso premia en su cálculo de PageRank a aquellos sitios que los utilizan adecuadamente.

Ejemplos de Microformats

Datos de contacto

Para los datos de contactos podemos crear un div con la clase «vcard», el cual contendrá todos los datos personales que queramos mostrar. Una tarjeta de contacto tipo hCard podría ser algo así:

<div id="hcard-Juan-López" class="vcard">
 <span class="fn">Juan López</span>
 <div class="org">Google Corp.</div>
 <a class="email" href="mailto:jlopez@server.com">jlopez@server.com</a>
 <div class="adr">
  <div class="street-address">Main St.</div>
  <span class="locality">Palo Alto</span>, 
  <span class="region">California</span>, 
  <span class="postal-code">CA1234</span>
  <span class="country-name">Estados Unidos</span>
 </div>
 <div class="tel">123456789</div>
</div>

Podemos observar que todo se basa en añadir clases a los distintos elementos del documento. Por ejemplo:

  • vcard. Para indicar que definiremos un bloque de datos personales.
  • fn (full name). Para destacar el nombre completo del contacto.
  • org. Para destacar la organización en la que trabaja.
  • Puedes encontrar más documentación sobre vcard en hCard 1.0

Eventos de calendario

Para los datos de un evento podemos crear un div con la clase «vevent», el cual contendrá todos los datos del evento de calendario que queramos mostrar. Una evento de calendario tipo hCalendar podría ser algo así:

<div id="hcalendar-Reunion-con-cliente" class="vevent">
<abbr class="dtstart" title="2011-05-24T10:00Z00">May 24, 2011  10</abbr> – 
<abbr class="dtend" title="2011-05-24T13:00Z">1pm</abbr>:  
<span class="summary">Reunion con cliente</span> at <span class="location">Sala de reuniones</span>
<div class="description">Reunión con nuestro mejor cliente</div>
</div>

En este caso, utilizamos otras clases diferentes para remarcar los datos del evento. Por ejemplo:

  • vevent. Para indicar que vamos a comenzar un bloque de datos relativos a un evento de calendario.
  • dtstart o dtend. Para indicar la fecha y hora de inicio y fin del evento.
  • Puedes encontrar más información sobre vevent en hCalendar 1.0

A tener en cuenta…

  • Los principales sitios de referencia en Internet como Facebook, Twitter o Google hacen uso de Microformats para especificar datos de contacto o eventos.
  • Los principales buscadores de Internet reconocen los microformats a la hora de indexar páginas que los contengan.
  • Para más información sobre Microformats puedes visitar microformats.org

You can read the English version of this post in http://phpsblog.agustinvillalba.com/javascript-css-minified-carabiner-codeigniter/

Hoy vamos a hablar de una potente librería disponible para el framework CodeIgniter, es: Carabiner. Esta librería nos permite incluir de forma específica para cada vista de nuestro sitio los archivos JavaScript y CSS que son necesarios, ahorrándonos tener que incluirlos todos, y además, los envía al usuario en un único archivo «.js» y «.css» con todos los que hemos ido incluyendo pero minimizados, con lo que el tamaño del «.js» y «.css» que se envía al usuario es mucho menor, con la consiguiente mejora de tiempo de carga del sitio que ello implica.

Instalando Carabiner en nuestro proyecto

Lo primero para instalar Carabiner en nuestro proyecto es descargarlo, podemos hacerlo desde su hilo en el foro de CodeIgniter. Para instalarlo simplemente hemos de colocar los archivos carabiner.php, cssmin.php y jsmin.php en el directorio /application/libraries de nuestro proyecto. Una vez hecho esto, hemos de colocar el archivo de configuración carabiner.php en el directorio application/config. En este archivo hemos de especificar la ruta de los directorios que contendrán nuestros archivos «.js» y «.css».
(más…)


You can read the English version of this post in http://phpsblog.agustinvillalba.com/upload-progress-bar-in-codeigniter-without-flash/

Hoy vamos a ver cómo podemos crearnos una barra de progreso de subida de archivos en CodeIgniter sin la necesidad de recurrir a librerías o plug-ins hechos en Flash (del tipo SWFUpload, etc) que escapan a nuestro control, dado que habitualmente estas librerías nos ofrecen los archivos .swf ya compilados, por lo que nos es imposible modificar nada en ellos, en el caso de que tengamos conocimientos de programación en ActionScript 2 o 3.

Antes que nada hemos de decir que crear una barra de progreso de subida de archivos en PHP no es tan sencillo como pudiera parecer. El primer problema es que las versiones de PHP anteriores a la 5.2 no ofrecen las herramientas necesarias para poder ofrecer información sobre cómo la subida del archivo en cada momento. El segundo problema es que AJAX, por sí solo, no nos permite consultar el estado de la subida del archivo, dado que, por razones de seguridad obvias, JavaScript no tiene acceso a los archivos del sistema operativo del cliente, por lo que necesitaremos un «truco» utilizando un iframe.

(más…)


You can read the English version of this post in http://phpsblog.agustinvillalba.com/scrollto-jquery-plug-in-css/

Hoy vamos a hablar un poco del plug-in para jQuery scrollTo y su dependencia «oculta» con la carga de nuestros archivos CSS.

scrollTo de jQuery

El plug-in scrollTo de jQuery (desarrollado por Ariel Flesler) nos permite que nuestra página web realice un scroll (desplazamiento de la barra vertical) hasta cualquier elemento de nuestro documento web que necesitemos, de esta forma podemos centrar la atención del usuario en dicho elemento cada vez que se recarga la página (por ejemplo, una entrada del menú de la izquierda en nuestra web), evitándole al usuario tener que hacerlo él manualmente. En la web del proyecto del plug-in podrás encontrar toda (o casi toda) la documentación necesaria para integrarlo en tu proyecto web. De más está decir que para poder utilizarlo has de incluir también en tu proyecto el propio framework JavaScript jQuery. A este plug-in que tan útil me ha sido sólo le encontré un pequeño fallo de documentación…
(más…)


You can read the English version of this post in http://phpsblog.agustinvillalba.com/swfupload-codeigniter/

En esta entrada vamos a explicar un poco qué es y cómo podemos utilizar la librería SWFUpload en nuestra aplicación hecha con el framework php CodeIgniter para que nuestros usuarios puedan subir sus archivos a la aplicación de una forma elegante y muy visual, y todo ello combinado con la seguridad y facilidad que nos ofrece CodeIgniter para la subida de archivos al servidor.

Qué es SWFUpload

SWFUpload es una librería que permite a los usuarios de nuestro sitio subir archivos al servidor, mediante la combinación de Flash y JavaScript. Aquí pueden ver unos ejemplos de uso de la librería.

Integrando SWFUpload en CodeIgniter

Lo primero que necesitamos para integrar la librería es, lógicamente, descargarla. Necesitaremos descargarnos el archivo de «core» y los «samples». Una vez la tenemos descargada y descomprimida, crearemos una carpeta en el directorio raíz de nuestra aplicación CodeIgniter llamada swf/, y dentro de esta a su vez crearemos otra llamada swfupload/, de tal forma que la ruta a nuestra librería SWFUpload es /swf/swfupload/. En este último directorio colocaremos los archivos «swfupload.swf» y «swfupload_fp9.swf» (este último para los usuarios con Flash Player 9) que encontraremos en la carpeta del «core». Bien con esto tenemos los swfs en su sitio.
(más…)