Cómo aprender PHP

Como saben, me gano el pan haciendo aplicaciones web en PHP. Frecuentemente recibo preguntas de muchos tipos, así que intentaré contestar algunas.

Empezaremos con ésta: ¿Cómo puedo aprender PHP?

La respuesta más precisa es a la vez la más genérica: Tal como aprenderías cualquier otra nueva habilidad. Leyendo, investigando y practicando, practicando, practicando. Como en toda cosa valiosa, esto toma trabajo y esfuerzo duro. Como podrás leer a continuación, no todo es tan fácil como parece.

En primer lugar, hay una distinción importante que hacer: aprender PHP no es lo mismo que aprender a programar, así como aprender a escribir el abecedario no es lo mismo que aprender a escribir poesía.

– “Aprender PHP” es aprender la sintaxis del lenguaje, cómo se escribe un programa, cuáles son las funciones, sus estructuras de control, bucles, etc.
– “Aprender a programar” es aprender a resolver problemas usando un lenguaje de programación.

Muchas personas confunden ambas cosas, y cuando piensan en “aprender PHP” están metiendo ambos conceptos en la misma bolsa, y no es así. Tu primer paso es diferenciar ambas cosas.

Probablemente habrás sentido curiosidad por PHP al ver lo fácil que es, y es muy cierto. PHP es un lenguaje muy fácil de aprender. Pero ojo, eso no significa que aprender a programar sea igual de fácil.
Es por este motivo que muchos diseñadores web intentan hacer programas con PHP y el resultado no es una aplicación robusta, ni segura, ni escalable. [1] Es por ello que vemos muchos websites hackeados porque sus autores no saben programar. Saben PHP y no es lo mismo.

Entonces vamos a reformular nuestra pregunta: “¿Cómo puedo aprender a programar y aprender PHP?”

Eso está mejor, pero todavía está incompleto.

Verás, PHP es un lenguaje para programar aplicaciones web. Es cierto, se puede usar fuera del contexto de la web (cosa que personalmente hago a menudo), pero cuando nos referimos a “programar en PHP” estamos hablando de “programar una aplicación web.”

Entonces lo segundo que tenemos que aprender es cómo funciona la web. Debes ser capaz de entender los siguientes conceptos:

1) El concepto de cliente/servidor.
2) El protocolo “http”.
3) Métodos GET y POST — cómo funcionan y cómo se diferencian.
4) El lenguaje HTML.
5) Cómo funciona a grandes rasgos un navegador web.
6) Cómo funciona a grandes rasgos un servidor web.

Ya puedo ver sus caras de “TODO ESO TENGO QUE APRENDER!?” Como les dije en un principio, aprender PHP requiere trabajo y esfuerzo duro. Ok, pasemos a una pregunta más sensible: “¿Pero Jaime, es realmente necesario que conozca todo esto?” La respuesta es “No.”
Entonces, ¿por qué razón hago esta lista? Porque tarde o temprano la falta de estos conceptos te va a traer problemas. [2]

Depende mucho de hasta dónde quieres llegar. ¿Quieres hacer un par de cosillas con PHP, un contador por aquí, un gráfico al azar en la portada y nada más? Perfecto, no es necesario que te tragues esa lista.
¿O quieres ser un buen programador? ¿De aquellos que buscan la excelencia y definen el futuro? Oh, entonces coge tu taza de café y vamos a aprender lo que es necesario aprender. De tí depende.

Una vez que tengas los conceptos de la web bien aprendidos, el siguiente paso es aprender poco a poco PHP y poco a poco programar. Hay tutoriales regados por la web, varios en español inclusive. Te recomiendo que busques un tutorial que te enseñe primero lo básico del lenguaje. Aquí unos tips en tu aprendizaje:

1) No copies y pegues. Escribe cada uno de los ejemplos a mano. Debes ser capaz de poder escribir cientos de líneas de código a mano. Debes ser capaz de recordar la sintaxis de PHP. No quiero decir que debas saberte de memoria cada una de las funciones de PHP, llevo cerca de cinco años en esto y todavía tengo que consultar la sintaxis de str_replace. Lo que quiero es que te familiarices con la forma del lenguaje, de cada comando.

2) Lee todo el manual. Si, todo. O para ser más literales, échale un vistazo a todo el manual. Un desliz frecuente es implementar todo un programa y luego descubrir que había una función en PHP que hacía eso. La idea de echarle un vistazo a toda la librería de funciones es que sepas qué cosas hay disponibles, de modo que más adelante al menos puedas pensar: “Hmmm… me parece haber visto una función que hacía eso.”

3) Elige un pequeño proyecto. Piensa en algo que te sea útil y te gustaría tener, que sea sencillo y simple. Por ejemplo: una lista de direcciones web, una tabla de colores HTML, una lista de tus gastos, etc. Luego mira qué es lo que te falta saber para poder implementarlo y averigua cada cosa, un paso a la vez. “Ah, necesito saber cómo guardar cosas en un fichero,” entonces lee el manual de PHP sobre ello o busca en Google tutoriales. “Ok, necesito saber cómo guardar lo que escribí en esta caja de texto,” entonces mira el manual de PHP o busca en Google por algún tutorial.

Se me acabó el tiempo. Este post no pretende ser ninguna guía exhaustiva, a este paso creo que voy a terminar escribiendo un libro. Si tienen alguna pregunta o duda, escriban un comentario o un mail a j@jgwong.org. Les aviso que soy tardo para contestar, así que no desesperen.

Espero que esto les sea útil. La programación es fascinante.

Notas
[1] Debo aclarar que no tengo nada en contra de los diseñadores que deciden aprender PHP; todo lo contrario, les animo a que aprendan a programar lo cual les puede abrir innumerables puertas para competir con la mejor de las ventajas: la diferenciación.

[2] Las personas que carecen de estos conceptos fundamentales son los que más tarde tienen confusión entre el cliente y el servidor. Muchos se confunden pensando que PHP puede hacer lo mismo que Javascript, que PHP puede imprimir, etcétera. Esta es la sencilla razón.

Procesando mails con procmail y PHP

Este año quiero poner cosas más, um, edificantes en mi blog. Así que empezaré comentando esto que picó mi interés hace (muchas) semanas atrás.

Nestor Sertzen nos cuenta su forma de procesar mails usando procmail y PHP (y bash) aquí y aquí, sin embargo la forma cómo lo hace es un tanto ineficiente.

Su flujo básicamente es:

  • Recibir el correo con procmail
  • Pasarle el correo a un script en bash
  • El script en bash crea un fichero temporal con las últimas 5 líneas
  • El script en bash llama al script PHP con el nombre del fichero temporal
  • El script en PHP procesa la información y escribe a STDOUT, que está redireccionado a “/home/nestor/proceso”
  • El control regresa al script de bash, quien envía por mail el contenido de “/home/nestor/proceso”
  • Las ineficiencias principales son las siguientes:

    1) Usar bash para recortar las últimas 5 líneas del correo. Esto lo podemos hacer en el mismo script de PHP ya que de todas formas vamos a tener que recibir todo el mensaje.
    2) Usar un fichero temporal para pasarle las líneas a PHP. Bueno, esto no tiene mucho de malo, pero podemos evitar esto recibiendo de frente el mensaje con PHP.
    3) Esta falla si es grave: la redirección de la salida del script de PHP a “/home/nestor/proceso”. Si dos procesos PHP coinciden, uno puede chancar el fichero del otro. No hay una diferenciación por nombre como sí se hace previamente con el fichero temporal.
    4) El script de bash envía el resultado usando el comando “mail”. Esto también lo podemos hacer en el mismo PHP, con lo cual nos evitamos el posible conflicto descrito en el punto 3.

    Entonces, lo podemos mejorar de la siguiente forma:

  • Recibir el correo con procmail
  • Procesarlo todo con PHP
  • Profit!
  • El siguiente ejemplo está basado en un script mío llamado littlesister-getaddress.php. Lo que hace es recopilar el “From:” de todos los mails que me llegan.
    Mi script también es hackish, pero sirve de ejemplo. :)

    Llamamos al script de PHP directamente desde procmail:

    :0:
    * ^Subject.*(Numera)
    | /home/jgwong/bin/littlesister-getaddress.php
    

    Y en el script de PHP leemos todo el correo para procesarlo:

    #!/usr/bin/php
    <?php
    // Little Sister GetAddress 1.0
    // written by jaime g. wong <jaguar@paperclip.com.pe>
    
    $address_file = "/home/jgwong/.little-sister";
    
    $list = file ($address_file);
    
    $f = fopen ("php://stdin", "r");
    
    while ($line = fgets ($f)) {
        echo $line;
        
        if (preg_match ("/^From: (.+?)\$/", $line, $match)) {
            $email = trim ($match[1]);
            
            // ignore rules
            if (in_array ($email . "\n", $list) || strpos ($email, "orkut")) {
    //            echo "X-LittleSister: Found " . $email . "\n";
            }
            else {
                $e = fopen ($address_file, "a");
                fputs ($e, $email . "\n");
                fclose ($e);
            }
        }
    }
    
    ?>
    

    Lo importante del script es cómo se lee el contenido del mail desde procmail, que viene por STDIN y luego se procesa. No hay ficheros temporales intermedios, lo cual nos evita posibles conflictos. Escribimos en STDOUT el contenido recibido para que procmail siga con su flujo. Fíjense que hay un código comentado donde añadía una cabecera más al cuerpo del mail.

    Me quedé sin tiempo, mas espero que les sea útil. Si descargamos alguna librería para parsear mails (seguro hay alguna en PEAR) podemos hacer un poderoso script para procesar nuestros mails.

    Una idea que tengo para reducir mis distracciones en el trabajo es un filtro por importancia. Mi idea es retener mensajes no importantes por cierto tiempo e inyectarlos en mi buzón de entrada. Así los mensajes importantes (los del jefe, los de clientes VIP o cuentas especiales de notificación) sí pasan inmediatamente.