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();

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

Cargar extensión mcrypt de php en IIS

Hoy he tenido que cargar la extensión mcrypt de php en nuestro servidor porque no venía cargada por defecto.

Me ha dado algo más de guerra porque el servidor le gestionamos con Plesk y este crea varios php.ini, pero en principio no daría muchos problemas.

Lo primero que tenemos que saber es cual es el archivo php.ini que usa nuestro servidor, para ello podemos crear un archivo php en el que ejecutemos la función:

PHP:
  1. <?php
  2. ?>

La séptima fila nos dirá donde se encuentra el php.ini en el server "Loaded Configuration File". También lo que podemos comprobar es que la extensión que queremos cargar no esté en este archivo (a ver si la vas a tener instalada sin saberlo :P ). Buscaremos también la ruta de las extensiones configuradas en el php.ini (Configuration -> PHP Core -> extension_dir).

Localizamos el php.ini y abrimos la carpeta de las extensiones, dentro de esta buscamos el archivo php_mcrypt.dll, si le tenemos buscamos el archivo libmcrypt.dll en esa carpeta o en la anterior, ya que esa librería es necesaría para mcrypt, pero se debe copiar en la carpeta WINDOWS/System32 ya que es externa.

Una vez que tenemos los archivos bien colocados abrimos el php.ini y buscamos una línea donde aparezca esto:

CODE:
  1. ;extension=php_mcrypt.dll

El punto y coma ';' significa que esa línea está comentada, lo quitamos y reiniciamos el IIS: Inicio -> Ejecutar y escribímos: iisreset

Esperamos a que termine el reset y volvemos a cargar la página de info de php, buscamos mcrypt y debemos encontrar la extensión ya instalada.

Eliminar el último carácter de una cadena con PHP

Es sencillo, podemos utilizar la función substr, esta función nos devuelve la cadena que se le pasa recortada, desde un punto de comienzo a otro final, lo que haremos será decirle a la función que empiece en la primera posición de la cadena (0) y termine en la longitud menos 1.

CODE:
  1. string substr (string $cadena, int $comienzo [, int $longitud])

Podemos hacerlo de esta forma:

PHP:
  1. $string = "Cadena a recortar";
  2. $string = substr ($string, 0, strlen($string) - 1);
  3. echo $string; // esto muestra "Cadena a recorta"

Pero no es necesario especificar la longitud de la cadena ya que la función lo tiene implícito, sólo tendremos que enviarle que la longitud, el punto final, sea -1, y quitará el último carácter, tal que así:

PHP:
  1. $string = "Cadena a recortar";
  2. $string = substr ($string, 0, - 1);
  3. echo $string; // esto muestra "Cadena a recorta"

El mismo resultado, pero más veloz. :)

Generar una cadena aleatoria en PHP

A veces, he necesitado generar una cadena aleatoria con PHP. Por ejemplo para poner un nombre a un archivo que se sube al servidor o para generar una nueva password/contraseña para un usuario olvidadizo.

Para ello utilizo una sencilla técnica:

PHP:
  1. $name = md5(microtime());

La función microtime, me devolverá el tiempo en formato Unix, con micro-segundos, y la función md5 codificará la cadena en md5, de esta forma estoy seguro que la cadena que he generado es única, es muy difícil que un mismo usuario tenga que generar la cadena en el mismo micro-segundo, el mismo día que otro.

La cadena generada tendría este aspecto:

eca422045b1abecf1a401bdda3a67f2f

También podemos recortar la cadena obtenida para, por ejemplo, nombres de archivos únicos:

PHP:
  1. $longitud = 8; // Elegimos la longitud de la cadena
  2. // recortamos la cadena, conseguimos nueva pass
  3. $pass = substr( md5(microtime()), 1, $longitud);