Steve Jobs

Aunque en este blog no he tratado muchos temas fuera del código y el desarrollo web quería hacer una pequeña mención a un gran personaje del cambio de milenio. Steve Jobs.

Después de varios años sufriendo cáncer de páncreas y de retirarse como CEO de Apple hace poco más de un mes, Jobs deja este mundo dejando un gran legado tecnologico. Su muerte ha recorrido el mundo entero y muchas personalidades de distintos ámbitos han querido honrar su memoria de alguna forma. Entre los más destacados se encuentran Barack Obama, Bill Gates, Steven Spielberg o Mark Zuckerberg.

Todas las declaraciones se despiden de él como una de las personas que han cambiado el mundo, a mejor. Lo que está claro es que su pasión por hacer bien las cosas, por llegar a donde los demás no han llegado, sus ganas de superación y la búsqueda de la perfección, le ha hecho brillar y prácticamente convertir en oro todo lo que tocaba.

La noticia saltó a la luz en la página principal de Apple, el espacio que siempre han dedicado a enseñar sus nuevos productos, donde los fieles de Apple descubrieron el iPod, el iPhone o el iPad sin olvidar a los portátiles u ordenadores de sobremesa. En ese espacio ponían su peor anuncio. He hecho una captura para la posteridad.

Aunque es posible que no haya blogger que no haga hoy una referencia a este acontecimiento, no quería dejar de hacerlo. Para mí es un antes y un después en la tecnología.

Sit tibi terra levis

Convertir caracteres especiales a entidades de HTML en PHP

El lenguaje HTML, dependiendo la codificación que usemos, no permite usar caracteres látinos como los que se muestran en esta tabla.

Carácter Entidad HTML Carácter Entidad HTML
á á Á Á
é é É É
í í Í Í
ó ó Ó Ó
ú ú Ú Ú
ü ü Ü Ü
ñ ñ Ñ Ñ
¡ ¡ ¿ ¿

En ocasiones no podemos asegurar que codificación se va a usar donde esté contenido el texto como en algunos CMS o al maquetar emails, por lo que se decide convertir estos caracteres a las entidades especiales que les corresponde.

Para hacerlo de forma automática en PHP usaremos la función htmlentities, esta función convierte a entidades especiales HTML los caracteres latinos. Si lo que queremos es crear un formulario para copiar este texto transformado sin mirar el código fuente podemos hacer una doble llamada a la función:

PHP:
  1. $text = 'El veloz murciélago hindú comía feliz cardillo y kiwi';
  2. $result = htmlentities(htmlentities($text));
  3.  
  4. // $result = 'El veloz murciélago hindú comía feliz cardillo y kiwi';

Rendimiento de los scripts PHP

¿Qué se ejecuta más rápido? ¿una sentencia de if anidados o un switch? ¿es mejor usar comillas simples o dobles para trabajar con cadenas? ¿foreach, for o while? Estas preguntas nos las hemos podido hacer, o no, alguna vez trabajando con PHP. Y la respuesta es que si hay diferencias entre usar un código u otro. Muy posiblemente si trabajamos con sites pequeños no notaremos diferencia, pero cuando se trabaja a mayor escala el ahorro en el rendimiento pasa a ser fundamental.

En la página www.phpbench.com hicieron distintas pruebas y sacaron conclusiones de qué instrucciones son más rápidas o tienen un mejor rendimiento al ejecutarse. La instrucción es la misma, pero la ejecución es más óptima.

Estas son algunas conclusiones que ya comentaron en otros blogs como sentidoweb.com:

  • Realizar un foreach es siempre más rápido, y si no recuperamos la clave del array mejor aún.
  • Un for es más rápido si no calculamos previamente en una variable el tamaño del array que recorremos, y que sizeof es más rapido que count.
  • Cuando vamos a asignar el valor de una posición de un array a una variable para tratar con ella, es conveniente hacerlo por referencia ($alias = &$aSingleDimArray[$i]).
  • No es más rápido crear un objeto como referencia ($obj =& new SomeClass();).
  • if es más rápido que switch/case, y ligeramente más rápido es usar == que ===.
  • Parece ser que el uso de comilla simple o doble en las últimas versiones se ha mejorado y no existe apenas diferencia.

Si quieres hacer tus propias pruebas con tu código puedes crear una pequeña clase para hacer el cálculo, como encontré en kickbill.com:

PHP:
  1. class benchmark{
  2.  
  3. private $start;
  4. private $end;
  5.  
  6. function __construct(){
  7. $this->start= microtime(true);
  8. }
  9.  
  10. function endBenchmark(){
  11. $this->end= microtime(true);
  12. }
  13.  
  14. function getBenchmark(){
  15. $time = ($this->end$this->start);
  16. return $time;
  17. }
  18. }
  19.  
  20. /**************************
  21. ** Código para la prueba **
  22. ***************************/
  23.  
  24. $test= new benchmark;
  25.  
  26. // tu código aquí
  27. usleep(2000000);
  28.  
  29. $test->endBenchmark();
  30.  
  31. echo \”Tiempo de la prueba: \”.$test->getBenchmark();

Mejorar la carga de imágenes con CSS y sprites

Los diseños de nuestras páginas suelen acompañar a los textos una pequeña imagen o nuestros menús requieren que los items sean una imagen y que al hacer roll-over una  cambie por otra u otras funcionalidades. Al maquetar podemos hacer que cada item tenga una imagen asociada, esto hace que durante unos segundos el hueco del menú quede vacío durante el roll-over, esto ocurre porque las imágenes están separadas en distintas imágenes y cada una significa una carga independiente del resto, esto afecta a que la experiencia de usuario no sea la deseada y que el servidor sufra más llamadas innecesarias.

Para solucionar estos problemas se usan los sprites en css. Los sprites son simplemente imágenes de gran tamaño que contienen imágenes más pequeñas. Este concepto viene de los antiguos videojuegos, donde los personajes se movían gracias a estas imágenes, en la imagen se contenía al personaje en todas sus posiciones, luego, mediante código hacemos que esas imágenes parezcan movimiento. Pongo un ejemplo de como es el sprite con los movimientos de Super Mario 3.

Con este concepto vamos a ver como llevarlo a web. Lo que hacemos es crear una imagen con los distintos iconos que tendrá la web o con cada item del menú y su respectivo roll-over, en el siguiente ejemplo tenemos 4 items de menú el lado derecho corresponde al item en reposo y el lado izquierdo representa a cada item activado:

De esta forma hacemos que el servidor entregue una sóla imagen y nuestro visitante también, lo único que tendremos que hacer es cambiar la posición de fondo de la imagen para que se vea cada item donde debe.

También podemos usar los sprites para todos los iconos o bullets que encontramos en la web. En la página de youtube.com, usan la siguiente imagen que contiene a las imágenes que se usan como iconos o fondos en la web:

En este ejemplo, todos los items que van a usar una de esas imágenes de fondo tienen por css la orden de que su imagen de fondo sea esta. En el ejemplo que os voy a poner queremos que todos los vínculos tengan una imagen de fondo.

CSS:
  1. a {
  2. background:url(gran-imagen-fondo.gif) no-repeat;
  3. padding: 0 0 0 15px;
  4. }

Así todos nuestros vínculos van a tener la misma imagen de fondo y un hueco a su izquierda para que la imagen se vea sin que el texto aparezca encima, también dejamos una posición genérica para los vínculos. Ahora vamos a diferenciar entre vínculos.

CSS:
  1. a.media {
  2. background-position: 0 25px;
  3. }

Con esto lo que queremos ahora es que los vínculos que sean de media muestren de la imagen de fondo que les hemos dado la que está a 0px de la izquierda y 25px del top de la imagen. A continuación un ejemplo mejor desarrollado:

Código

HTML:
  1. <div id="contenedor_menu">
  2.     <li class="item1"><a href="#">Item 1</a></li>
  3.     <li class="item2"><a href="#">Item 2</a></li>
  4.     <li class="item3"><a href="#">Item 3</a></li>
  5.     <li class="item4"><a href="#">Item 4</a></li>
  6. </ul>
  7. </div>

CSS:
  1. #contenedor_menu{float:left;width:178px;}
  2. ul li{width:178px;height:78px;float:left;}
  3. ul li a{
  4.     background:url("http://morenogil.com/victor/wp-content/ejemplosprite.jpg") no-repeat scroll 0 0 transparent;
  5.     display: block;
  6.     float: left;
  7.     height: 56px;
  8.     text-indent: -9999px;
  9.     width: 180px;}
  10. ul li.item1 a{background-position:0 0;}
  11. ul li.item1 a:hover{background-position:-183px 0;}
  12. ul li.item2 a{background-position:0 -58px;}
  13. ul li.item2 a:hover{background-position:-183px -58px;}
  14. ul li.item3 a{background-position:0 -124px;}
  15. ul li.item3 a:hover{background-position:-183px -124px;}
  16. ul li.item4 a{background-position:0 -176px;}
  17. ul li.item4 a:hover{background-position:-183px -176px;}

En funcionamiento:

Firefox 3.5 el más usado según StatCounter

StatCounter, uno de los sistemas de medición de visitas más conocidos permite ver estadísticas globales. Filtrando la búsqueda por versión de navegador usado y las estadísticas de este año, podemos ver que la versión 3.5 de Firefox ha empezado a encabezar la lista de los navegadores más usados:

Source: StatCounter Global Stats - Browser Version Market Share

Como podemos observar IE7, que tenía un gran monopolio en este listado, ha tenido una grave caída y que IE8 está experimentando un muy buen ascenso igualándose casi con Firefox 3.5. IE6, pese a sus malísimas características, tiene un descenso constante pero muy lento (cuándo conseguiremos quitárnoslo de en medio?), curiosamente entre el 11 y 17 de mayo tiene un pico de popularidad que Firefox 3.0 sintió.

Si cambiamos la vista a la de barras podemos ver que Safari y Chrome están en plena pelea que aún gana Safari, aunque de esto no le queda mucho al navegador de Apple, ya se dice que la pelea la está ganando ahora Chrome, podemos comprobarlo cambiando las fechas en el filtro, este nuevo año el navegador de Google le saca un 2% a Safari.

Visto en: alt1040

Google goggles, una imágen vale más que mil palabras

Google no deja de sorprendernos, ha lanzado una nueva aplicación para su sistema operativo Android con la que con hacer una simple fotografía puedas obtener muchas más información.

¿Queires buscar la dirección de una tarjeta y no quieres escribirla? hazle una foto, la aplicación obtendrá la info, te hará una búsqueda en Google de la dirección, separará el email, los teléfonos y te dará el link a Google Maps. Y si quieres podrás añadir este como un nuevo contacto :D

goggles_contact

¿Un amigo tiene un libro que quieres saber donde comprarlo? ¿Quieres más info de un edificio o un monumento? ¿Quieres saber a que empresa le pertenece ese logo? Haz una foto la aplicación hará el resto :)

Visita el sitio de Google Goggles.

Puedes conseguir la aplicación para tu Android en el Market, la aplicación funciona a partir de la versión 1.6 (Donut o Eclair).

Estilo de inputs basados en su tipo con CSS

Muchas veces cuando le doy estilo a un formulario utilizo la etiqueta input para dar un estilo general a todos los elementos del formulario, pero estos elementos comprenden todos los input, incluso el botón de submit o los checkbox o radiobutton.

CSS:
  1. input{width:100px;background:#ccc;border:#000 solid 1px;}

Para evitar darle un borde, por ejemplo, a los radiobutton daremos el estilo de otra forma (en IE6 esta selección de elementos no es válida):

CSS:
  1. input[type="text"],
  2. input[type="password"],
  3. input[type="submit"]{width:100px;background:#ccc;border:#000 solid 1px;}
  4.  
  5. input[type="submit"]{width:200px !important;}

De esta forma podemos definir que estilo dar a cada tipo de input y nos ahorramos poner clases que definan las CSS de cada elemento en el HTML. Hay que tener presente el detalle de que al dar el estilo sólo a las cajas de texto y definamos input[type="text"] tenemos que dar el mismo estilo a los input tipo password (input[type="password"]), ya que también son cajas de texto. También podríamos aprovechar a dar el estilo a los textareas (recuerda que es uno de los elementos que no heredan, por ejemplo el font-family ;) ).

Modificando las cabeceras HTTP con PHP

Algunos ejemplos de uso para la función header():

PHP:
  1. // Use this header instruction to fix 404 headers
  2. // produced by url rewriting...
  3. header('HTTP/1.1 200 OK');
  4.  
  5. // Page was not found:
  6. header('HTTP/1.1 404 Not Found');
  7.  
  8. // Access forbidden:
  9. header('HTTP/1.1 403 Forbidden');
  10.  
  11. // The page moved permanently should be used for
  12. // all redrictions, because search engines know
  13. // what's going on and can easily update their urls.
  14. header('HTTP/1.1 301 Moved Permanently');
  15.  
  16. // Server error
  17. header('HTTP/1.1 500 Internal Server Error');
  18.  
  19. // Redirect to a new location:
  20. header('Location: http://www.example.org/');
  21.  
  22. // Redriect with a delay:
  23. header('Refresh: 10; url=http://www.example.org/');
  24. print 'You will be redirected in 10 seconds';
  25.  
  26. // you can also use the HTML syntax:
  27. // <meta http-equiv="refresh" content="10;http://www.example.org/ />
  28.  
  29. // override X-Powered-By value
  30. header('X-Powered-By: PHP/4.4.0');
  31. header('X-Powered-By: Brain/0.6b');
  32.  
  33. // content language (en = English)
  34. header('Content-language: en');
  35.  
  36. // last modified (good for caching)
  37. $time = time() - 60; // or filemtime($fn), etc
  38. header('Last-Modified: '.gmdate('D, d M Y H:i:s', $time).' GMT');
  39.  
  40. // header for telling the browser that the content
  41. // did not get changed
  42. header('HTTP/1.1 304 Not Modified');
  43.  
  44. // set content length (good for caching):
  45. header('Content-Length: 1234');
  46.  
  47. // Headers for an download:
  48. header('Content-Type: application/octet-stream');
  49. header('Content-Disposition: attachment; filename="example.zip"');
  50. header('Content-Transfer-Encoding: binary');
  51. // load the file to send:
  52. readfile('example.zip');
  53.  
  54. // Disable caching of the current document:
  55. header('Cache-Control: no-cache, no-store, max-age=0, must-revalidate');
  56. header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
  57. header('Pragma: no-cache');
  58.  
  59. // set content type:
  60. header('Content-Type: text/html; charset=iso-8859-1');
  61. header('Content-Type: text/html; charset=utf-8');
  62. header('Content-Type: text/plain'); // plain text file
  63. header('Content-Type: image/jpeg'); // JPG picture
  64. header('Content-Type: application/zip'); // ZIP file
  65. header('Content-Type: application/pdf'); // PDF file
  66. header('Content-Type: audio/mpeg'); // Audio MPEG (MP3,...) file
  67. header('Content-Type: application/x-shockwave-flash'); // Flash animation
  68.  
  69. // show sign in box
  70. header('HTTP/1.1 401 Unauthorized');
  71. header('WWW-Authenticate: Basic realm="Top Secret"');
  72. print 'Text that will be displayed if the user hits cancel or ';
  73. print 'enters wrong login data';

fuente: jonasjohn.de