Una ciudad a puro código

Este video nos muestra como un programador diseño una ciudad virtual solo con código de programación sin utilizar ninguna otra cosa que, normalmente, se usan para diseñar este tipo de cosas en 3D: las texturas. El programa genera todo literalmentre “desde la nada”, desde las texturas hasta el modelado y el renderizado.

Shamus Young tiene 37 años y es quien hizo el programa que generó lo que más arriba viste. Su objetivo fue simple: hacer una ciudad de noche y que se viera realista… sin duda alguna que lo logró. Los que entienden un poco de programación saben que esto, no es nada fácil.

Vía: PlanetaRed

PHP: include seguros

Me canso de ver a menudo aplicaciones web o scripts que hacen cosas como esta:

<?PHP
$sPagina = $_GET[‘pagina’];
include ($sPagina);
?>

Eso es lo que yo llamo una aberración de seguridad. Al menos algunos se toman el trabajo de “limpiar” $sPagina, igualmente para mi gusto, sigue siendo peligroso por el solo hecho de estar mostrando algo de la estructura interna de nuestra aplicación.

La idea es que, cuando quieras incluir una “página” o archivo dentro de tu script “a petición”, es que trates de darle la menor cantidad de información posible a quién está del otro lado (cliente). Hay muchos métodos, pero básicamente te recomiendo dos: utilizar un diccionario, o codificando la petición.

Utilizando un diciconario

En este caso te valés de un array. Este ejemplo es para cuando tenés un número conocido de páginas.

<?PHP
// Tienes el array con la lista de páginas a cargar
$aPaginas = array(0 => 'index.php', 1 => 'acerca-de.php', 2 => 'servicios.php', 3 => contacto.php);
// Tomas el parámetro "pagina" que viene por GET y lo transformas a un entero
$iPagina = (int) $_GET['pagina'];
// Validación
if (!isset($aPaginas[$iPagina])
{
// La petición es incorrecta. Están tratando de cargar una página que no existe
// Puedes directamente "matar" la petición con un die('Solicitud incorrecta'); o mandarlos
// a la página por defecto: index.php que está en el índice 0;
$iPagina = 0;
}
// La petición es válida
include($aPaginas[$iPagina];
?>

Codificando la petición

El ejemplo es para cuando no tenés un N° conocido de páginas, así que lo mejor es codificar de alguna forma (más simple o más compleja) la petición. La idea es que los archivos a incluir los tengas en un directorio, y bajo este, los directorios que quieras. De esta forma te asegurás de incluir solo archivos de ese lugar (directorio base).

Cuando me refiero a codificar no me refiero a “encriptar” (aunque se puede hacer) sino más que nada a ocultar detalles de la implementación. Por ejemplo evitar peticiones de path’s absolutos a nuestros archivos para que no conozcan los directorios, el document root, y demás.

Supongamos que tenemos nuestros includes organizados en:

/fichas/rubro01/producto0001.php
/fichas/rubro02/producto0001.php
/fichas/rubro03/producto0001.php
/fichas/rubro03/producto0002.php

Sabemos entonces que, todos nuestros includes, están organizados dentro del /fichas. También tenemos un patrón en el nombre de la segunda carpeta, donde el nombre es igual a “rubro” + NN (código del rubro). Y la ficha en sí, que está dentro de la carpeta rubroNN; tiene la forma “producto” + NNNN .php

Entonces, una forma de ocultar nuestra implementación es utilizando estos patrones, y recibiendo como petición solamente el código del rubro y del producto, datos suficientes para “deducir” que ficha queremos incluir en nuestro script.

Podríamos usar dos parámetros: rubro y producto, pero mejor usamos uno solo y separamos el rubro del producto con un caracter, por ejemplo el “.” (punto). Así, nuestro request va a ser pagina=1.1 (rubro 1, producto 1).

<?PHP
// Este es el directorio base
$sDirBase = '/fichas';

// Recuperamos la página que se pide
$sPagina = (string) $_GET['pagina'];

// Siempre en $sPagina esperamos el código del rubro más el código del producto separados por un punto. Validamos este patrón con una expresión regular.
if (preg_match("/^\d{1,2}\.\d{1,4}$/", $sPagina))
{
// La expresión regular validó. Proceso el request $sPagina
$aPagina = explode('.', $sPagina);
// Armo el nombre de nuestro archivo a incluir
$sPagina = '/rubro' . str_pad($aPagina[0], 2, '0', STR_PAD_LEFT) .
'/producto' . str_pad($aPagina[1], 4, '0', STR_PAD_LEFT) .
'.php';
// Listo... ahora lo incluyo con toooda seguridad :)
include ($sDirBase . $sPagina);
}
else
{
// Falló la validación de la expresión regular
}

?>

Es muy simple y muy fácil. Y muy seguro. Espero que sirva.

Programando con estilo

“El código es poesía” resa el refrán de WordPress.org (Code is poetry), y si… para los que lo entendemos lo es en cierta manera, o al menos por aquellos que nos preocupamos por escribirlo bien, porque hay mucho código de programas que parecen ser escritos por monos (¿alguién dijo PhpNuke por ahí?.

Leyendo este post el algorítmica (al que llegué por este post de Picando Código) me encuentro con los nombres de las distintas formas de indentar el código fuente de un programa.

Yo utilizo el estilo Allman en todo el código que escribo. A mi criterio es el más fácil de leer, ya que aporta de espacios en blanco que me ayudan a distinguir los distintos bloques de código. Estoy hablando de este:

function mostrarAlgo($sAlgo)
{
   if (!null($sAlgo))
   {
      echo $sAlgo;
   }
   else
   {   
      echo "No hay nada que mostrar";
   }
}

También al igual que a Eduardo de Algorítmica, indento el seteo de las variables de esta forma:

$sString  = "Pablo";
$sPais    = "Argentina";
$bSoltero = true;
$iEdad    = "32";

Y encontré algo interesante que voy a aplicar: utilizar bloques de código.

{// Ver si es verdad
   if ($bTalCosa)
   {
      echo "Es verdad";
   }
   else
   {
      echo "Es falso";
   }
}// Fin de ver si es verdad    

Esta es una forma más clara de organizar ciertos bloques de código que a veces no se nos ocurre como marcarlos o diferenciarlos del resto.

Algunos enlaces: