<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Mundo Geek &#187; php</title>
	<atom:link href="http://mundogeek.net/etiqueta/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://mundogeek.net</link>
	<description>Mundo geek, bitácora sobre todo lo geek: software, gadgets, tecnología, internet, ...</description>
	<lastBuildDate>Fri, 25 May 2012 14:51:34 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Depurar con Xdebug de forma remota estando detrás de un firewall</title>
		<link>http://mundogeek.net/archivos/2012/05/11/depurar-con-xdebug-de-forma-remota-estando-detras-de-un-firewall/</link>
		<comments>http://mundogeek.net/archivos/2012/05/11/depurar-con-xdebug-de-forma-remota-estando-detras-de-un-firewall/#comments</comments>
		<pubDate>Fri, 11 May 2012 15:55:00 +0000</pubDate>
		<dc:creator>Zootropo</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[depurador]]></category>
		<category><![CDATA[depurar]]></category>
		<category><![CDATA[firewall]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[remoto]]></category>
		<category><![CDATA[router]]></category>
		<category><![CDATA[ssh]]></category>
		<category><![CDATA[tunel]]></category>
		<category><![CDATA[xdebug]]></category>

		<guid isPermaLink="false">http://mundogeek.net/?p=8027</guid>
		<description><![CDATA[¿Quieres depurar tu código PHP con Xdebug pero te encuentras detrás de un router, un proxy o un firewall que no administras? Si puedes conectarte al servidor por SSH, no hay ningún problema: basta con utilizar un túnel SSH. Lo que haremos es modificar php.ini para que Xdebug envíe el tráfico al propio servidor remoto [...]]]></description>
			<content:encoded><![CDATA[<p>¿Quieres <a href="http://mundogeek.net/archivos/2009/12/11/depurar-php-con-xdebug/" title="Depurar PHP con Xdebug">depurar tu código PHP con Xdebug</a> pero te encuentras detrás de un router, un proxy o un firewall que no administras? Si puedes conectarte al servidor por SSH, no hay ningún problema: basta con utilizar un túnel SSH.</p>
<p>Lo que haremos es modificar php.ini para que <a href="http://xdebug.org/" title="Depurador para PHP XDebug">Xdebug</a> envíe el tráfico al propio servidor remoto (<code>xdebug.remote_host = localhost</code>) y lanzar un SSH desde nuestra máquina indicando al cliente que redireccione el tráfico del puerto 9000 del servidor (puerto por defecto de Xdebug) a un puerto de nuestra máquina donde nuestro IDE esté a la espera del depurador:<span id="more-8027"></span></p>
<p class="code">ssh -R 9000:localhost:9000 usuario@servidor.com</p>
<p>Si utilizas Windows y prefieres las aplicaciones gráficas, puedes utilizar indistintamente el cliente de SSH y telnet <a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/" title="PuTTY">PuTTY</a>, o cualquiera de sus alternativas, como mi favorito, <a href="http://mundogeek.net/archivos/2010/11/21/kitty-una-alternativa-a-putty/" title="KiTTy, una alternativa a PuTTY">KiTTy</a>. Sólo tenemos que introducir el servidor y el puerto al que queremos conectarnos en Session, y configurar el túnel en Connection -> SSH -> Tunnels. En Source port (puerto de orígen) introduciremos el puerto al que está enviando la información Xdebug en el servidor y en Destination (destino) la máquina y el puerto al que queremos redireccionarlo. Por último, marcaremos la casilla Remote (remoto) y, muy importante, pulsaremos el botón Add (Añadir) para confirmar la redirección.</p>
<div style="text-align:center"><img src="http://mundogeek.net/wp-content/tunel-ssh-xdebug.png" alt="Túnel SSH para depurar con Xdebug detrás de un firewall"/></div>
<p>Una vez hecho esto, ya podremos depurar el código con Xdebug aunque nos encontremos detrás de un firewall. Si no es así, activa la opción de registro de Xdebug  (<code>xdebug.remote_log = /ruta/archivo/log</code>) y comprueba que tu cliente SSH esté efectivamente escuchando en el puerto 9000 del servidor</p>
<p class="code">netstat -an | grep 9000</p>
]]></content:encoded>
			<wfw:commentRss>http://mundogeek.net/archivos/2012/05/11/depurar-con-xdebug-de-forma-remota-estando-detras-de-un-firewall/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Iteradores en PHP</title>
		<link>http://mundogeek.net/archivos/2012/04/12/iteradores-en-php/</link>
		<comments>http://mundogeek.net/archivos/2012/04/12/iteradores-en-php/#comments</comments>
		<pubDate>Thu, 12 Apr 2012 07:36:29 +0000</pubDate>
		<dc:creator>Zootropo</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[desarrollo]]></category>
		<category><![CDATA[iteradores]]></category>
		<category><![CDATA[iterator]]></category>
		<category><![CDATA[patrones]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[programacion]]></category>

		<guid isPermaLink="false">http://mundogeek.net/?p=7867</guid>
		<description><![CDATA[Iterador es uno de los patrones de diseño más conocidos, gracias al uso que hacen de él distintos lenguajes de programación, como Python, Java, C++ o el propio PHP. Básicamente, lo que propone este patrón es trasladar la responsabilidad de recorrer una colección a una clase nueva, que debe utilizar una interfaz estándar definida en [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://es.wikipedia.org/wiki/Iterador_%28patr%C3%B3n_de_dise%C3%B1o%29" title="Patrón Iterador">Iterador</a> es uno de los patrones de diseño más conocidos, gracias al uso que hacen de él distintos lenguajes de programación, como Python, Java, C++ o el propio PHP. Básicamente, lo que propone este patrón es trasladar la responsabilidad de recorrer una colección a una clase nueva, que debe utilizar una interfaz estándar definida en una clase abstracta o una interfaz, de forma que se pueda recorrer de forma similar tuplas de la base de datos, nodos de un documento XML, elementos de un array, o cualquier otro tipo de colección que se nos ocurra.</p>
<p>Para crear nuestro iterador en PHP tenemos que / podemos implementar la interfaz <a href="http://php.net/manual/es/class.iterator.php" title="Iterator"><code>Iterator</code></a>. Esto nos permitirá recorrer nuestra colección utilizando un <code>foreach</code>, por ejemplo. La interfaz <code>Iterator</code> declara los siguientes métodos:<span id="more-7867"></span></p>
<ul>
<li><code>abstract public void rewind(void)</code>: debe mover el puntero al primer elemento, sin devolver ningún valor</li>
<li><code>abstract public mixed current(void)</code>: debe devolver el valor actual</li>
<li><code>abstract public scalar key(void)</code>: devuelve la clave actual</li>
<li><code>abstract public void next(void)</code>: mueve el puntero al siguiente elemento</li>
<li><code>abstract public boolean valid(void)</code>: devuelve <code>true</code> si el iterador sigue siendo válido (no se ha alcanzado el final de la colección) y <code>false</code> en caso contrario</li>
</ul>
<p>Como ejemplo de iterador en PHP, vamos a implementar algo parecido a la clase <code>DatePeriod</code> de PHP 5.3, que permite iterar sobre los días de un periodo de fechas</p>
<pre name="code" class="php">&lt;?php
class Intervalo {
    public $inicio;
    public $fin;

    function __construct($inicio, $fin) {
        $this-&gt;inicio = strtotime($inicio);
        $this-&gt;fin = strtotime($fin);
    }
}</pre>
<pre name="code" class="php">&lt;?php
class IteradorPorDia implements Iterator {
	private $intervalo;

	function __construct(Intervalo $intervalo) {
		$this-&gt;intervalo = $intervalo;
	}

    function rewind() {
        $this-&gt;claveActual = 1;
        $this-&gt;fechaActual = $this-&gt;intervalo-&gt;inicio;
    }

    function key() {
        return $this-&gt;claveActual;
    }

    function current() {
        return date('Y-m-d', $this-&gt;fechaActual);
    }

    function next() {
        $this-&gt;claveActual++;
        $this-&gt;fechaActual = strtotime('+1 day', $this-&gt;fechaActual);
    }

    function valid() {
        return ($this-&gt;fechaActual &lt;= $this-&gt;intervalo-&gt;fin);
    }
}</pre>
<pre name="code" class="php">&lt;?php
require_once 'Intervalo.php';
require_once 'IteradorPorDia.php';

$intervalo = new Intervalo('2012-12-24', '2013-01-08');
$iterador = new IteradorPorDia($intervalo);
foreach($iterador as $num =&gt; $fecha)
	echo "El día $num del intervalo es $fecha&lt;br/&gt;";</pre>
<p>Si queremos seguir el patrón Iterador al pie de la letra (recomendado), haciendo que sea el agregado el que cree el iterador y lo devuelva, nuestra colección tendrá que implementar la interfaz <a href="http://php.net/manual/es/class.iteratoraggregate.php" title="IteratorAggregate"><code>IteratorAggregate</code></a> y su método <code>abstract public Traversable getIterator(void)</code>. Si hacemos esto podremos pasar la colección al <code>foreach</code> directamente, haciendo nuestro código cliente más sencillo y claro.</p>
<pre name="code" class="php">&lt;?php
require_once 'IteradorPorDia.php';

class Intervalo implements IteratorAggregate {
    public $inicio;
    public $fin;

    function __construct($inicio, $fin) {
        $this-&gt;inicio = strtotime($inicio);
        $this-&gt;fin = strtotime($fin);
    }

    public function getIterator() {
        return new IteradorPorDia($this);
    }
}</pre>
<pre name="code" class="php">&lt;?php
require_once 'Intervalo.php';

$intervalo = new Intervalo('2012-12-24', '2013-01-08');
foreach($intervalo as $num =&gt; $fecha)
	echo "El día $num del intervalo es $fecha<br/>";</pre>
<p>La librería estándar de PHP (SPL) también cuenta con varios <a href="http://www.php.net/manual/es/spl.iterators.php" title="Iteradores en SPL">iteradores predefinidos</a> que pueden ser interesantes, además de una serie de clases que permiten encadenar varios iteradores (<a href="http://www.php.net/manual/es/class.appenditerator.php" title="AppendIterator">AppendIterator</a>), filtrar valores no deseados (<a href="http://www.php.net/manual/es/class.filteriterator.php" title="FilterIterator">FilterIterator</a>), iterar indefinidamente (<a href="http://www.php.net/manual/es/class.infiniteiterator.php" title="InfiniteIterator">InfiniteIterator</a>), iterar sobre un subgrupo de elementos (<a href="http://www.php.net/manual/es/class.limititerator.php" title="LimitIterator">LimitIterator</a>) o iterar de forma recursiva (<a href="http://www.php.net/manual/es/class.recursiveiteratoriterator.php" title="RecursiveIteratorIterator">RecursiveIteratorIterator</a>).</p>
<link type="text/css" rel="stylesheet" href="http://mundogeek.net/sh/css/SyntaxHighlighter.css"></link>
<script language="javascript" src="http://mundogeek.net/sh/js/shCore.js"></script><script language="javascript" src="http://mundogeek.net/sh/js/shBrushPhp.js"></script><script language="javascript">dp.SyntaxHighlighter.ClipboardSwf = 'http://mundogeek.net/sh//flash/clipboard.swf';
dp.SyntaxHighlighter.HighlightAll('code');</script></p>
]]></content:encoded>
			<wfw:commentRss>http://mundogeek.net/archivos/2012/04/12/iteradores-en-php/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Symfony 2.0</title>
		<link>http://mundogeek.net/archivos/2011/07/28/symfony-2-0/</link>
		<comments>http://mundogeek.net/archivos/2011/07/28/symfony-2-0/#comments</comments>
		<pubDate>Thu, 28 Jul 2011 15:52:41 +0000</pubDate>
		<dc:creator>Zootropo</dc:creator>
				<category><![CDATA[Linklog]]></category>
		<category><![CDATA[frameworks]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://mundogeek.net/?p=7132</guid>
		<description><![CDATA[Les ha llevado bastante, pero el nuevo Symfony 2.0 es doblemente bueno]]></description>
			<content:encoded><![CDATA[<p>Les ha llevado bastante, pero el nuevo <a href="http://symfony.com/blog/symfony-2-0" title="Symfony 2.0">Symfony 2.0</a> es doblemente bueno</p>
]]></content:encoded>
			<wfw:commentRss>http://mundogeek.net/archivos/2011/07/28/symfony-2-0/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Variables globales</title>
		<link>http://mundogeek.net/archivos/2011/07/12/variables-globales/</link>
		<comments>http://mundogeek.net/archivos/2011/07/12/variables-globales/#comments</comments>
		<pubDate>Tue, 12 Jul 2011 15:03:38 +0000</pubDate>
		<dc:creator>Zootropo</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[codigo]]></category>
		<category><![CDATA[desarrollo]]></category>
		<category><![CDATA[globales]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[programacion]]></category>
		<category><![CDATA[variables]]></category>
		<category><![CDATA[variables globales]]></category>

		<guid isPermaLink="false">http://mundogeek.net/?p=7088</guid>
		<description><![CDATA[Una de las primeras cosas que se aprende al empezar a programar es que las variables globales son malvadas. Son casi tan despreciables como el infame goto, y (casi) nunca existen razones justificadas para utilizarlas. Martin Fowler lo expresa muy bien en su &#8220;Patterns of Enterprise Application Architecture&#8221; cuando dice que &#8220;cualquier variable global es [...]]]></description>
			<content:encoded><![CDATA[<p>Una de las primeras cosas que se aprende al empezar a programar es que <strong>las variables globales son malvadas</strong>. Son casi tan despreciables como el infame <code>goto</code>, y (casi) nunca existen razones justificadas para utilizarlas. Martin Fowler lo expresa muy bien en su &#8220;<a href="http://www.amazon.co.uk/gp/product/0321127420/ref=as_li_ss_tl?ie=UTF8&#038;tag=mundogeek-21&#038;linkCode=as2&#038;camp=1634&#038;creative=19450&#038;creativeASIN=0321127420">Patterns of Enterprise Application Architecture</a><img src="http://www.assoc-amazon.co.uk/e/ir?t=&#038;l=as2&#038;o=2&#038;a=0321127420" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />&#8221; cuando dice que <cite>&#8220;cualquier variable global es siempre culpable hasta que se demuestre lo contrario&#8221;</cite>. Pero, ¿por qué son tan odiadas las variables globales? ¿realmente son perjudiciales? ¿o se trata sólo de un odio irracional por parte de los puristas?<span id="more-7088"></span></p>
<p>Las dos formas más comunes de proporcionar una dependencia a una función son, por un lado, los parámetros de la función:</p>
<pre name="code" class="php">function insertarItem($db, $item) {
	// Haz algo
	// ...

	$db-&gt;insertar($item);

	// Haz más algo
	// ...
}</pre>
<p>y por otra parte, cualquier tipo de mecanismo de acceso global con el que contemos en el lenguaje (variables globales, patrón Singleton, etc). En este ejemplo en PHP utilizamos la palabra clave <code>global</code> para crear una variable local con una referencia a la variable global.</p>
<pre name="code" class="php">function insertarItem($item) {
	// Haz algo
	// ...

	global $db;
	$db->insertar($item);

	// Haz más algo
	// ...
}</pre>
<p>En principio podría parecer que no hay mucha diferencia entre ambos ejemplos. Nada más lejos de la realidad.</p>
<p>El primer problema con el que nos encontramos es que las variables globales ocultan las dependencias, y transportan la información de un lado a otro por arte de magia. Imagina que quieres utilizar la función <code>insertarItem</code> dentro de un año. Podrías pensar que puedes usarla de esta forma:</p>
<pre name="code" class="php">insertarItem($item);</pre>
<p>cuando, de hecho, la función puede estar esperando que hagas esto:</p>
<pre name="code" class="php">
$GLOBALS['db'] = new Db('localhost', 'mibbdd', 'usuario', 'pass');
$_SESSION['permisos'] = new Usuario()-&lt;permisos();
insertarItem($item);</pre>
<p>¿Cómo podrías saberlo sin tener que leer todo el código?</p>
<p>Otro problema es que es terriblemente difícil seguir sus cambios. Es posible que en algún momento crees otra variable global con el mismo nombre, y termines sobre escribiendo su valor sin percatarte, lo cuál generaría errores de lo más esotérico y de lo más difícil de depurar.</p>
<p>Las variables globales son malvadas por, al menos, 6 razones relacionadas:</p>
<ol>
<li>El código es más difícil de entender</li>
<li>El código es más difícil de depurar</li>
<li>El código es más difícil de testear</li>
<li>El código es más difícil de mantener</li>
<li>El código es más difícil de reutilizar</li>
<li>Las variables globales matan gatitos</li>
</ol>
<p>A pesar de todo puede tentarte usar variables globales para no tener que pasar el objeto <code>$db</code> a todas y cada una de las funciones que puedan necesitarlo, por ejemplo, y todas las funciones que llamen a funciones que puedan necesitarlo. En ese caso, en lugar de una colección de funciones con usos relacionados, puedes utilizar clases, y pasar la dependencia al objeto utilizando el constructor. Otras opciones son el uso de los patrones Abstract Factory, Service Locator o, mucho mejor, la inyección de dependencias (Dependency Injection, también llamado Inversion of Control).</p>
<p>Ojo, porque el patrón Singleton NO es una solución adecuada a este problema. Sí, es uno de los patrones explicados en <a href="http://mundogeek.net/archivos/2010/02/04/10-libros-miticos-sobre-programacion-que-todo-desarrollador-deberia-leer/" tile="10 libros míticos sobre programación que todo desarrollador debería leer">Design patterns: elements of reusable object-oriented software</a>, uno de los 10 libros míticos que todo programador debería leer, pero se suele abusar de él utilizándolo simplemente como una especie de variable global glorificada. Así las cosas, existen multitud de artículos que desaconsejan su utilización, e incluso Google desarrolló en su día un pequeño <a href="http://code.google.com/p/google-singleton-detector/">script para detectar el uso de singletons</a> y poder eliminarlos.</p>
<link type="text/css" rel="stylesheet" href="http://mundogeek.net/sh/css/SyntaxHighlighter.css"></link>
<script language="javascript" src="http://mundogeek.net/sh/js/shCore.js"></script><script language="javascript" src="http://mundogeek.net/sh/js/shBrushPhp.js"></script><script language="javascript">dp.SyntaxHighlighter.ClipboardSwf = 'http://mundogeek.net/sh//flash/clipboard.swf';
dp.SyntaxHighlighter.HighlightAll('code');</script></p>
]]></content:encoded>
			<wfw:commentRss>http://mundogeek.net/archivos/2011/07/12/variables-globales/feed/</wfw:commentRss>
		<slash:comments>30</slash:comments>
		</item>
		<item>
		<title>PHP in Action</title>
		<link>http://mundogeek.net/archivos/2011/06/27/php-in-action/</link>
		<comments>http://mundogeek.net/archivos/2011/06/27/php-in-action/#comments</comments>
		<pubDate>Mon, 27 Jun 2011 15:23:20 +0000</pubDate>
		<dc:creator>Zootropo</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[criticas]]></category>
		<category><![CDATA[desarrollo]]></category>
		<category><![CDATA[libros]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[programacion]]></category>
		<category><![CDATA[reviews]]></category>

		<guid isPermaLink="false">http://mundogeek.net/?p=7002</guid>
		<description><![CDATA[PHP in Action Calificación: Autores: Dagfinn Reiersol, Marcus Baker, Chris Shiflett Año: 2007 Editorial: ManningUna de las grandes ventajas con las que siempre ha contado PHP es la de ser un lenguaje tremendamente accesible. Es fácil de aprender y utilizar, cuenta con abundante documentación, y no existe servicio de hosting que se precie que no [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://mundogeek.net/wp-content/php-in-action.png" alt="PHP in Action" align="left" style="margin-right:1em"/><a href="http://www.amazon.co.uk/gp/product/1932394753/ref=as_li_ss_tl?ie=UTF8&#038;tag=mundogeek-21&#038;linkCode=as2&#038;camp=1634&#038;creative=19450&#038;creativeASIN=1932394753">PHP in Action</a><img src="http://www.assoc-amazon.co.uk/e/ir?t=&#038;l=as2&#038;o=2&#038;a=1932394753" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /><br />
Calificación: <img src="http://mundogeek.net/wp-content/themes/mg5/excelente.png"/><br />Autores: Dagfinn Reiersol, Marcus Baker, Chris Shiflett<br />
Año: 2007<br />
Editorial: Manning<br clear="all"/><br />Una de las grandes ventajas con las que siempre ha contado PHP es la de ser un lenguaje tremendamente accesible. Es fácil de aprender y utilizar, cuenta con abundante documentación, y no existe servicio de hosting que se precie que no lo tenga instalado por defecto. Este, a su vez, es el origen de uno de sus grandes males, y es que, al ser tan accesible, muchos de sus usuarios son pésimos programadores.<span id="more-7002"></span></p>
<p>Esto, unido a otros pecados como las inconsistencias en el nombrado de las funciones y el orden de los parámetros, ha convertido a PHP en un lenguaje con no muy buena fama. Seguramente, esto cambiaría drásticamente si más personas leyeran y aplicasen los conceptos que se explican en este <strong>PHP in Action</strong>.</p>
<p>PHP in Action es un compendio de técnicas modernas, conceptos, principios y consejos dirigidos a los profesionales que están interesados en convertirse en mejores programadores. No puede convertirte en un gran programador por sí sólo, pero puede sentar las bases.</p>
<p>El libro está dividido en 4 grandes partes claramente diferenciadas. Comienza con un repaso básico de la orientación a objetos, explicando los 5 <a href="http://mundogeek.net/archivos/2011/06/09/principios-solid-de-la-orientacion-a-objetos/" title="Principios SOLID de la orientación a objetos">principios SOLID</a> y algunos patrones de diseño clásicos como Strategy, Decorator o Composite; continúa con pruebas unitarias y funcionales, desarrollo guiado por pruebas (TDD) y refactorización; pasa a describir conceptos como el patrón MVC, el patrón Front controller o las plantillas, y termina con todo lo relacionado con bases de datos, desde cómo tener disponible la conexión en cualquier rincón del código sin usar globales o Singleton, a patrones comunes para CRUD, como Row Data Gateway o Active Record.</p>
<p>Si ya has leído &#8220;Agile Software Development, Principles, Patterns, and Practices&#8221;, &#8220;Design Patterns: Elements of Reusable Object-Oriented Software&#8221;, &#8220;Refactoring: Improving the Design of Existing Code&#8221; y &#8220;Patterns of Enterprise Application Architecture&#8221;, puede ser un buen repaso. Si todavía no has leído ninguno de estos libros, puedes empezar por este.</p>
]]></content:encoded>
			<wfw:commentRss>http://mundogeek.net/archivos/2011/06/27/php-in-action/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Obtener el número de fans en Facebook con PHP</title>
		<link>http://mundogeek.net/archivos/2011/06/12/obtener-el-numero-de-fans-en-facebook-con-php/</link>
		<comments>http://mundogeek.net/archivos/2011/06/12/obtener-el-numero-de-fans-en-facebook-con-php/#comments</comments>
		<pubDate>Sun, 12 Jun 2011 15:55:48 +0000</pubDate>
		<dc:creator>Zootropo</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[fans]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://mundogeek.net/?p=6932</guid>
		<description><![CDATA[En un artículo anterior explicaba cómo publicar en el muro de Facebook con PHP, cómo publicar eventos, y cómo publicar imágenes en el álbum de la página, utilizando siempre la API Graph. Obtener el número de fans que tenemos en Facebook es igual de sencillo. Primero necesitamos descargar los archivos de la API de Facebook [...]]]></description>
			<content:encoded><![CDATA[<p>En un artículo anterior explicaba cómo <a href="http://mundogeek.net/archivos/2011/03/08/api-de-facebook-con-php/" title="Publicar en el muro de Facebook con PHP">publicar en el muro de Facebook con PHP</a>, cómo publicar eventos, y cómo publicar imágenes en el álbum de la página, utilizando siempre la API Graph. Obtener el número de fans que tenemos en Facebook es igual de sencillo.</p>
<p>Primero necesitamos descargar los archivos de la <a href="https://github.com/facebook/php-sdk/" title="SDK PHP para la API Facebook">API de Facebook para PHP</a>, así como <a href="http://mundogeek.net/archivos/2011/03/08/api-de-facebook-con-php/" title="Obtener el id y el secreto de una aplicación Facebook">obtener el id y el secreto de aplicación</a>, tal como explicamos anteriormente.<span id="more-6932"></span></p>
<p>Una vez hecho esto, para obtener el número de fans que tenemos en Facebook, utilizaremos el siguiente código, sustituyendo, respectivamente, ID_APP por el id de aplicación, SECRETO por el secreto de aplicación, e ID_USUARIO por nuestro id de usuario.</p>
<pre name="code" class="php">
&lt;?php
require 'php-sdk/facebook.php';

$fb = new Facebook(array(
  'appId'  => 'ID_APP',
  'secret' => 'SECRETO',
  'cookie' => true
));

$res = $fb->api('/ID_USUARIO');
echo "Tienes {$res['likes']} fans";
</pre>
<p>El array asociativo <code>$res</code>, que devuelve esta consulta, incluye además el id de la cuenta (clave <code>id</code>), el nombre (<code>name</code>), la imagen (<code>picture</code>), la URL de nuestra página en Facebook (<code>link</code>), la categoría (<code>category</code>), la URL de nuestra página web (<code>website</code>), el nombre de usuario (<code>username</code>) y la descripción (<code>description</code>).</p>
<link type="text/css" rel="stylesheet" href="http://mundogeek.net/sh/css/SyntaxHighlighter.css"></link>
<script language="javascript" src="http://mundogeek.net/sh/js/shCore.js"></script><script language="javascript" src="http://mundogeek.net/sh/js/shBrushPhp.js"></script><script language="javascript">dp.SyntaxHighlighter.ClipboardSwf = 'http://mundogeek.net/sh//flash/clipboard.swf';
dp.SyntaxHighlighter.HighlightAll('code');</script></p>
]]></content:encoded>
			<wfw:commentRss>http://mundogeek.net/archivos/2011/06/12/obtener-el-numero-de-fans-en-facebook-con-php/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>El lenguaje de los grandes programadores</title>
		<link>http://mundogeek.net/archivos/2011/05/08/el-lenguaje-de-los-grandes-programadores/</link>
		<comments>http://mundogeek.net/archivos/2011/05/08/el-lenguaje-de-los-grandes-programadores/#comments</comments>
		<pubDate>Sun, 08 May 2011 12:42:22 +0000</pubDate>
		<dc:creator>Zootropo</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[haskell]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[lenguajes]]></category>
		<category><![CDATA[lenguajes de programacion]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[programacion]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://mundogeek.net/?p=6738</guid>
		<description><![CDATA[Hace un par de días comenzaba una nueva edición del Code Jam de Google, la famosa competición de programación que la empresa viene organizando desde hace ya 8 años. A parte de proporcionar una gran selección de problemas con los que practicar nuestras habilidades, sus estadísticas también pueden servirnos para comprobar cuáles son los lenguajes [...]]]></description>
			<content:encoded><![CDATA[<p>Hace un par de días comenzaba una nueva edición del <a href="http://code.google.com/codejam/" title="Google Code Jam">Code Jam</a> de Google, la famosa competición de programación que la empresa viene organizando desde hace ya 8 años. A parte de proporcionar una gran selección de problemas con los que <a href="http://mundogeek.net/archivos/2011/03/02/katas-de-codigo/" title="Katas de código">practicar nuestras habilidades</a>, sus <a href="http://www.go-hero.net/jam/11/languages" title="Estadísticas Google Code Jam">estadísticas</a> también pueden servirnos para comprobar cuáles son los lenguajes de programación preferidos por los desarrolladores, y qué lenguajes utilizan los mejores programadores (sobre una muestra de 12.200 participantes).<span id="more-6738"></span></p>
<p>Empecemos con los lenguajes más utilizados. Estos podrían ser los lenguajes cuyas sintaxis y características gustan más, o, simplemente, aquellos con los que están más familiarizados los participantes. Como vemos, C++ es, con mucha diferencia, el lenguaje más popular, seguido a larga distancia de Java y <a href="http://mundogeek.net/tutorial-python/" title="Python para todos, mi libro sobre programación en Python">Python</a>.</p>
<div style="text-align:center"><img src="http://mundogeek.net/wp-content/lenguajes-programacion-mas-utilizados.png" alt="Lenguajes de programación más utilizados"/></div>
<p>Pasamos a continuación a los lenguajes con mayor porcentaje de programadores capaces. Vemos que el porcentaje de programadores que consiguieron la puntuación suficiente para pasar de fase es altísimo en el caso de C++ y Haskell (90,8% y 90,68%), mientras que el porcentaje de programadores aprobados en el caso de <a href="http://mundogeek.net/archivos/2009/11/26/tutorial-rapido-de-php/" title="Tutorial rápido de PHP">PHP</a> (lenguaje con el que yo me gano las lentejas actualmente) es alarmantemente bajo en comparación (76,5%).</p>
<div style="text-align:center"><img src="http://mundogeek.net/wp-content/mejores-lenguajes-programacion.png" alt="Mejores lenguajes de programación"/></div>
<p>Por último, veamos el porcentaje de programadores que consiguieron la puntuación perfecta, agrupados por lenguaje de programación. Aquí Haskell se distancia bastante de C++, y mucho más del resto de lenguajes, quizás por la llamada <a href="http://mundogeek.net/archivos/2007/10/23/la-paradoja-python/">paradoja Python</a>. PHP, por su parte, se mantiene con el dudoso honor de ser el lenguaje con peor porcentaje de programadores con puntuaciones perfectas.</p>
<div style="text-align:center"><img src="http://mundogeek.net/wp-content/mejores-lenguajes.png" alt="Lenguajes de programación con los mejores programadores"/></div>
]]></content:encoded>
			<wfw:commentRss>http://mundogeek.net/archivos/2011/05/08/el-lenguaje-de-los-grandes-programadores/feed/</wfw:commentRss>
		<slash:comments>45</slash:comments>
		</item>
		<item>
		<title>API de Facebook con PHP</title>
		<link>http://mundogeek.net/archivos/2011/03/08/api-de-facebook-con-php/</link>
		<comments>http://mundogeek.net/archivos/2011/03/08/api-de-facebook-con-php/#comments</comments>
		<pubDate>Tue, 08 Mar 2011 17:34:29 +0000</pubDate>
		<dc:creator>Zootropo</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[album]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[eventos]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[muro]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://mundogeek.net/?p=6478</guid>
		<description><![CDATA[Esta mañana he tenido que dedicar un buen rato a lidiar con los caprichos de la API de Facebook, API que no había tenido necesidad de utilizar nunca, y cuya documentación, si hemos de ser sinceros, no me ha dejado un buen sabor de boca. Por eso, por si alguno os encontrarais alguna vez con [...]]]></description>
			<content:encoded><![CDATA[<p>Esta mañana he tenido que dedicar un buen rato a lidiar con los caprichos de la API de Facebook, API que no había tenido necesidad de utilizar nunca, y cuya documentación, si hemos de ser sinceros, no me ha dejado un buen sabor de boca. Por eso, por si alguno os encontrarais alguna vez con cualquier complicación al intentar publicar una nota en el muro, subir una imagen al álbum o publicar un evento usando PHP, os dejo una pequeña explicación de cómo lo he hecho yo. Procedimiento que no tiene por qué ser el mejor o ser si quiera correcto, ojo: si tenéis cualquier sugerencia, os espero en los comentarios.<span id="more-6478"></span></p>
<p>Lo primero que necesitaremos, evidentemente, es la API oficial de Facebook, que podemos <a href="https://github.com/facebook/php-sdk/">descargar desde GitHub</a>. Descomprimimos el archivo y lo subimos a nuestro servidor.</p>
<p>También necesitamos crear una aplicación, que será la encargada de llevar a cabo estas operaciones sobre nuestra cuenta de usuario o de marca. Para ello os podéis dirigir <a href="https://www.facebook.com/developers/apps.php">al sitio web de desarrolladores de Facebook</a>, donde os pedirán amablemente que validéis vuestra cuenta, bien introduciendo vuestro teléfono móvil, para que os envíen un código de confirmación, o bien introduciendo vuestro número de cuenta. En serio, es escalofriante, pero ya sabemos todos como es Facebook.</p>
<p>Una vez hayáis creado la aplicación, podréis consultar el id de la aplicación y la clave secreta de aplicación en esa misma página. Estos son dos de los datos que vamos a necesitar, así que tenerlos a mano.</p>
<p>Lo siguiente que necesitamos es que nuestro usuario dé permisos a nuestra aplicación para poder interactuar con nuestra cuenta. Esto lo podemos hacer de forma sencilla utilizando una URL especialmente diseñada a tal efecto, que tendrá el siguiente aspecto:</p>
<blockquote><p>https://graph.facebook.com/oauth/authorize?type=user_agent&#038;<br />
    client_id=<em>ID_APLICACION</em>&#038;<br />
    redirect_uri=http://www.facebook.com/connect/login_success.html&#038;<br />
    scope=offline_access,manage_pages,publish_stream,create_event</p></blockquote>
<p>donde:</p>
<ul>
<li><code>client_id</code> es el id de la aplicación, que habíamos apuntado en el paso anterior</li>
<li><code>redirect_uri</code> es la página a la que redireccionar el navegador una vez hayamos dado los permisos a la aplicación</li>
<li>y <code>scope</code> es una lista de permisos, cuyos posibles valores podemos consultar <a href="http://developers.facebook.com/docs/authentication/permissions/">en la documentación al respecto</a>. El permiso <code>offline_access</code> es uno de los más importantes: permite que el token que nos va a pasar Facebook para autenticarnos no caduque, incluso cuando el usuario esté desconectado. Si quieres interactuar con las páginas que gestiona tu usuario, en lugar, o además de con tu propia cuenta personal, necesitarás requerir también el permiso <code>manage_pages</code></li>
</ul>
<div style="text-align:center"><img src="http://mundogeek.net/wp-content/permisos-aplicacion-facebook.png" alt="Dando permisos a nuestra aplicación PHP para Facebook"/></div>
<p>Al cargar la URL en tu navegador y pulsar &#8216;Permitir&#8217;, si no ha pasado nada raro, Facebook debería redirigirte a la página que indicaste como valor de <code>redirect_uri</code>, añadiendo a esta un parámetro <code>access_token</code>, que es el que utilizaremos para identificarnos, y otro <code>expires_in</code>, que nos informa de que el token de acceso no va a caducar.</p>
<p>Para comprobar que todo funciona correctamente puedes intentar cargar la siguiente URL:</p>
<blockquote><p>https://graph.facebook.com/me?access_token=<em>ACCESS_TOKEN</em></p></blockquote>
<p>Si el token de acceso es el adecuado, Facebook nos mostrará un objeto JSON con la información de nuestra cuenta de usuario. En caso contrario, mostrará un objeto JSON informando del error.</p>
<p>Ahora bien, si queremos interactuar con las páginas de marca que administremos, en lugar de con nuestra página personal, necesitaremos un access token distinto. Para obtenerlo preguntaremos a Facebook por la información de las distintas páginas y aplicaciones que administramos utilizando la URL:</p>
<blockquote><p>https://graph.facebook.com/me/accounts?access_token=<em>ACCESS_TOKEN</em></p></blockquote>
<p>Listo. Ahora sí, ya estamos preparados para empezar a jugar con la API de Facebook. Para publicar en el muro, crear eventos y subir imágenes en Facebook utilizaremos la clase del mismo nombre, a cuyo constructor le pasamos un array con el identificador de nuestra aplicación y su secreto:</p>
<pre name="code" class="php">$fb = new Facebook(array(
  'appId'  => 'ID_APP',
  'secret' => 'SECRETO',
  'cookie' => true
));</pre>
<p>El método que nos interesa de esta clase es <code>api</code>, que normalmente tendrá como primer parámetro una cadena del tipo <code>"/<em>ID_USUARIO</em>/<em>SERVICIO</em>"</code> o <code>"/<em>ID_PAGINA</em>/<em>SERVICIO</em>"</code>. El segundo parámetro es siempre el método a utilizar (POST o GET), y el tercero, un array con los argumentos necesarios para ese servicio.</p>
<p>Para publicar algo en el muro, por ejemplo, utilizaríamos como primer parámetro una cadena <code>"/<em>ID_USUARIO</em>/feed"</code> y como tercer parámetro, un array con claves <code>message</code> (el mensaje a publicar) y <code>access_token</code>, siendo este último el valor que obtuvimos anteriormente para identificar a nuestro usuario o alguna de las páginas de marca que administramos (OJO: el token de acceso del usuario no sirve para identificar a la página, evidentemente, y viceversa).</p>
<pre name="code" class="php">$fb = new Facebook(array(
  'appId'  =&gt; 'ID APLICACION',
  'secret' =&gt; 'SECRETO',
  'cookie' =&gt; true
));

$params = array(
    'access_token' =&gt; 'TOKEN ACCESO',
    'message' => 'Hola mundo'
);
$res = $fb->api('/ID_USUARIO</em>/feed', 'POST', $params);
if(!$res)
    echo 'Ha ocurrido un error indeterminado';
elseif($res->error)
    echo "Ha ocurrido un error: {$res->error}";
else
    echo "OK";
</pre>
<p>Para terminar, os dejo una pequeña clase con la que podréis publicar en el muro, subir una imagen o crear un evento fácilmente:</p>
<pre name="code" class="php">
&lt;?php
require_once 'facebook.php';

/**
 * Clase para facilitar el trabajo con Facebook. Proporciona métodos para
 * publicar imágenes en un álbum, notas en el muro, y eventos
 *
 * Ejemplos de uso:
 * $fb = new Fb();
 * $fb-&gt;publicarNota('Prueba');
 * $fb-&gt;publicarImagen('/home/zootropo/html/imagenes/mi-imagen.jpg');
 * $fb-gt;publicarEvento('Prueba de evento', 'Descripción del evento', '2011-03-08');
 */
class Fb {
    const ID_APP = 'ID APLICACION';
    const SECRETO = 'SECRETO APLICACION';
    const ACCESS_TOKEN = 'TOKEN ACCESO';
    const ID_ALBUM = 'ID ALBUM';
    const ID_PAGINA = 'ID PAGINA';
    private $fb;

    /**
     * Constructor de la clase. Crea el objeto Facebook que utilizaremos
     * en los métodos que interactúan con la red social
     */
    function __construct() {
        $this-&gt;fb = new Facebook(array(
          'appId'  =&gt; self::ID_APP,
          'secret' =&gt; self::SECRETO,
          'cookie' =&gt; true
        ));
    }

    /**
     * Publica un evento
     * @param string $titulo Título del evento
     * @param string $descripcion Descripción del evento
     * @param string $inicio Fecha o fecha y hora de inicio del evento, en formato ISO-8601 o timestamp UNIX
     * @return bool Indica si la acción se llevó a cabo con éxito
     */
    function publicarEvento($titulo, $descripcion, $inicio) {
        $params = array(
            'access_token' =&gt; self::ACCESS_TOKEN,
            'name' =&gt; $titulo,
            'description' =&gt; $descripcion,
            'start_time' =&gt; $inicio,
        );
        $res = $this-&gt;fb-&gt;api('/'.self::ID_PAGINA.'/events', 'POST', $params);
        if(!$res or $res-&gt;error)
            return false;

        return true;
    }

    /**
     * Publica una nota en el muro de la página
     * @param string $mensaje
     * @return bool Indica si la acción se llevó a cabo con éxito
     */
    function publicarNota($mensaje) {
        $params = array(
            'access_token' =&gt; self::ACCESS_TOKEN,
            'message' =&gt; $mensaje
        );
        $res = $this-&gt;fb-&gt;api('/'.self::ID_PAGINA.'/feed', 'POST', $params);
        if(!$res or $res-&gt;error)
            return false;

        return true;
    }

    /**
     * Publica una imagen en el álbum de la página
     * @param string $ruta Ruta absoluta a la imagen en nuestro servidor
     * @param string $mensaje Mensaje a mostrar en el muro, si queremos avisar
     * de la subida de la imagen
     * @return bool Indica si la acción se llevó a cabo con éxito
     */
    function publicarImagen($ruta, $mensaje='') {
        $this-&gt;fb-&gt;setFileUploadSupport(true);

        $params = array(
            'access_token' =&gt; self::ACCESS_TOKEN,
            'source' =&gt; "@$ruta"
        );
        if($mensaje) $params['message'] = $mensaje;

        $res = $this-&gt;fb-&gt;api('/'.self::ID_ALBUM.'/photos', 'POST', $params);
        if(!$res or $res-&gt;error)
            return false;

        return true;
    }
}</pre>
<link type="text/css" rel="stylesheet" href="http://mundogeek.net/sh/css/SyntaxHighlighter.css"></link>
<script language="javascript" src="http://mundogeek.net/sh/js/shCore.js"></script><br />
<script language="javascript" src="http://mundogeek.net/sh/js/shBrushPhp.js"></script><br />
<script language="javascript">dp.SyntaxHighlighter.ClipboardSwf = 'http://mundogeek.net/sh//flash/clipboard.swf';
dp.SyntaxHighlighter.HighlightAll('code');</script></p>
]]></content:encoded>
			<wfw:commentRss>http://mundogeek.net/archivos/2011/03/08/api-de-facebook-con-php/feed/</wfw:commentRss>
		<slash:comments>54</slash:comments>
		</item>
		<item>
		<title>El Paamayim nekudotayim de PHP</title>
		<link>http://mundogeek.net/archivos/2011/01/29/el-paamayim-nekudotayim-de-php/</link>
		<comments>http://mundogeek.net/archivos/2011/01/29/el-paamayim-nekudotayim-de-php/#comments</comments>
		<pubDate>Sat, 29 Jan 2011 10:38:06 +0000</pubDate>
		<dc:creator>Zootropo</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[curiosidades]]></category>
		<category><![CDATA[desarrollo]]></category>
		<category><![CDATA[paamayim nekudotayim]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[programacion]]></category>

		<guid isPermaLink="false">http://mundogeek.net/?p=6335</guid>
		<description><![CDATA[No, este título tan raro no es producto de un deface de algún hacker indio. Es hebreo (פעמיים נקודתיים), significa doble dos puntos, y es el nombre que recibe el token utilizado por el analizador léxico y el analizador sintáctico de PHP para representar el operador de resolución de ámbito del lenguaje (::), un operador [...]]]></description>
			<content:encoded><![CDATA[<p>No, este título tan raro no es producto de un <a href="http://es.wikipedia.org/wiki/Defacement" title="Definición de defacement en la Wikipedia">deface</a> de algún hacker indio. Es hebreo (פעמיים נקודתיים), significa doble dos puntos, y es el nombre que recibe el <a href="http://docs.php.net/manual/es/tokens.php" title="Lista de tokens de análisis">token</a> utilizado por el analizador léxico y el analizador sintáctico de PHP para representar el <a href="http://docs.php.net/manual/es/keyword.paamayim-nekudotayim.php" title="Operador de Resolución de Alcance (::)">operador de resolución de ámbito</a> del lenguaje (::), un operador que se utiliza para acceder a miembros estáticos de una clase, y a propiedades y métodos que han sido sobreescritos por una clase al heredar de otra.</p>
<p>&#8220;¿Y por qué hebreo?&#8221;, se preguntará alguno. El motivo es sencillo, y es que, como ya vimos en <a href="http://mundogeek.net/archivos/2011/01/26/una-no-tan-breve-historia-de-php/" title="Una no tan breve historia de PHP">Una no tan breve historia de PHP</a>, Zeev Suraski y Andi Gutmans, los dos programadores que crearon el Zend Engine, son ambos israelíes.<span id="more-6335"></span></p>
<p>Os podéis encontrar con este nombre tan críptico, por ejemplo, al utilizar el operador condicional ternario y repetir el carácter de dos puntos por accidente. Si probáis a ejecutar el siguiente código:</p>
<pre name="code" class="php">&lt;?php
$modo = $_SERVER['SERVER_NAME']!=='localhost'?'Debug'::'Producción';</pre>
<p>PHP os responderá con un mensaje parecido a este:</p>
<blockquote><p>Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM in /usr/local/apache/htdocs/ejemplo.php on line 2</p></blockquote>
<link type="text/css" rel="stylesheet" href="http://mundogeek.net/sh/css/SyntaxHighlighter.css"></link>
<script language="javascript" src="http://mundogeek.net/sh/js/shCore.js"></script><br />
<script language="javascript" src="http://mundogeek.net/sh/js/shBrushPhp.js"></script><br />
<script language="javascript">dp.SyntaxHighlighter.ClipboardSwf = 'http://mundogeek.net/sh//flash/clipboard.swf';
dp.SyntaxHighlighter.HighlightAll('code');</script></p>
]]></content:encoded>
			<wfw:commentRss>http://mundogeek.net/archivos/2011/01/29/el-paamayim-nekudotayim-de-php/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Una no tan breve historia de PHP</title>
		<link>http://mundogeek.net/archivos/2011/01/26/una-no-tan-breve-historia-de-php/</link>
		<comments>http://mundogeek.net/archivos/2011/01/26/una-no-tan-breve-historia-de-php/#comments</comments>
		<pubDate>Wed, 26 Jan 2011 09:50:17 +0000</pubDate>
		<dc:creator>Zootropo</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[historia]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://mundogeek.net/?p=6326</guid>
		<description><![CDATA[En la prehistoria A principios de los años 90 Tim Berners-Lee estableció las bases de la World Wide Web cuando desarrolló, mientras trabajaba en el CERN, el primer servidor web (CERN httpd) y el primer navegador de la historia (WorldWideWeb, más tarde rebautizado como Nexus). Durante los primeros meses, la web consistió en una pequeña [...]]]></description>
			<content:encoded><![CDATA[<h2>En la prehistoria</h2>
<p>A principios de los años 90 Tim Berners-Lee estableció las bases de la World Wide Web cuando desarrolló, mientras trabajaba en el CERN, el primer servidor web (<a href="http://www.w3.org/Daemon/" title="CERN httpd, el primer servidor web de la historia">CERN httpd</a>) y el primer navegador de la historia (<a href="http://www.w3.org/People/Berners-Lee/WorldWideWeb.html" title="WorldWideWeb, el primer navegador web de la historia">WorldWideWeb</a>, más tarde rebautizado como Nexus). Durante los primeros meses, la web consistió en una pequeña gran colección de documentos estáticos escritos en HTML, pero no pasó mucho tiempo antes de que Robert McCool y su equipo del NCSA pensaran en la posibilidad de poder responder a las peticiones del navegador con el resultado de la ejecución de pequeños programas, permitiendo así al servidor web una mayor interacción con el usuario.<span id="more-6326"></span></p>
<p>Así nació en 1993 CGI (Common Gateway Interface), como parte del servidor NCSA HTTPd, que más tarde daría origen al famoso Apache. Esta tecnología, que aún se utiliza ampliamente en los servidores web debido a su sencillez, definía una interfaz común mediante la cuál el servidor web, y por tanto el cliente, podía comunicarse con un programa situado en el servidor, utilizando para ello variables de entorno predefinidas, argumentos de línea de comandos, y la entrada y salida estándar. La mayoría de estos programas estaban escritos en C o en Perl.<br />
<hr style="border:0;border-top:1px dotted #444;width:85%"/>
<h2 style="margin-top:2.5em">El nacimiento de PHP</h2>
<p>Y así llegamos a una tarde de otoño de 1994, en la que un programador danés en paro afincado en Toronto (Canadá), Rasmus Lerdof, se pone manos a la obra para escribir un pequeño CGI en Perl que le ayude a contabilizar las visitas que llegan a su currículum vitae, guardando este valor en una base de datos mSQL. Más tarde, como el servidor web en el que se alojaba tenía algún problema de rendimiento, Rasmus decide reescribir su script en C, para ahorrarse la carga de tener que crear un nuevo proceso de Perl cada vez que alguien visitara su web.</p>
<p>El pequeño script de Rasmus llama la atención de otras personas alojadas en su mismo servidor, que le piden poder utilizarlo, y van sugiriendo cada vez más y más funcionalidades. De esta forma, acaba con una pequeña colección de 30 scripts distintos, que decide combinar en una única librería C.</p>
<p>El siguiente paso es escribir un sencillo analizador sintáctico que busque etiquetas en el código HTML y las reemplace con la salida de las funciones correspondientes de su pequeña librería. Este analizador sintáctico va aumentando en complejidad, y Rasmus añade etiquetas condicionales, etiquetas de bucles y funciones. El danés bautizó este paquete de software, junto con algunas utilidades de uso común por esas fechas, como un libro de visitas y un contador, con el nombre de Personal Home Page Tools (Herramientas para Página de Inicio Personal) o PHP Tools.</p>
<p>Además, de forma paralela, Rasmus empieza a desarrollar otro CGI que analizaría consultas SQL, y facilitaría crear los formularios y las tablas correspondientes. Esta herramienta se llamó FI (Form Interpreter), y al conjunto de ambos paquetes PHP/FI.</p>
<p>Con todo ya listo, y tras crear una lista de correo y un pequeño FAQ, el 8 de Junio de 1995, Rasmus <a href="http://groups.google.com/group/comp.infosystems.www.authoring.cgi/msg/cc7d43454d64d133" title="Anuncio de PHP 1.0 en los grupos de noticias">anuncia la primera versión oficial de PHP</a> en los grupos de noticias. Esta primera versión, publicada bajo la licencia GPL, sólo corría en servidores UNIX y carecía de características tan básicas como el bucle <code>for</code>.</p>
<p>No obstante, el número de usuarios comienza a crecer, y algunos programadores empiezan a ayudar en el proyecto. PHP y FI se combinan creando un único binario, se reescribe el analizador sintáctico, y el paquete se renombra a Personal Home Page Construction Kit (Kit de Construcción de Páginas Personales). Con esto llegamos a la publicación de PHP/FI 2.0, el 1 de Noviembre de 1997, con una base de usuarios de unas 50.000 personas.<br />
<hr style="border:0;border-top:1px dotted #444;width:85%"/>
<h2 style="margin-top:2.5em">La contribución de Zend</h2>
<p>Con la versión 3.0, lanzada el 6 de Junio de 1998, bajo una licencia dual GPL &#8211; PHP License, el lenguaje daría un salto de gigante en cuanto a rendimiento, funcionalidad y popularidad, alcanzando el millón de usuarios. Esto fue posible en gran parte gracias a la colaboración de Zeev Suraski y Andi Gutmans, dos programadores israelíes que descubrieron PHP/FI 2.0 cuando buscaban una herramienta para desarrollar una aplicación de comercio electrónico para la universidad, y que más tarde fundarían la famosa Zend Technologies, llamada así por la contracción de sus nombres de pila.</p>
<p>Zeev y Andi volvieron a reescribir el analizador sintáctico de PHP y contribuyeron en la reescritura de buena parte del resto de su código. También diseñaron una nueva API que permitía crear extensiones para PHP, atrayendo así la atención de un gran número de programadores.</p>
<p>Otras novedades de esta versión, lanzada para Windows 95, Windows NT, Macintosh y varias versiones de UNIX, fue la introducción de una muy básica orientación a objetos, el soporte para los sistemas de bases de datos más populares, como MySQL y PostgreSQL, y la creación de un módulo nativo para Apache. Fue también en esta versión en la que el nombre del lenguaje perdió el sufijo /FI, quedando sólo en PHP, y en la que el acrónimo cambió su significado por el que conocemos hoy en día, &#8216;PHP Hypertext Pre-processor&#8217; (Pre-procesador de hipertexto PHP), tras <a href="http://web.archive.org/web/20000815063125/il.php.net/vote_listing.php3">una votación</a> de los desarrolladores, y después de un breve periodo de tiempo en que se utilizó como nombre &#8216;Professional Home Pages&#8217; (Páginas de Inicio Profesionales).</p>
<p>El 22 de Mayo de 2000 se lanza PHP 4, basado en el Zend Engine 1.0, una máquina virtual de código abierto, bajo licencia PHP, desarrollada también por Zeev y Andi. Desde esta versión el código fuente se compila primero a un código máquina intermedio llamado bytecode, y el Zend Engine se encarga después de ejecutar este código, al estilo Java. Esto mejoró considerablemente la velocidad de ejecución respecto de la versión anterior.</p>
<p>Entre las novedades introducidas en PHP 4.0 también encontramos mejoras de rendimiento en la API de extensiones, una capa de abstracción que permitía a PHP ejecutarse en la mayoría de los servidores web más populares, sesiones HTTP, control de buffer de salida, el tipo booleano, mejoras en la orientación a objetos y varias construcciones nuevas. También se pasó de usar una licencia dual GPL &#8211; PHP License, a utilizar exclusivamente la licencia PHP, lo que causó un pequeño revuelo entre la comunidad open source. Y es que Rasmus y el resto de desarrolladores no veían sentido a utilizar una licencia dual, teniendo en cuenta que los usuarios solían siempre utilizar la menos restrictiva de las dos.</p>
<p>Las revisiones menores de PHP 4 también introdujeron mejoras interesantes, como la inclusión de las variables superglobales en PHP 4.1.0, la desactivación por defecto de la opción <code>register_globals</code> en PHP 4.2.0, o la posibilidad de ejecutar los scripts desde la línea de comandos y la capa de acceso a ficheros y recursos de red a través de flujos o streams en PHP 4.3.0.<br />
<hr style="border:0;border-top:1px dotted #444;width:85%"/>
<h2 style="margin-top:2.5em">Presente y futuro de PHP</h2>
<p>El 13 de Julio de 2004, por fin, contando el lenguaje con una base de usuarios de 15 millones de dominios, se lanza PHP 5, basado en el Zend Engine 2.0, versión que haría que PHP entrara en su madurez, y lo convertiría en un lenguaje muy agradable de utilizar. El esfuerzo principal a la hora de desarrollar esta versión se centró en una muy necesaria mejora en el soporte de la orientación a objetos, muy pobre y discutida hasta ese momento, aunque también se añadieron otras características igual de importantes, como la capa de abstracción de acceso a bases de datos PDO (PHP Data Objects u Objetos de Datos PHP), SQLite por defecto, manejo de excepciones con bloques <code>try</code>-<code>catch</code>, iteradores, mejoras en el manejo de XML gracias a la extensión SimpleXML, mejoras en la velocidad y el rendimiento, y muchas cosas más.</p>
<p>La versión 5.3.x, la actual a la hora de escribir estas líneas, y que fue lanzada inicialmente el 30 de Junio de 2009, introdujo también características muy interesantes, inicialmente pensadas para PHP 6, como los espacios de nombres, el late static binding (enlace estático en tiempo de ejecución), closures o funciones anónimas.</p>
<p>Y es que la futura sexta versión del lenguaje, que venía planeándose desde mediados de 2005, viene sufriendo retrasos desde hace un tiempo, principalmente, debido a lo ambicioso del proyecto y los problemas con el soporte completo de Unicode. Tanto es así, que el desarrollo de PHP 6 se movió a una rama en Marzo de 2010, y el desarrollo continúa en el trunk, en un código basado en la versión 5.3.</p>
<p>Pero el futuro de PHP se presenta más brillante que nunca, no obstante, con millones de usuarios en todo el mundo y siendo utilizado en un 75% de los servidores, alcanzando el puesto de cuarto lenguaje más utilizado del mercado según TIOBE; con novedades tan útiles en un futuro próximo como los traits y con <a href="http://mundogeek.net/archivos/2010/10/30/frameworks-php/" title="Frameworks PHP">frameworks</a> que nada tienen que envidiar a Django o Ruby on Rails, como Yii, y a Struts o Spring MVC, como Zend o Symfony.</p>
]]></content:encoded>
			<wfw:commentRss>http://mundogeek.net/archivos/2011/01/26/una-no-tan-breve-historia-de-php/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
	</channel>
</rss>

