Archivo por autor

CoRD, cliente de escritorio remoto de Mac

Hace unos días hablaba de mi reintroducción al mundo Windows. Para conectar desde Mac mencionaba que se podía utilizar el cliente de escritorio remoto de Microsoft. Bien, al poco de probarlo uno se da cuenta de que es un software que no está listo para producción. El teclado de un Mac es ligeramente distinto al de un Pc convencional. Una de las diferencias es que no tiene tecla “Alt Gr”. Si utilizas un teclado inglés de EEUU, esto no te supondrá un problema, ya que no se utiliza esa tecla:

Disposición de un teclado Inglés

Pero si ése no es tu caso, el cliente de escritorio remoto de Microsoft no te servirá; no hace una conversión previa de un teclado a otro, sino que envía a Windows tal cual las teclas que has pulsado.

Todo esto intenté antes de dar con la solución:

  • Utilizar otro software, como VNC.
  • Hacer uso de la combinación Alt+Ctrl, que en Windows emula la tecla AltGr. Además de ser incómodo, no muestra algunos caracteres como ‘{‘ o ‘\’.
  • Hacer un mapeo de teclado personalizado modificando el registro.

Cuando ya creía haberlo probado todo, vi un foro en el que hablaban de CoRD, un cliente de escritorio remoto para Windows. Lo probé, y a la primera :)

Además de contar con las mismas funcionalidades que el de Microsoft, tiene unas cuantas cosas que lo convierten en un mejor cliente RDP:

  • Se comporta mejor en el modo pantalla completa, ajustándolo a la resolución de tu monitor. Con el de Microsoft esto no ocurría, dejando una banda negra a cada lado.
  • Interpreta y convierte de tu teclado al equivalente en Windows. Puedes escribir la arroba, llaves, almohadillas, o corchetes.
  • Convierte la tecla cmd de Mac en la tecla Win.
  • Puedes tener varias sesiones abiertas a la vez, pudiendo navegar entre ellas desde un cómodo panel.

Y además, es open source!

Mejorar el rendimiento de javascript con timers

Uno de mis últimos encargos consiste en una aplicación financiera para el navegador. En resumen, se trata de “traducir” una serie de hojas en Excel a javascript. El cómo lo he implementado da para otro artículo.

Básicamente el funcionamiento es el siguiente:

  • Creamos un campo de texto por cada celda del fichero Excel.
  • Muchas celdas tienen valores dinámicos, es decir, se generan a partir del valor de otras.
  • Definimos la fórmula que genera el valor de cada celda dinámica, y esa fórmula la añadimos a la pila de callbacks del evento ‘change’ de todas las celdas de las que depende.

Problema: Hay miles de celdas, prácticamente todas dinámicas. Esto implica que a menudo, al cambiar un sólo valor, se generan cientos o miles de cálculos. Javascript es single threaded, es decir, sólo se ejecuta una única hebra (para realizar cálculos, modificar el árbol DOM, gestionar eventos, o redibujar la pantalla). Si una operación muy costa en cálculos conlleva 8 segundos, la interfaz de usuario se quedará bloqueada hasta que finalice. Mal asunto.

El experto en usabilidad Jakob Nielsen dijo:

0,1 segundos es el límite para que el usuario perciba que el sistema responde inmediatamente.

¿Son los Web Workers la solución?

Quizás te preguntes qué son los Web Workers. Se trata de una especificación de WHATWG, el equipo que ha dado forma a lo que hoy conocemos como HTML5, para permitir programar aplicaciones multihebra en javascript, es decir, correr procesos en segundo plano.

Si bien es una funcionalidad que han empezando a incorporar recientemente los navegadores (a excepción de IE9), no es nada nuevo; el paquete Google Gears ya ofrecía estos mecanismos. De hecho, los web workers están basados en la API WorkerPool de Google Gears.

Por tanto, ¿son la solución al problema? Sí, pero…

A pesar de que una hoja de cálculo puede ser un ejemplo de libro para el uso de Web Workers, finalmente no los he utilizado. Existen algunas limitaciones, por cuestiones de seguridad, a la hora de usar Web Workers. A destacar, que no tiene acceso a:

  1. DOM.
  2. objeto window.
  3. objeto document.
  4. objeto parent.

Toda la comunicación con la hebra principal se realiza mediante mensajes. Esto interfiere con el código que ya tenía, de modo que implicaría reescribirlo en gran parte. No es una opción por desgracia.

Luego está el motivo de que no funcionan ni funcionarán en Internet Explorer.

Timers al rescate

Repasemos conceptos de sistemas operativos. En un sistema multitarea, en un momento dado no se pueden ejecutar más tareas que procesadores tiene el equipo. Por eso existe el planificador de procesos, que es la parte que se encarga de repartir el tiempo disponible entre los distintos procesos en ejecución. Si se asignan tiempos bajos de ejecución, el efecto será que están funcionando varios procesos concurrentemente. Sintetizando muchísimo, podríamos decir que el planificador de procesos se encarga de asignar bloques de tiempo a cada proceso.

Ahora repasemos los timers. ¿Qué hacen exactamente? Posponen la ejecución de un comando. Esto significa que, mientras se espera ese tiempo, el navegador queda libre para hacer otras cosas.

¿Y si añadimos pausas voluntarias en la propagación de eventos ‘change’ de las celdas? De esta forma, habrá pausas que permitirán “descongelar” la interfaz de usuario, emulando que los cálculos se están ejecutando en un segundo plano, haciendo que la interfaz de usuario sea fluida. Miremos el siguiente gráfico:

Gráfico de relación de tiempos con y sin timers

El color azul representa los cálculos. El verde, es cuando no realizamos cálculos y la interfaz responde a eventos (el equivalente a este proceso en sistemas operativos se llama idle).

En el primer caso no utilizamos timers. Lo que ocurre es que el navegador se queda congelado durante más de tres segundos.

Sin embargo, en el segundo caso añadimos pausas voluntarias, con lo que percibimos que en todo momento el navegador reacciona inmediatamente a nuestras acciones.

Demo

He hecho una sencilla demo. El script se encarga de calcular los números primos menores de 300.000. En un caso con timers y en otro sin él:

  1. Sin timers. La página se quedará congelada hasta que finalice el cálculo.
  2. Con timers. Podrás interactuar con la página mientras hace los cálculos.

Si miramos el código, veremos que hay algunas diferencias. En el primer caso, esto es lo que ocurre:

jQuery("#button").bind('click', function() {
  for (var i=1; i<=300000; i++) {
    if(isPrime(i)) {
      jQuery('#prime').append(" "+ i);
    }
  }

Comprobamos uno a uno cada número desde un bucle, y si es primo, lo mostramos en pantalla. Seguramente haga saltar un aviso en el navegador de que el script está llevando demasiado tiempo.

El segundo ejemplo es un poco más elaborado:

function comprobarPrimo(numero, fin,total) {
  var delay = 10;
  var heap = 500;
  if (isPrime(numero)) {
    jQuery('#prime').append(" "+ numero);
  }
  if(++numero < fin) {
    if (total%heap === 0) {
      setTimeout("comprobarPrimo("+numero+","+fin+","+(total+1)+")", delay);
    } else {
      comprobarPrimo(numero, fin, (total+1));
    }
  }
}

jQuery("#button").bind('click', function() {
  comprobarPrimo(1,300000,0);
});

En lugar de usar un bucle, usamos una función recursiva. Esto lo hacemos porque, cada vez que llamamos a setTimeout, se ejecuta el código que le sigue sin esperar el delay. Es decir, que al añadir un timer no pararíamos realmente toda la ejecución. Con una función recursiva corregimos esto.

Y definimos dos variables: delay, que es el retardo en milisegundos que se aplicará, y heap, que define cada cuántas llamadas se aplica delay. En este ejemplo se establece un delay de 20 milisegundos que se aplica cada 500 números primos. Los otros 499 se ejecutan sin retardo.

El resultado es completamente distinto al del primer ejemplo. Y únicamente añadimos pausas de 20 milisegundos cada 500 números primos. Por supuesto el tiempo de ejecución se ve incrementado.

Desarrollo web: de Unix a Windows

Un cliente me ha propuesto colaborar con el proyecto que están desarrollando. Tras decirme que utilizan .NET, le comenté que no lo conozco y que generalmente trabajo en entornos LAMP, a lo que me comentó que no cree que me fuera a suponer ningún problema familiarizarme con C#. ¿Y por qué no? Mentiría si dijera que no me apetecía aprender un poco de Windows y de sus tecnologías. La última vez que utilicé un sistema operativo de Microsoft para trabajar o estudiar fue a mediados de 2003. Desde entonces sólo he tenido sistemas Unix (Linux y Mac).

El equipo

Lo primero era hacerme con un equipo –la virtualización está muy bien para poder hacer pruebas en otros sistemas, pero no para utilizar estos sistemas como herramientas de trabajo. Por suerte, tenía uno acumulando polvo. Pero no me apetecía ni comprar ni tener 2 monitores, 2 ratones y 2 teclados, uno para el servidor Linux y otro para Windows, de modo que me compré un conmutador.

Con este fantástico cacharrito puedo compartir monitor, teclado y ratón con dos equipos. Simplemente tengo que usar un atajo del teclado para alternar entre uno y otro.

Instalación de Windows 7

El siguiente paso era instalar Windows 7 Professional. He elegido Windows 7 porque ya que me pongo, que al menos sea con lo último. ¡Faltaría más! La instalación ha sido muy sencilla, más que la de cualquier programa o driver de Windows :) Además, y como punto a favor, ha detectado e instalado prácticamente todo el hardware, y lo que no ha detectado, ha utilizado drivers compatibles (como el caso de la tarjeta gráfica).

Una vez instalado, el arranque ha sido rapidísimo, y el funcionamiento una vez iniciada sesión también muy aceptable. Sinceramente, no me lo esperaba.

Instalación del servidor web

El siguiente paso era instalar Internet Information Services (el servidor web por defecto de Windows). De nuevo, bastante sencillo. Desde el panel de control, en el apartado “Programs and Features”, accedemos a “Turn Windows features on or off”, y una vez ahí se selecciona “Internet Information Services”. Damos a “Ok” y listo, ya tenemos un servidor web. Vamos a localhost para comprobarlo:

Web por defecto al instalar IIS

Por lo que he podido ver, no es del todo imprescindible correr IIS, ya que Visual Studio crear un servidor ad-hoc en un puerto aleatorio a la hora de desarrollar una aplicación web.

Escritorio remoto

Afortunadamente trabajo desde distintos equipos: Linux, Mac y, ahora también, Windows. Al servidor Linux ya tengo acceso remoto gracias a ssh. No es necesario tener acceso al escritorio (a pesar de que lo tengo habilitado). Sin embargo en Windows sí lo necesito. De modo que ahora toca activar el escritorio remoto (Remote Desktop Services):

  1. Vamos a Control Panel.
  2. System and Security.
  3. System.
  4. Remote Settings.
  5. Se nos abre una nueva ventana. En el apartado “Remote Desktop” activamos la opción “Allow connections from computers running any version of Remote Desktop (less secure)”.
  6. Pulsamos en Apply, y ya está hecho.

Además, al tratarse de un servidor, he cambiado la política de ahorro de energía para que el equipo no se suspenda nunca, de modo que siempre pueda conectar a él.

Conectar desde KDE

Para conectar desde KDE/Linux es muy sencillo. Por defecto viene instalada la aplicación KRDC para conectar a escritorios remotos, bien por vnc, o por rdp. Éste último, es el protocolo propietario de Microsoft para escritorios remotos, pero además, está también implementado en sistemas Linux, por lo que es también posible compartir un escritorio en Linux con este mismo sistema. Pero volviendo al ajo, KRDC es un avanzado cliente de escritorio remoto, y al iniciar sesión podremos especificar rango de colores, resolución de pantalla, compartir sonidos, etc.

Escritorio remoto RDC en KDE

Configuración de KRDC

Conectar desde Mac

Actualización: Si vas a conectar a un Windows desde Mac con un teclado que no sea de EEUU, no uses el cliente de Microsoft. Echa un vistazo a este artículo para ver porqué, y cuál usar en su lugar.

Desde Mac es también sencillo. Microsoft tiene un cliente nativo de plataformas Mac para conectar a escritorios remotos. Descargamos la versión 2.0.1, la instalamos, y lo ejecutamos :) Desde el panel de preferencias también podemos configurar la conexión (resolución, sonidos, colores, distribución del teclado, etc.):

Instalación de ASP.NET

Ya está casi todo listo. Me dirijo a www.asp.net, y desde ahí accedo a la sección “Get Started“. Nos muestra una serie de pasos, en concreto uno para instalar ASP.NET y Visual Studio Express Tools. De nuevo bastante sencillo; descargamos el instalador, y éste se encarga de obtener todos los ficheros necesarios para la instalación. Una vez finalizado, ya tendremos instalado:

  • ASP.NET – Es el framework de desarrollo de .NET para crear aplicaciones web. Contiene toda la biblioteca .NET, y permite utilizar cualquiera de sus lenguajes.
  • ASP.NET MVC – Framework, basado en ASP.NET, que implementa el patrón MVC. Similar a la mayoría de frameworks MVC, con algunas diferencias (esto da para otro artículo).
  • Visual Web Developer 2010 Express – Es la versión freeware diseñada para estudiantes y aficionados. Existen muchas otras versiones de Visual Studio (Professional, Premium, Ultimate…), siendo la más barata de ellas 550€, aunque a través del programa DreamSpark se puede adquirir una licencia de 3 años por 100 dólares. Incluye también SQL Server.
  • SQL Server Express Database – Es la versión gratuita. Contiene algunas limitaciones, generalmente de rendimiento y de volumen de datos.

Hola mundo en ASP.NET MVC

Para finalizar el primer paso en mi cruzada, sólo queda hacer un “Hola mundo” en ASP.NET MVC. Como ahora vamos a ver, este punto no tiene mucho misterio. Tal y como ocurre con la mayor parte de frameworks de desarrollo web MVC, ASP.NET también tiene un generador inicial de código: se encarga de crear la estructura básica de directorios, layout global (Site.Master), controladores de inicio, vistas para cada acción de los controladores, bootstrap (Global.asax), modelos, etc. Además, utiliza por defecto ficheros de configuración.

Pero veamos cómo crear un nuevo proyecto:

  1. Arrancamos Microsoft Visual Web Developer 2010 Express.
  2. File > New Project
  3. En la columna izquierda seleccionamos “Visual C#”, y posteriormente “ASP.NET MVC 2 Web Application”. De este modo nuestro proyecto utilizará el framework MVC.
  4. Le damos un nombre a nuestro proyecto en el campo “Name”.
  5. Pulsamos “Ok”.

El proyecto ya está creado. Sólo tenemos que ejecutarlo accediendo a “Debug” > “Start Debugging” (también mediante el atajo de teclado F5). Se abrirá la página en un puerto aleatorio del navegador:

proyecto por defecto de ASP.NET MVC

¡Y con esto finaliza el primer salto de Unix a Windows!

Requisitos en proyectos a licitación

Recientemente, en un proyecto que salió a licitación dependiente del Ministerio de Medio Ambiente, y Medio Rural y marino, vi unos cuantos requisitos que, en mi opinión, merece la pena compartir y revisar con detenimiento. Para entrar en contexto, el proyecto consiste en el diseño, desarrollo, implantación y mantenimiento de una página web. Es normal que quieran curarse en salud, todos lo hacemos en nuestros contratos. Pero esto…

Lo primero que me llama la atención, es un párrafo que dice lo siguiente:

La herramienta de gestión de contenidos proporcionará a la Fundación Biodiversidad la capacidad de modificar en su totalidad el diseño, imagen del portal Web y todos sus contenidos. Todo ello de una manera sencilla sin requerir conocimientos de programación ni HTML.

Lamentablemente no existe tecnología que permita realizar esto. Existen multitud de editores WYSIWYG, aplicaciones que permiten editar textos de forma enriquecida sin necesidad de lidiar con CSS o HTML. Pero no existe nada que permita modificar el aspecto de toda una web sin necesidad de tener conocimientos de HTML y/o CSS. Ni siquiera aplicaciones como WordPress, Joomla o Blogger, todas ellas conocidas por lo sencillas de manejar que son, permiten nada remotamente parecido. Permiten instalar plantillas, eso sí, desarrolladas por gente que sí tiene conocimientos técnicos.

Pero sigamos. En otro párrafo nos indican esto:

La propiedad intelectual de los trabajos realizados por el adjudicatario pertenecerá a la Fundación Biodiversidad.

Todos desarrollamos código reutilizable. Por ejemplo, si un día diseño una página web en la que hay un sistema de gestión de usuarios, procuraré que este código se pueda reutilizar para otros proyectos. Es bastante frecuente contar con un buen número de “bloques” de código que reutilizas para ensamblar nuevos proyectos. Esto permite abaratar costes sin perder en calidad.

Pero volvamos con la cita anterior. Si toda la propiedad intelectual (esto incluye el software) pasa a pertenecer a la Fundación Biodiversidad, ¿qué ocurre con nuestros anteriores clientes? ¿Sus aplicaciones serán en parte propiedad de esta fundación? O una pregunta todavía más interesante, ¿y si el software utilizado, bien desarrollado por nosotros, bien por terceros, está licenciado como software libre? Por favor, si me equivoco agradecería alguna explicación, pero hasta donde yo sé, la única solución viable consiste en desarrollar un software desde cero para este proyecto.

Pero hay más puntos interesantes a analizar:

Además la Fundación Biodiversidad se reserva el derecho a ampliar los contenidos sin que el presupuesto varíe.

Al definir un proyecto siempre se olvida algún contenido o requisito. Esto es normal. Si presupuesto una web que inicialmente cuenta con 30 documentos, pero finalmente se realizan 33, muy posiblemente el precio no variará con respecto al presupuesto inicial (salvo que se trate de apartados especialmente costosos en tiempo, y siempre indicándoselo con antelación al cliente).

Pero que te obliguen a firmar unas condiciones en las que te comprometes a añadir todos los contenidos extra que te proporcionen, únicamente fiándote de su buena fe, lo veo abusivo. ¿Quién te garantiza que finalmente no será el doble de lo estimado? Personalmente considero una cláusula así como un claro indicativo de la seriedad del cliente con el que vas a trabajar. Por suerte no he tenido ningún cliente así; la gente entiende que si se salen de los requisitos iniciales, es normal pagar por ello.

Limitar la velocidad de descarga en PHP

Una de las cosas que tienen muchas páginas de descarga directa es la velocidad limitada para los clientes no premium. ¿Cómo lo hacen? Vamos cómo.

En este ejemplo vamos a suponer que queremos limitar la velocidad de descarga a 5kB/s. Para ello utilizaremos la extensión HTTP de pecl, en concreto la magia reside en la función http_throttle. Esta función recibe dos parámetros:

  1. número de segundos entre cada envío de bloques de datos.
  2. tamaño en bytes de cada bloque de datos.

De este modo, si le decimos que cada bloque de datos tenga un tamaño de 5000 bytes, y que entre cada petición debe transcurrir un segundo, conseguiremos que las descargas se realicen a 5kB/s. Realmente no es una velocidad estable, pero tiene muy pocas oscilaciones, la mayoría debidas a la conexión más que al servidor. Este es el código de ejemplo:

<?php http_throttle(1, 5000); http_send_content_type('application/pdf'); http_send_content_disposition('test.pdf'); http_send_file('test.pdf'); ?>

Como veis, únicamente establecemos la velocidad, las cabeceras para que el navegador sepa cómo manejar la petición, y finalmente mandamos un fichero de prueba llamado test.pdf que se encuentra en el directorio de trabajo actual.

El único problema está en la disponibilidad de la extensión HTTP. No creo que muchos servicios de alojamiento la tengan activada, aunque siempre se les puede pedir que lo instalen. Si quieres saber cómo hacerlo, simplemente tienes que hacer lo siguiente (en sistemas debian):

$ sudo pecl install http_pecl

Si te devolviera un código de error, quizás sea porque no tienes instaladas las herramientas de desarrollo de PHP, o alguna de las bibliotecas necesarias para compilar esta extensión. Tendrás que hacer lo siguiente:

$ sudo aptitude install php5-dev
$ sudo aptitude install libcurl3-openssl-dev

Ahora ya podrás compilarla. Sólo queda activarla en tu fichero php.ini. Añade esta línea:

extension=http.so

Y reinicia Apache con

$ sudo /etc/init.d/apache2 restart

10 cosas que quizás no sabías de PHP en la shell

Todos sabemos lo fantástico que es PHP como lenguaje de programación de páginas web. Lo que no muchos saben es que es igualmente fantástico como lenguaje para realizar programas multiplataforma para la shell. No todo es bash, Python, perl o Microsoft Powershell. Vamos a ver algunas de las cosas que quizás no sabías que podemos hacer con PHP en la consola.

Nota: Toda esta información está disponible en el manual de documentación de PHP.

1. Ejecutar un script

Podemos crearnos nuestros propios programas simplemente creando un fichero .php y ejecutándolo con el binario CLI php. Por ejemplo:

<?php
   echo "hola mundo!\n";
?>

Y ahora para ejecutarlo sólo tendríamos que llamar al binario php (php.exe en Windows) seguido del nombre del script. Supongamos que el ejemplo de arriba lo guardamos en un fichero que se llama test.php. Sería así:

$ php test.php

Y en sistemas Windows:

> php.exe test.php

De esta forma, los dos mostrarían en pantalla el texto “hola mundo!”. Fácil, verdad? :)

2. Hacer que el script se sea ejecutable

En Windows tendremos que asociar la extensión .php al binario php.exe. De esa forma, al hacer doble clic sobre un fichero, este se ejecutará. Sin embargo, si quisiéramos que se pudiera ejecutar desde la consola, tendríamos que crear un fichero por lotes .bat que realice la llamada.

@echo OFF
"C:\php\php.exe" test.php

En sistemas Unix es más sencillo. Tenemos que añadir en la primera línea la ruta al binario que ejecuta el script, y posteriormente otorgamos permisos de ejecución al fichero. Y ya está, ya es ejecutable desde la consola y desde el entorno gráfico. El fichero quedaría así:

#!/usr/bin/php
<?php
   echo "hola mundo!\n";
?>

Y después damos permisos de ejecución, y ya podremos ejecutarlo:

$ chmod +x test.php
$ ./test.php

3. Pasar parámetros al programa

Supongamos un comando cualquier de la consola, por ejemplo “ls”. Este comando acepta numerosos parámetros para controlar su comportamiento. En PHP también podemos pasar parámetros. Sólo tenemos que tener en cuenta una cosa: Si el script no tiene permisos de ejecución, hay que pasar los parámetros tras los caracteres “–”. Es así para prevenir que el binario php los considere parámetros suyos. Veamos un ejemplo de cómo hacerlo:

$ php test.php — parametro1 parametro2
$ ./test.php parametro1 parametro2

En el primer ejemplo ejecutamos el binario php y le pasamos como parámetro el nombre del script, por lo que en este caso añadimos los caracteres “–”. En cambio, en el segundo no es necesario, ya que el script tiene permisos de ejecución.

En sistemas Windows, como vimos arriba, habría que crear un fichero por lotes .bat, que para que pasara los parámetros a nuestro script quedaría así:

@echo OFF
"C:\php\php.exe" test.php %*

Bien, ya sabemos cómo enviar parámetros al script. Sólo nos queda saber cómo manejarlos. Pues muy sencillo. Hay dos variables globales para manejarlos:

  1. $argc – Contiene el número de parámetros que recibe el script
  2. $argv – Es un array con los parámetros en sí

4. Usar PHP en como consola interactiva

Al igual que ocurre con Python, PHP también puede ejecutarse en modo interactivo. Esto es, introducimos a mano los comandos en una “consola PHP”, y ésta los ejecuta al vuelo. Sólo hay que poner el parámetro “-a”. Por ejemplo:

$ php -a
Interactive shell

php > echo 5+8;
13
php > function sumarDos($n)
php > {
php { return $n + 2;
php { }
php > var_dump(sumarDos(2));
int(4)
php >

Además, pulsando el botón tabulador, tendrás autocompletado de variables, funciones, clases, constantes, método estáticos y constantes de clases.

5. Ejecutar una línea de código PHP al momento

Podemos ejecutar el código que queramos usando el modificador “-r”. Imaginemos que queremos aplicar un hash md5 a un fichero de texto, y no tenemos en nuestro sistema el comando md5sum. Podríamos hacer lo siguiente:

php -r 'echo md5(file_get_contents("fichero.txt"));'

Lo que hacemos es ejecutar los comandos que hay entre las comillas simples:

  1. Cargamos el contenido de ‘fichero.txt’.
  2. Le aplicamos el hash md5.
  3. Lo mostramos en pantalla.

¡Qué de cosas se pueden hacer con esto!

6. Pasar contenidos a PHP por tuberías

Muchas veces vemos comandos como:

echo "hola mundo" | wc -c

En este sencillo ejemplo lo que hemos hecho es en la salida estándar el texto “hola mundo”, que a su vez se envía a la entrada estándar del comando “wc -c”, que se encarga de contar el número de caracteres. ¿Cómo hacemos esto en PHP? Consultando la entrada estándar. En la versión CLI de PHP ponen a nuestra disposición 3 útiles constantes:

  1. STDIN – Stream a la entrada estándar.
  2. STDOUT – Stream a la salida estándar.
  3. STDERR – Stream a la salida de errores.

Si quisiéramos contar el número de caracteres del texto recibido por la entrada estándar en PHP, podríamos hacer lo siguiente:

echo "hola mundo" | php -r 'echo strlen(fgets(STDIN));'

7. Mostrar un fichero PHP sin comentarios ni espacios

¿Nunca te has preguntado cuántos caracteres útiles tiene un gran proyecto? Con el modificador “-w” puedes verlo, pues eliminará todos los caracteres en blanco innecesarios (incluidos tabulares, retornos de carro, cambios de línea, etc), y todos los comentarios. Además, también podrás así minimizar el tamaño de los ficheros. Por ejemplo:

$ php -w fichero.php

8. Consultar documentación desde la consola

Supón que deseas conocer los parámetros de una función, o los métodos de una clase… Puedes consultarlo desde la consola, siempre y cuando tu versión de PHP esté compilada con la extensión Reflection. Esta familia de modificadores nos da 4 opciones:

  1. “–rf” – Muestra información de una función o de un método de una clase.
  2. “–rc” – Muestra información de una clase (sus métodos, atributos, constantes…).
  3. “–re” – Muestra información de una extensión (directivas .ini, funciones, constantes, clases, etc).
  4. “–ri” – Muestra información sobre la configuración de una extensión. Esto es, lo mismo que devuelve phpinfo() para cada extensión. Si queremos ver la información general, usaremos “main” como nombre de extensión.

Veamos un ejemplo en el que consultamos información de la función md5():

$ php --rf md5
Function [ <internal:standard> function md5 ] {
  - Parameters [2] {
    Parameter #0 [ <required> $str ]
    Parameter #1 [ <optional> $raw_output ]
  }
}

Una opción estupenda cuando no tenemos acceso a internet, ni nos hemos descargado la documentación de PHP a nuestro equipo.

9. Decorar la sintaxis de nuestro código

PHP nos ofrece una forma sencillísima de generar una versión HTML de nuestro código, coloreando y destacando cada parte. Sólo tendremos que ejecutarlo con el modificador “-w”. Una vez hecho esto, podremos exportarla al formato que queramos (PDF, Word, XHTML, etc). Muy útil cuando queremos imprimir un código fuente.

$ php -w fichero.php

Además, al estar disponible desde el propio binario de php, es muy fácil generar una versión HTML coloreada de cada fichero.

10. La joya de la corona: definir código inicial, final, y para cada línea

Si no tenías suficiente con sed o awk, ahora con PHP vas a poder hacer maravillas. Tenemos estos cuatro modificadores:

  1. “-B” – Código PHP a ejecutar antes que todo lo demás.
  2. “-F” – Código PHP a ejecutar cuando finalice todo lo demás.
  3. “-R” – Código PHP a ejecutar por cada línea. Tendremos $argn con la línea que se está procesando, y $argi con el número de línea.
  4. “-F” – Fichero con el código PHP a ejecutar por cada línea.

Veamos un ejemplo muy didáctico y muy poco útil de la documentación de PHP. Supongamos que queremos contar el número de líneas de un proyecto. Accedemos a su directorio y ejecutamos lo siguiente:

$ find . | php -B '$lineas=0;' -R '$lineas += count(@file($argn));' -E 'echo "Total de líneas: $lineas\n";'

Veámoslo paso a paso:

  1. En primer lugar ejecutamos el comando “find” de la consola de Linux. Nos mostrará (recursivamente) todos los ficheros del directorio actual.
  2. El resultado se lo pasamos por la entrada estándar al binario php, el cual realiza lo siguiente:
    1. En el modificador “-B” especificamos el código inicial. Simplemente inicializamos la variable $lineas a cero.
    2. En el modificador “-R” decimos lo que se hará por cada línea recibida por la entrada estándar. En este caso, cada línea se corresponde con la ruta a un fichero:
      1. Como vimos arriba, $argn contiene el texto que se está procesando. Contiene la ruta a un fichero
      2. Pasamos esa ruta a la función file(), que genera un array donde cada índice contiene una fila del fichero leído.
      3. Consultamos el tamaño del array, es decir, el número de líneas del fichero.
      4. Incrementamos la variable $lineas con el valor obtenido en el paso anterior.
    3. Finalmente, el modificador ‘-E’ se ejecuta al finalizar todo lo demás, y nos muestra como resultado el número total de líneas de texto que hay en todos los ficheros de la carpeta actual.

Sencillísimo y muy potente. Lo que más complicado puede resultar es recordar los 3 modificadores (B,F,R) y las dos variables ($argn y $argi).