Generador de contraseñas en PHP

En PHP hay muchas formas de generar contraseñas, algunas propias del sistema. En ocasiones se usan sistemas sólo números. Con este sistema tienes disponible todos los caracteres que quieres como disponibles (mayúsculas, minúsculas, números, símbolos…) y la longitud (24, que en este caso la convierte en segura). Así que si necesitas restaurar la clave a un usuario, con esto le ofrecerás una clave segura.

<?php
$caracteres = '0123456789abcdefghijklmnpqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$#@!?=%-+*.[]{}_,;:<>|';
$caractereslong = strlen($caracteres);
$clave = '';
for($i = 0; $i < 24; $i++) {
  $clave .= $caracteres[rand(0, $caractereslong - 1)];
}
echo $clave;
?>

smushit.net, una API simple de smushit

Si te dedicas al mundo de Internet es muy probable que entre las aplicaciones que utilices se encuentre la de comprimir imágenes… pero el uso de algunas herramientas a veces se hace muy complejo o necesita de servidores con algunas configuraciones extrañas. Es por eso que, como yo mismo me he encontrado en esa situación y soy bastante asiduo a la herramienta de Smush.it de Yahoo! he querido simplificarme la vida y, de paso, os hago partícipes de ello a vosotros.

Que conste que es una simple prueba y que puede fallar (como todo en la vida). El servicio es smushit.net y lo que hace es simplificar la API existente eliminando los datos poco útiles.

El objetivo es que introduzcas por parámetro la URL de la imagen que quieres optimizar y te devuelva la URL de la imagen optimizada. De esta forma con un simple código en PHP, ASP o lo que te apetezca podrás hacer un “fopen” o un “fread” y te devolverá la URL que luego podrás descargar o hacer lo que te apetezca.

El ejemplo es sencillo http://smushit.net/?img=http://smushit.net/Tux.png.

Se aceptan sugerencias y demás… aunque, como digo, es una prueba por entretenerme a pasar el rato.

Google Maps + Foursquare

Si eres de los que le da igual que sepan donde estás en todo momento (o al menos donde accedes en Foursquare) tal vez te interese este pequeño mashup con el que podrás mostrar gracias a los mapas de Google Maps tu última localización de Foursquare.

¿Cómo se consigue esto? Pues tan sencillo como entrando en tu cuenta de Foursquare y luego visitando la sección de feeds. Allí encontrarás una de las opciones en formato KML.

Ahora tan sólo has de añadir esa dirección URL al final del mapa de Google. Por ejemplo:

<iframe scrolling="no" marginheight="0" marginwidth="0" width="300" height="300" src="http://maps.google.com/maps?f=q&source=s_q&hl=es&geocode=&q=http://feeds.foursquare.com/history/ABCDEF0123456789.kml?count=1&ie=latin1&output=embed"></iframe>

El parámetro “q” es el que lleva la URL de Foursquare, y el “count” es el número de puntos que quieres que se muestren. Si pones 1 indicará el último en el que hayas hecho checkin.

Cachear de forma sencilla una página dinámica en PHP

¿Te ha pasado alguna vez que tienes una web desde hace un montón de años, que la hiciste tú y a veces te da problemas de saturación por exceso de visitas? Pues a mi sí y, aunque llevaba tiempo pensando en alguna forma de cachear, que acababa siendo hipercompleja, hoy me ha dado por pensar alguna forma sencilla basándome en unas pruebas que había hecho hacía poco.

La cuestión es que sabía cómo hacerlo, iba por el camino, pero entre unas cosas y otras “nunca encontraba el momento”, hasta ahora. El sistema es bastante simple y en principio se podría aplicar a cualquier sitio. El código sería algo tal que este:

<?php
$md5 = md5($_SERVER["REQUEST_URI"]); // convertimos la URL a único identificador
$file = "cache/".$md5.".html"; // donde se guardará el fichero
$hora = filemtime($file); // comprobamos la hora del fichero si ya existiera
if(time() <= $hora+86400) { // asignamos un tiempo de cache de 86400 segundos
    include($file); // incluimos el contenido del fichero cacheado
    echo "<!-- ".date('YmdHis', $hora)." -->"; // (opcional) añadimos al pie de página la fecha-hora de la caché
    exit; // salimos
}
ob_start(); // abrimos la memoria
?>
AQUI VA LA WEB NORMAL
<?php
$fp = fopen($file, 'w+'); // abrimos el fichero de caché
fwrite($fp, ob_get_contents()); // guardamos el contenido de la página generada en el fichero
fclose($fp); // cerramos el fichero
ob_end_flush(); // devolvemos la página que se ha generado y cerramos la memoria
?>

Con este sistema podremos incrementar una página dinámica tranquilamente entre un 50% y un 1.000% la velocidad, dependiendo de la carga de base de datos o cálculo que tuviera anteriormente.

Combinar y reducir JavaScript

En muchas ocasiones me encuentro que tengo varios JavaScript en una página y, al final, se hace bastante pesado tener que gestionar múltiples ficheros. Además, otra cosa que me gusta es la de reducir al máximo el tamaño del fichero, y el hecho de poder combinarlos también permite reducirlos…

Es por esto que existe para PHP una pequeña biblioteca de funciones llamada JSmin-php que ayuda a gestionar esta situación tanto la de combinar como de minimizar.

Básicamente lo que hace esta biblioteca es leer todos los ficheros JS de una carpeta, combinarlos, comprimirlos y generar un fichero único cacheado.

require_once("jsmin.php");
$files = glob("/carpeta/js/*.js");
$js = "";
foreach($files as $file) {
  $js .= JSMin::minify(file_get_contents($file));
}
file_put_contents("/carpeta/combinado.js", $js);

En el caso en que no queramos leer todos los ficheros de una carpeta y sólo incluior unos pocos, podemos cambiar la línea por algo al que así:

$files = array("/carpeta/js/1.js", "/carpeta/js/2.js", "/carpeta/js/3.js");

De esta forma generaremos un único fichero. Personalmente creo que esto habría que ejecutarlo una vez de forma externa, y usar el fichero generado a mano… a menos que montemos un sistema que verifique las cachés o que permita cambiar este fichero sin que ocurra nada… que luego ya se sabe, cambios de versiones, etc.

Evita, con PHP, ataques XSS y SQL injection

Una de las cosas que normalmente no revisamos cuando creamos un sitio web es la vulnerabilidad que se tiene a ataques por URL por cosas como XSS e incluso a ataques a la base de datos por una mala configuración. Para esto normalmente se usa una revisión y se ejecuta, con PHP, la función htmlentities() que, gracias a eliminar el código HTML puede filtrar cosas como los <script>. Para solventar esto existe una cosa llamada Genius Open Source Libraries que, con unas simples funciones, permiten hacer una megalimpieza contra ataques de todo tipo.


require_once 'Core/sgConfig.inc.php';
// Output an unsafe string, presumably user input
$xss = '<script>alert(\'oh snap\');</script>';
echo 'If your entered your name as ' . $xss . ', we\'d be in trouble.<br>' . "\n";
// Sanitize that string, and output it safely
$htmlContentContext = sgSanitizer::sanitizeForHTMLContent($xss);
echo "But if we sanitize your name, " . $htmlContentContext . ", then all is well.<br>\n";
echo '<h2>HTML Attribute</h2>';
// We can also safely sanitize it for an HTML attribute context
$htmlAttributeContext = sgSanitizer::sanitizeForHTMLAttribute($xss);
echo 'Tainted strings can also be used in an <a href="http://google.com" title="' . $htmlAttributeContext . '">HTML attribute</a> context.<br>' . "\n";
echo '<h2>JavaScript string</h2>';
// And we can even make strings used in JavaScript safe
$jsString = '\';alert(1);var b =\'';
echo '<script type="text/javascript">
var a = \'' . $jsString . '\';
var aSafe = \'' . sgSanitizer::sanitizeForJS($jsString) . '\';
</script>';

En este sistema de limpieza descargable como proyecto Genius encontramos algunas funciones como sanitizeForHTMLContent (que limpia el contenido teniendo en cuenta que es código HTML), sanitizeForHTMLAttribute (que limpia como atributo de HTML, por ejemplo el “alt” de una imagen) o sanitizeForJS (que dejaría el código arreglado para poder ejecutarse como JavaScript).

Sin duda una biblioteca de funciones interesante a la hora de aumentar la seguridad de un sitio web.

DISTCHA, un antispam accesible

Una de las peculiaridades de los CAPTCHA es que habitualmente son bastante complejos de entender y ya no os digo si cuesta a alguien con todas sus facultades, a alguien que tenga falta parcial o total de alguno de sus sentidos.

Y es por eso que desde Francia Quebec (Canada) llega una propuesta llamada DISTCHA (Device Independent Slider Test to tell Computers and Humans Apart) y que es un sistema bastante parecido al de activación del iPhone, ese “slide” que moviéndolo de un lado a otro permite activar el teléfono.

Aunque aun se encuentra en una versión muy previa, y a falta de ser probado en muchas plataformas, sí que es cierto que en la mayor parte de los navegadores ya funciona.

Funciona gracias a jQuery y es bastante sencillo de implementar. Os dejo un ejemplo de código para que veáis cómo funciona y uséis su código si lo veis conveniente…

Cargar una página por bloques

Normalmente cuando desarrollamos una página web no nos preocupamos en exceso cómo enviamos la información a los usuarios que se conectan a ella, dejando que el sistema lo haga de forma automática. Eso no es del todo malo, pero hace que la paralelización de la que alguna vez os he hablado se pueda perder en parte.

Sabemos que en muchas ocasiones en la cabecera de una página incluimos los CSS y JS, y que estos pueden llegar a bloquear nuestra carga de página. Teniendo en cuenta que la cabecera en sí “no hace nada” ¿por qué no enviarla en cuanto la tengamos? Esto significaría que, una vez la mandemos, antes de pintar nada, y mientras calculamos el contenido de la página que verá el usuario, podemos enviar cierta información y el navegador puede comenzar la descarga de elementos externos como los que comentaba antes.

Para hacer esto, y como seguro que usaremos gzip, en PHP podríamos utilizar algunas funciones como ob_flush().

A partir de este momento, en el que ya hemos enviado la cabecera de la página, hay que decidir si nuestro sitio está preparado para ser enviado por partes. Normalmente las páginas tiene diversos bloques que no suelen estar contenidos dentro de otros. De esta forma podríamos dividir lo que se muestra al usuario en una cabecera, un contenido, un menú lateral y un pie. cada uno de estos bloques, al ser independiente del otro, podrían llevar, entre uno y otro, estas funciones flush, y así el sistema sería capaz de ir pintando la página sin dependencias entre cada uno de estos bloques, y la sensación de carga sería mayor, ya que estará “precargado” el CSS y JS, que se cargan antes de que se reciba toda la página.

El último de los bloques no necesita llevar este elemento. Eso sí, para que esto funcione realmente hace falta seguir las normas que dicen que los JavaScript que no afectan al “pintado” de la página se encuentren en el pie, y que los que sí afectan se encuentren en la cabecera.

Ahora sólo queda implementarlo y ver si hace efecto…

Cómo hacer muchas peticiones HTTP simultáneas en PHP

Uno de los problemas que habitualmente nos pueden frenar la carga de un sitio es si leemos mucha información de varios sitios de forma simultánea, como podría ser la lectura de varios feeds. Y es que habitualmente se usa la función file_get_contents() que tiene una cosa: es síncrona, es decir, hay que ejecutarla, esperar a que finalice, y volver a ejecutarla… pero ¿por qué esperar a qué acabe de leer para hacer otra llamada?

Para hacerlo podemos utilizar las funciones curl_multi_* que básicamente permiten hacer muchas llamadas cURL en muy poco tiempo. No es del todo asíncrono y en paralelo, pero casi casi se podría considerar como una opción.

El tiempo total de estas peticiones será la de la más lenta de todas, de forma que si tenemos algo como esto:

  • URL 1: 2,3 segundos
  • URL 2: 0,3 segundos
  • URL 3: 1,4 segundos
  • URL 4: 1,8 segundos
  • URL 5: 3,0 segundos

de la forma normal tardaríamos 8,8 segundos 8que es la suma de todos, aunque habría que sumarle los tiempos de conexión y desconexión), y de la forma que propongo se tardaría un poco más de 3,0 segundos, que es el tiempo de la más lenta de todas.

¿Cómo hacer esto?

<?php
function PeticionMultiple($urls, $opciones = array()) {
  $curly = array();
  $resultado = array();
  $pm = curl_multi_init();
  foreach ($urls as $id => $d) {
    $curly[$id] = curl_init();
    if(is_array($d) && !empty($d['url'])) {
      $url = $d['url']
    } else {
      $url = $d;
    }
    curl_setopt($curly[$id], CURLOPT_URL, $url);
    curl_setopt($curly[$id], CURLOPT_HEADER, 0);
    curl_setopt($curly[$id], CURLOPT_RETURNTRANSFER, 1);
    if (!empty($d['post'])) {
      curl_setopt($curly[$id], CURLOPT_POST, 1);
      curl_setopt($curly[$id], CURLOPT_POSTFIELDS, $d['post']);
    }
    if (!empty($opciones)) {
      curl_setopt_array($curly[$id], $opciones);
    }
    curl_multi_add_handle($pm, $curly[$id]);
  }
  $ejecutando = null;
  do {
    curl_multi_exec($pm, $ejecutando);
  } while($ejecutando > 0);
  foreach($curly as $id => $c) {
    $resultado[$id] = curl_multi_getcontent($c);
    curl_multi_remove_handle($pm, $c);
  }
  curl_multi_close($pm);
  return $resultado;
}
?>

Y el código de invocación:

<?php
$urls = array(
  'http://javiercasares.com/feed/atom/',
  'http://www.ethek.com/feed/atom/',
  'http://www.tumanitas.com/feed/'
);
$r = PeticionMultiple($urls);
print_r($r);
?>

Con esto, en principio, conseguiríamos múltiples peticiones para leer feeds de muchos sitios lo más rápido posible…

Relacionado: interesante la función EpicCurl del código EpiCode.

Open Standard Media (OSM) Player

Uno de los poyos que siempre me he encontrado a la hora de poner un reproductor de vídeo en la web es que en la mayoría de casos sólo aceptaba vídeos flash (.flv). La cosa es que con el HTML 5 y con jQuery se han montado un reproductor llamado Open Standard Media que tiene muy buena pinta, es código abierto y gratuito.

Entre otras cosas, permite el uso de HTML 5, soporta los nuevos elementos audio y video del HTML 5 con los formatos estándar, para el resto de formatos monta un reproductor Flash, se le puede cambiar el diseño de una forma sencilla gracias al uso de ThemeRoller, permite la integraciónd e vídeos de Vimeo y Youtube (simplemente indicando la URL), tiene la opción de listados de vídeos.

La instalación es muy sencilla, ya que sólo hay que añadir un par de JavaScript en la cabecera, poner el código básico del reproductor, y al final de la página, puedes incorporar un listado de los vídeos o una llamada a un XML que los tenga. Aun así, creo que la opción más sencilla es la de usar la librería en PHP, que con unas pocas líneas funcionaría:

<?php
include("OSMPlayer.php");
$player = new OSMPlayer(array(
  'file' => 'http://www.mysite.com/files/myvideo.flv',
  'image' => 'http://www.mysite.com/files/myimage.jpg',
  'disablePlaylist' => true
));
?>
<html>
  <head>
    <title>Open Standard Media (OSM) Player: PHP Demo</title>
    <script type="text/javascript" src="jquery-ui/js/jquery.js"></script>
<?php
print $player->getHeader();
?>
  </head>
  <body>
    <h2>Open Standard Media (OSM) Player</h2><br/>
<?php
print $player->getPlayer();
?>
  </body>
</html>

Con esto tendríamos un reproductor sencillo, aunque también se puede complicar un poco si le añadimos una lista de reproducción que nos permita visualizar decenas de vídeos… o si queremos modificar algunos parámetros, aquí está la lista de todos los disponibles…