Archivo de 'php'

Introducción a la programación en Facebook V

Quinta y última parte de esta guía introductoria al desarrollo de aplicaciones web sobre la Facebook Platform. Ya conoces el ecosistema de tecnologías de Facebook, sabes cómo crear distintos tipos de aplicaciones, y conoces el SDK JavaScript por completo. Hoy vamos a ver el PHP SDK.

Antes de seguir leyendo, puedes echar un vistazo a la página GitHub donde está alojado el proyecto PHP SDK, y desde donde te lo podrás descargar. Nosotros vamos a hablar sobre la última versión estable, la 3.1.0.


Read more

Introducción a la programación en Facebook

¿De modo que te han pedido que hagas una aplicación para Facebook y no sabes por dónde empezar? ¿Has llegado a la documentación oficial y te pierdes entre tanto Open Graph, SDK, plugins, dialogs y Graph API? Don’t panic! En este artículo vamos a ver paso a paso cómo empezar a programar en el nuevo sistema de Facebook. ¡Al lío!


Read more

Introducción a Doctrine 2

¡Hola! Últimamente sigo liado sumergiéndome en el mundo de ASP.NET, de ADO.NET, y sacando tiempo de debajo de las piedras para un pequeño proyecto en mi querido Zend Framework en PHP. Tras ver ADO.NET Entity Framework sentí la necesidad de usar algo igual en PHP; la solución se llama Doctrine :) La primera pregunta que nos deberíamos hacer es, qué es exactamente Doctrine. Respuesta rápida: Es un ORM de PHP. Pero analicémoslo un poco más.

En primer lugar, ¿qué diantres es un ORM? Viene de las siglas Object-relational mapping, que viene a traducirse como Mapeo objeto-relacional. En concreto es una técnica, o patrón arquitectónico, que permite comunicar dos sistemas distintos, típicamente una base de datos relacional con objetos de un lenguaje orientado a objetos, mediante un sistema que “mapea” (vincula) ambos sistemas. Mucha gente (yo mismo) ha creado a mano sus objetos mapeadores que, junto con objetos usando el patrón Active Record, daban un resultado muy similar a lo que un ORM nos ofrece. Pero oye, un ORM hace todo el trabajo sucio por nosotros ;)

Existen ORMs para la mayoría de lenguajes de programación. Por ejemplo, en Java es muy popular Hibernate, en .NET se utiliza ADO.NET Entity Framework, y en PHP el más usado es Doctrine (hay más). Doctrine está inspirado en Hibernate.

Pero veamos algunas de las características que nos ofrece un ORM como Doctrine 2:

  • Muy sencillo de configurar. De hecho, no es necesario mantener complejos ficheros de configuración XML.
  • Tiene su propio dialecto de SQL, llamado DQL (Doctrine Query Language).
  • Puede generar los modelos (las clases PHP que representan una fila de la BD) a partir de la base de datos. Sólo habría que definir las dependencias entre ellos
  • Del mismo modo, también puede generar la base de datos a partir de los modelos.

¡Fantástico! Él puede crear las tablas, y las consultas por nosotros. Pero veamos ahora lo sencillo que es usarlo:

/* Código de inicialización ... */
$user = new User();
$user->name = "john";
$user->password = "doe";
$em->persist($user);
$em->flush();

Para que este código funcione sólo tenemos que hacer dos cosas:

  1. Creamos el código de inicialización que cree el EntityManager $em. Es el objeto que en última instancia lleva a cabo las acciones.
  2. Definimos las entidades (módulos) especificando en comentarios (o en XML o en YAML) cómo se relaciona con la base de dato

Vamos a ver cómo instalarlo y después haremos un ejemplo sencillo en SQLite.

Instalación

Si bien podemos instalarlo a mano descargándolo desde la página de Doctrine, para esta guía asumiré que se ha instalado con PEAR. Para ello tenemos primer que instalar el canal:

sudo pear channel-discover pear.doctrine-project.org

Y después instalamos el ORM:

sudo pear install pear.doctrine-project.org/DoctrineORM-2.0.1

Ahora lo tenemos instalado. Podemos probar a ejecutar su utilidad de línea de comandos, y nos mostrará esto:

$ doctrine
Doctrine Command Line Interface version 2.0.1
Usage:
[options] command [arguments]
Options:
--help           -h Display this help message.
--quiet          -q Do not output any message.
--verbose        -v Increase verbosity of messages.
--version        -V Display this program version.
--ansi           -a Force ANSI output.
--no-interaction -n Do not ask any interactive question.
Available commands:
help                         Displays help for a command (?)
list                         Lists commands
dbal
:import                      Import SQL file(s) directly to Database.
:run-sql                     Executes arbitrary SQL directly from the command line.
orm
:convert-d1-schema           Converts Doctrine 1.X schema into a Doctrine 2.X schema.
:convert-mapping             Convert mapping information between supported formats.
:ensure-production-settings  Verify that Doctrine is properly configured for a production environment.
:generate-entities           Generate entity classes and method stubs from your mapping information.
:generate-proxies            Generates proxy classes for entity classes.
:generate-repositories       Generate repository classes from your mapping information.
:run-dql                     Executes arbitrary DQL directly from the command line.
:validate-schema             Validate that the mapping files.
orm:clear-cache
:metadata                    Clear all metadata cache of the various cache drivers.
:query                       Clear all query cache of the various cache drivers.
:result                      Clear result cache of the various cache drivers.
orm:schema-tool
:create                      Processes the schema and either create it directly on EntityManager Storage Connection or generate the SQL output.
:drop                        Drop the complete database schema of EntityManager Storage Connection or generate the corresponding SQL output.
:update                      Processes the schema and either update the database schema of EntityManager Storage Connection or generate the SQL output.

Demo básica

Para este apartado, voy a utilizar una demo Sandbox (entorno de pruebas) prácticamente igual que la que usan en la documentación de Doctrine 2. En este artículo encontrarás el código de todos los ficheros necesarios. Además, al final del mismo encontrarás un enlace para poder descargarlo.

El proyecto consiste de sólo 4 ficheros:

  • Entities/Users.php – Modelo de usuarios
  • Entities/Address.php – Modelo de dirección
  • cli-config.php – Fichero PHP que contiene el código de inicialización necesario para usar la utilidad en linea de comandos ‘doctrine’. Cada vez que usemos la utilidad ‘doctrine’, tendremos que tener este fichero.
  • index.php – Código de inicialización típico de una aplicación web que utilice Doctrine 2.

Vamos a echar un vistazo a los ficheros. En primer lugar veamos cómo es el archivo cli-config.php:

<?php
// (1) Autocargamos clases
require_once 'Doctrine/Common/ClassLoader.php';
$classLoader = new \Doctrine\Common\ClassLoader('Doctrine');
$classLoader->register();
$classLoader = new \Doctrine\Common\ClassLoader('Entities', __DIR__);
$classLoader->register();
$classLoader = new \Doctrine\Common\ClassLoader('Proxies', __DIR__);
$classLoader->register();

// (2) Configuración
$config = new \Doctrine\ORM\Configuration();

// (3) Caché
$cache = new \Doctrine\Common\Cache\ArrayCache();
$config->setMetadataCacheImpl($cache);
$config->setQueryCacheImpl($cache);

// (4) Driver
$driverImpl = $config->newDefaultAnnotationDriver(array(__DIR__."/Entities"));
$config->setMetadataDriverImpl($driverImpl);

// (5) Proxies
$config->setProxyDir(__DIR__ . '/Proxies');
$config->setProxyNamespace('Proxies');

// (6) Conexión
$connectionOptions = array(
'driver' => 'pdo_sqlite',
'path' => 'database.sqlite'
);

// (7) EntityManager
$em = \Doctrine\ORM\EntityManager::create($connectionOptions, $config);

// (8) HelperSet
$helperSet = new \Symfony\Component\Console\Helper\HelperSet(array(
'db' => new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($em->getConnection()),
'em' => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($em)
));

¡Que nadie se asuste! Realmente es un código muy sencillo, y prácticamente siempre se usará algo igual o muy parecido. Para superar el medio inicial, vamos a ver detalladamente qué es lo que ha pasado. El proceso de inicialización consta básicamente de dos pasos: Por una parte hay que asegurarse de que las clases de Doctrine pueden cargarse, y por otra hay que crear una instancia del Entity Manager. Siguiendo paso a paso:

  1. En primer lugar autocargamos las clases necesarias (nota: para esto podríamos haber utilizado el autocargador de otro framework). En concreto autocargaremos 3 secciones:
    1. El propio Doctrine, que trae Common, DBAL, ORM y Symfony. Si lo hemos instalado con PEAR, podremos verlo en el directorio /usr/share/php/Doctrine.
    2. Entities, que es el directorio en el que almacenaremos nuestros modelos.
    3. Proxies, otro espacio que es necesario definir. Los proxies son subclases de nuestros modelos que el propio Doctrine crea automáticamente.
  2. Una vez que nos hemos asegurado de que todas las clases pueden cargarse automáticamente, comenzamos a crear nuestro objeto EntityManager. Para ello, lo primero es crear un objeto de tipo Configuration.
  3. El primer parámetro que vamos a configurar es la caché. Podríamos haber usado APC, el sistema de cachés de facto de PHP (aconsejable en un entorno en producción), pero para pruebas usaremos el método ArrayCache.
  4. A continuación establecemos el driver con el que mapearemos nuestra base de datos. Esto es necesario para  hacer que nuestros modelos se correlacionen con nuestras bases de datos. Existen tres drivers disponibles:
    1. XML, desde donde se puede definir como encajar el modelo con la base de datos mediante sintaxis XML.
    2. YAML, al igual que con XML, también se puede definir utilizando YAML.
    3. Anotaciones, que en mi opinión son una maravilla. Mediante etiquetas en comentarios PHP defines cómo se mapean los datos. Más abajo, cuando lleguemos a los modelos, veremos un ejemplo de uso.
  5. Ahora configuramos los proxies. Simplemente establecemos su directorio, y su espacio de nombres.
  6. Conexión. Es aquí donde establecemos dónde se se encuentra nuestra base de datos. Si ésta no existiera, Doctrine la crearía por nosotros. En nuestro ejemplo usaremos SQLite.
  7. Ya está todo listo: hemos configurado la Caché, el Driver para mapear, los proxies y la conexión. Ya podemos crear el objeto EntityManager.
  8. Por último, creamos un objeto de tipo HelperSet, que es el que utilizará la utilidad de línea de comandos para saber cómo conectarse. El objeto HelperSet debe tener dos helpers: db, para identificar la conexión, y em, el EntityManager.

Ya tenemos listo el fichero cli-config.php, que como dijimos, es el que se utiliza para conectar la utilidad de consola ‘doctrine’ con nuestro proyecto.

Ahora vamos a ver los modelos.

Entities/Adress.php
<?php
namespace Entities;

/** @Entity @Table(name="addresses") */
class Address
{
   /**
    * @Id @Column(type="integer")
    * @GeneratedValue(strategy="AUTO")
    */
   private $id;

   /** @Column(type="string", length=255) */
   private $street;

   /** @OneToOne(targetEntity="User", mappedBy="address") */
   private $user;

   public function getId()
   {
      return $this->id;
   }

   public function getStreet()
   {
      return $this->street;
   }

   public function setStreet($street)
   {
      $this->street = $street;
   }

   public function getUser()
   {
      return $this->user;
   }

   public function setUser(User $user)
   {
      if ($this->user !== $user) {
         $this->user = $user;
         $user->setAddress($this);
      }
   }
}
Entities/User.php
<?php
namespace Entities;

/** @Entity @Table(name="users") */
class User
{
   /**
    * @Id @Column(type="integer")
    * @GeneratedValue(strategy="AUTO")
    */
   private $id;

   /** @Column(type="string", length=50) */
   private $name;

   /**
    * @OneToOne(targetEntity="Address", inversedBy="user")
    * @JoinColumn(name="address_id", referencedColumnName="id")
    */
   private $address;

   public function getId()
   {
      return $this->id;
   }

   public function getName()
   {
      return $this->name;
   }

   public function setName($name)
   {
      $this->name = $name;
   }

   public function getAddress()
   {
      return $this->address;
   }

   public function setAddress(Address $address)
   {
      if ($this->address !== $address) {
         $this->address = $address;
         $address->setUser($this);
      }
   }
}

No me detendré a explicar cómo se definen los modelos. En la propia documentación de Doctrine puedes ver una introducción al mapeo. Lo importante aquí es que, mediante etiquetas en los comentarios, hemos definido la relación entre la entidad User y la entidad Address, y también hemos definido cada una de sus columnas (¡hasta podemos indicar que una columna sea autoincremental!).

Llegados a este punto, tenemos 3 ficheros ya creados: cli-config.php, Entity/User.php y Entity/Address.php. Desde el raíz de nuestro proyecto vamos a ejecutar lo siguiente:

$ doctrine orm:schema-tool:create

Si todo ha ido bien, nos saldrá un mensaje indicándonos que el esquema de base de datos se ha creado correctamente. Y si comprobamos el directorio, veremos que se ha creado un nuevo fichero, database.sqlite, que contiene la definición de nuestras dos tablas.

Usándolo en una aplicación web

Bien, ya hemos definido las entidades, hemos creado la base de datos, y sabemos cómo funciona el código de inicialización de Doctrine 2. Ahora vamos a ver el fichero index.php:

<?php

// (1) Autocargamos clases
require_once 'Doctrine/Common/ClassLoader.php';
$classLoader = new \Doctrine\Common\ClassLoader('Doctrine');
$classLoader->register();
$classLoader = new \Doctrine\Common\ClassLoader('Entities', __DIR__);
$classLoader->register();
$classLoader = new \Doctrine\Common\ClassLoader('Proxies', __DIR__);
$classLoader->register();

// (2) Configuración
$config = new \Doctrine\ORM\Configuration();

// (3) Caché
$cache = new \Doctrine\Common\Cache\ArrayCache();
$config->setMetadataCacheImpl($cache);
$config->setQueryCacheImpl($cache);

// (4) Driver
$driverImpl = $config->newDefaultAnnotationDriver(array(__DIR__."/Entities"));
$config->setMetadataDriverImpl($driverImpl);

// (5) Proxies
$config->setProxyDir(__DIR__ . '/Proxies');
$config->setProxyNamespace('Proxies');

// (6) Conexión
$connectionOptions = array(
    'driver' => 'pdo_sqlite',
    'path' => 'database.sqlite'
);

// (7) EntityManager
$em = \Doctrine\ORM\EntityManager::create($connectionOptions, $config);

// (8) Código de prueba
$user = new \Entities\User();
$address = new \Entities\Address();

echo 'Hola mundo!' . PHP_EOL;

// Introduce aquí el código que maneje $user y $address

Si nos fijamos, los 7 primeros puntos son exactamente iguales que en cli-config.php. En el punto 8 creamos dos objetos de nuestro modelo, ya listos para usar. ¡Pero cuidado! Antes de poder hacer cambios en la base de datos SQLite, debes asegúrate de que el usuario de tu servidor web tiene permisos de escritura en el fichero database.sqlite. Ahora podríamos añadir el siguiente código de ejemplo:

$address->setStreet("Calle Río tinto, 12");
$em->persist($address);
$em->flush();

echo "Insertamos dirección<br />" . PHP_EOL;

$user->setName("Pedro");
$user->setAddress($address);
$em->persist($user);
$em->flush();

echo "Insertamos usuario<br />" . PHP_EOL;

Simplemente tenemos que acceder desde nuestro navegador a ese fichero (o también mediante “php index.php”) para que PHP ejecute el código. Una vez hecho, podemos consultar la base de datos mediante sqlite3:

$ sqlite3 database.sqlite
SQLite version 3.6.22
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> select * from addresses;
1|Calle Río tinto, 12
sqlite> select * from users;
1|1|Pedro

¡Lo ha hecho todo él sólo por nosotros! Así de sencillo resulta trabajar con bases de datos con un ORM :) A partir de aquí empieza lo bueno: ya puedes guardar tus objetos de forma persistente en base de datos, sin tener preocuparte ni por crear las tablas, ni por SQL, ni nada. Céntrate en PHP :)

¡Gracias por leer!

Descargar el código fuente

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).

Traducción de la documentación de PHP a Español

Hace (mucho) tiempo que vengo pensando en colaborar en algún proyecto de software libre. Al fin y al cabo, hace años que casi todo el software que utilizo es libre. Gran parte del resultado es gracias al trabajo desinteresado de mucha gente por todo el mundo.

Pensando en qué puedo y qué me apetece aportar, llegué a la conclusión de que el proyecto adecuado era PHP. No en vano es el proyecto de software libre que me da de comer :) Si Apache no existiera podría utilizar lighttpd. Si Linux no existiera me instalaría algún BSD. Si MySQL tampoco existiera, mi gestor de bases de datos probablemente sería postgresql. Sin Joomla! utilizaría Drupal. Sin Zend Framework usaría Codeigniter.

Y sin PHP… ¿¡qué haría yo sin PHP!? ¿Usar Python? Sí, pero noslomismo:) A PHP le tengo un cariño especial. Mi primera página web la hice ya en PHP, en el año 2003, y desde entonces no he parado de aprender.

Bien, el proyecto ya está elegido. Ahora, ¿qué puedo hacer yo por PHP? Ya quisiera yo tener nivel para poder aportar algo al core de PHP. Hoy por hoy donde creo que puedo ser más útil es traduciendo la documentación a español. De modo que me puse en contacto con Yago (yago[arroba]php.net), quien amablemente me indicó los pasos a seguir para formar parte del equipo de traducción.

Tras un breve training, consistente en traducir un par de documentos y emplear la herramienta oficial de traducción, ya estoy dentro. ¡Y muy ilusionado!

Por ahora ya he detectado unas cuantas ventajas:

  • Es agradecido ver que tu trabajo puede ayudar a otras personas.
  • Devuelves parte del favor que otros te han hecho al usar software libre.
  • Aprendes a trabajar en proyectos libres.
  • Puedes fardar de tener una cuenta @php.net (chuso[arroba]php.net).
  • En muchas empresas valoran que participes en proyectos libres.
  • Y lo más importante en mi opinión: Es una forma sensacional de no parar de aprender nuevas cosas de PHP.

¿Alguien más se anima? Actualmente la documentación española es la tercera más traducida, lejos de la japonesa y la francesa. ¡Toda ayuda será bienvenida!