Pfff

Pfff es un conjunto de utilidades desarrolladas por Facebook y que permiten realizar análisis estático, análisis dinámico, refactoring y otras cosas más. Fue desarrollado principalmente para PHP, pero tambien incluye soporte para otros lenguajes. Sin duda algo que se puede usar para reducir el número de posibles errores.

Cuidado al utilizar unserialize() en PHP

Azares de la vida me hacen trabajar nuevamente con PHP a tiempo completo. Al igual que hace algunos años atrás, todavía existen algunas características de este lenguaje que me sorprenden. En este caso, se trata la función unserialize(). En la documentación, existe la siguiente advertencia.
No proporcione datos no fiables provenientes del usuario a unserialize(). Revertir la serialización puede resultar en que haya código que se cargue y ejecute debido a la instanciación y autocarga de objetos, y un usuario malicioso podría ser capaz de explotar esto. Se debe utilizar un formato de intercambio de datos seguro y estándar, como JSON (a través de json_decode() y json_encode()) si es necesario pasar datos serializados al usuario.
Por ejemplo, si en algún lugar de una aplicación existe la siguiente clase.
php:

<?php
class Foo {
  private $tmp_file;
  public function __construct() {
    $this->tmp_file = tempnam( '/tmp', 'foo' );
  }
  public function doSomething() {
    // ...
  }
  public function __destruct() {
    @unlink( $this->tmp_file );
  }
 
El riesgo de utilizar unserialize() con datos que provienen de fuentes externas, ejemplo unserialize( $_GET['foo'] ), permitiría a un atacante eliminar cualquier archivo al que el servidor web tenga acceso (de escritura). Usando sólo código PHP no hay muchas opciones para protegerse de ataques si uno está obligado a usar ésta función. Espero que algún día la siguiente extensión sea incluída en la versión oficial de PHP: https://wiki.php.net/rfc/secure_unserialize. La moraleja de la historia es leer la documentación y escoger con cuidado los formatos que uno usa para este tipo de escenarios.

PHP Fail

Aparentemente un "string" no es un "string" en PHP.
php:
<?php
interface IPhpSucks {
        function foo(string $bar);
}
class PhpSucks implements IPhpSucks {
    function foo(string $bar) {}
}
$f = new PhpSucks();
$f->foo('demo');
Al ejecutar ese script, se obtiene un lindo error.
Catchable fatal error: Argument 1 passed to PhpSucks::foo() must be an instance of string, string given, called in demo.php on line 10 and defined in demo.php on line 6
Actualización: Averiguando un poco más, al parecer esta característica (Type Hinting) funciona sólo para nombres de clases o el tipo array (s/PhpSucks/ISuckInPhp/).

¿Threads en PHP?

Nunca me ha gustado PHP como lenguaje, sin embargo en los últimos 4 o 5 años, he leído y escrito varios miles de lineas de código. Una contradicción dirían algunos.

Dicho esto, ahora último estuve jugando un poco con el código del plugin para importar contenido en WordPress. Actualmente, lo que hace es cargar todo el archivo XML en memoria, hace el parsing y finalmente comienza a importar el contenido. Todo esto, siempre y cuando se haya logrado subir con éxito el archivo.

La idea era modificarlo para que pueda procesar archivos de gran talla sin necesidad de cambiar mucho la configuración del servidor. El primer punto era poder subir los archivos sin problemas, así que el primer paso era subirlo en pedazos y juntarlo todo en el servidor. Dado que esto no se puede hacer sólo con javascript, pensé en utilizar flash, pero como no conozco ActionScript dejé de lado esa opción. Había hecho pequeñas cosas en Silverlight, así sería más sencillo. Sin embargo, como seguramente alguien había tenido el mismo problema, decidí buscar soluciones ya existentes. Encontré el excelente proyecto plupload.

El siguiente punto era procesar el archivo XML por partes, leyendo en bloques. Lo que normalmente hubiera hecho en otro lenguaje sería tener un pool de X threads, que procesarían las piezas que se vayan leyendo del documento (cada pieza por ejemplo conteniendo Y entradas). Sin embargo, esto parece no ser posible todavía y no sé si sea posible del todo. Por el momento, probablemente tenga que utilizar, lo que considero son hacks, el clásico cron o su variante de WordPress, wp-cron.

Si hay algún experto PHP en la audiencia y que tenga algo de tiempo para hacer una recomendación, ¿hay alguna manera más elegante de hacer ese tipo de cosas?

* Para los interesados en el código que modifiqué, pueden descargarlo de http://www.buayacorp.com/files/wordpress/wp-large-upload.zip
** Sé que me dirán algunos que es mejor hacerlo usando mysqldump o phpmyadmin, pero en ciertos casos no se tiene acceso a ese tipo de utilidades.