iDESWEB

Introducción al desarrollo web, primer curso MOOC sobre desarrollo web en español

iDESWEB - Introducción al desarrollo web, primer curso MOOC sobre desarrollo web en español

PHP: ejemplo de página web con orientación a objetos (parte 2)

Vídeo: PHP: ejemplo de página web con orientación a objetos (parte 2)

Descarga de ficheros del ejemplo: iDESWEB: PHP: ejemplo de página web con orientación a objetos

Transcripción:

Hola, soy Sergio Luján Mora, profesor de informática de la Universidad de Alicante, y en este vídeo que forma parte del curso “Introducción al desarrollo web”, te voy a mostrar un ejemplo de desarrollo de una página web con orientación a objetos.

En la primera parte de este vídeo, vimos un pequeño programa que estaba escrito con el estilo procedural y que trabajaba con datos almacenados en un array.

En esta segunda parte, voy a transformar ese código en orientado a objetos, con clases y objetos.

Algo muy importante en la programación orientada a objetos es el diseño orientado a objetos.

Utilizar la programación orientada a objetos sin un buen diseño previo es el camino adecuado para que cualquier proyecto acabe en un desastre.

En mi ejemplo el diseño es muy sencillo. Tenemos una clase llamada Persona, que posee dos propiedades ocultas llamadas nombre y apellidos.

De esta clase hereda la clase Profesor, que añade la propiedad cargo. Y también existe la clase Estudiante, que añade la propiedad curso.

Pasemos a ver el ejemplo.

Aquí en el editor muestro en paralelo los dos ficheros que he realizado. A la izquierda tenemos el ejemplo realizado con arrays, con el estilo procedural, es decir, con funciones sueltas, el ejemplo que mostré en el vídeo anterior. Y a la derecha tenemos el ejemplo realizado con orientación a objetos, es decir, con clases y con objetos.

Lo he puesto así en paralelo para comparar el código en una opción y en la otra, procedural a la izquierda y en orientado a objetos a la derecha.

Aquí tenemos otra vez la función e() que usaba en el ejemplo anterior.

En primer lugar tengo definida la clase Persona. La clase Persona tiene el constructor, tiene el destructor que no hace nada, pero lo he puesto porque ahora vamos a ver una traza de ejecución de los constructores y destructores.

Fíjate que en la función constructor y en la función destructor llamó a la función e(), esta función que tengo declarada aquí, para simplemente mostrar un mensaje y saber que se ha ejecutado el constructor de la clase Persona o el destructor de la clase Persona.

Lo importante es que la clase Persona tiene un constructor que inicializa el nombre y los apellidos que están declarados como protected.

Protected recuerda que es lo mismo que privado, private, pero permite el acceso desde las clases heredadas, pero desde el exterior de la clase no se puede acceder a estas propiedades. Y luego también tenemos la función toString() que me va a convertir una Persona en una cadena, toString(). Y aquí igual que hacía antes compruebo si tiene nombre y apellidos; si no tiene devolveré desconocido, y si tiene devolveré el nombre y los apellidos.

De la clase Persona hereda la clase profesor como podemos ver aquí. La clase profesor va a ser todo lo que sea la clase Persona más ciertas cosas. En concreto la clase Profesor añade una propiedad más, en este caso privada, llamada cargo. Tenemos el constructor, tenemos el destructor. En el constructor voy a llamar al constructor de la clase base, de la clase padre, es decir el constructor de la clase Persona. Y yo le paso el nombre y los apellidos. Yo aquí no tengo que inicializarlo a mano, digamos, yo se lo puedo pasar al constructor de la clase base y entonces se ejecutará este código. Lo mismo con el destructor, yo en el destructor de la clase Profesor puede invocar el destructor de la clase base, es decir, Persona. En este ejemplo no realiza nada, pero en ejemplos más complejos podría ser necesario invocar al destructor.

Y luego tenemos la función toString(). Fíjate aquí ya aparece una ventaja: yo no tengo que volver a escribir el código necesario para mostrar el nombre y los apellidos puede invocar al método toString() de la clase base y simplemente añadirle aquello que añade la clase profesor, aquello que es particular de la clase Profesor.

Esto mismo he realizado con la clase Estudiante que también hereda de la clase Persona y en este caso le añade la propiedad Curso.

Otra vez tenemos el constructor de la clase Estudiante, que invoca el constructor de la clase base, es decir, Persona y le pasa nombre y apellidos para que se inicialice. Y luego le asigna un valor a su propiedad particular que es curso. Otra vez tenemos el destructor y otra vez tenemos el método toString() que llamará al método toString() de la clase base, de Persona y a lo que devuelve le añade el curso.

Fíjate que tanto la clase Profesor como la clase Estudiante, invocan las dos al método toString() de la clase base Persona.

Bien, una vez visto el código de estas tres clases vamos a ver nuestros datos. Nuestros datos los almaceno en un array. En realidad, podría aquí, si hubiese sido orientación a objetos pura, debería de haber creado otra clase de tipo contenedor o lista para almacenar todos estos objetos que estoy creando. Pero no quería complicar el ejemplo creando una cuarta clase. Pero como digo, se podría haber hecho.

En el array almacenamos nuestros objetos que se crean con new y el nombre de la clase. Aquí tenemos dos objetos de tipo Profesor y tres objetos de tipo Estudiante. Y le paso los parámetros para inicializar cada uno de los objetos.

Fíjate que el código, personalmente yo creo que es más fácil de leer que el código del estilo procedural con el array, y además hay que escribir menos. Vale, antes he tenido que escribir más con las clases, pero luego veremos la ventaja.

Lo primero que voy a hacer es mostrar, con un print_r() voy a mostrar el array y vamos a ver su contenido. Me lo guardo y me voy al navegador y recargo la página y vemos aquí en primer lugar temor la traza de las llamadas a los constructores. Fíjate que aparece por cada objeto dos constructores. Aparece el constructor de la clase Profesor y el constructor de la clase base Persona. Estudiante y llama al constructor de la clase base Persona. Y así se repite para los cinco objetos.

Esto mismo luego se repite al final del código, al final de la página pero con la llamada a los destructores. Se invoca al destructor del objeto Profesor y luego dentro de ese destructor invocamos al destructor de la clase base que siempre es Persona, el destructor de la clase Persona.

Bien, fíjate el array tiene cinco posiciones, de la cero a la cuatro, cinco objetos, en cada posición tenemos un objeto. Aquí nos dice que es un objeto de tipo Profesor y aquí nos dice que es un objeto de tipo Estudiante.

Y cada uno tiene pues sus campos, sus propiedades. El profesor tiene nombre, apellidos y cargo; y el estudiante tiene nombre, apellidos y curso.

Bien, volvamos ahora al código y voy a descomentar este fragmento. Bien, fíjate este fragmento es un bucle foreach que me recorre el array $comunidad para mostrarme cada uno de los objetos. Para mostrar cada objeto, $miembro es un objeto, esta posición del array, simplemente tengo que invocar el método toString() que lo he declarado siempre como público, lo puedo invocar desde fuera de la clase.

Este código de aquí equivale a este bucle que tenía aquí. Fíjate que ya tenemos un ahorro, un ahorro de código, de líneas.

En la orientación objetos yo no me tengo que preocupar por el tipo del objeto. Sí he definido bien mis clases, he hecho un buen diseño, como todas las clases tienen el método toString(), yo lo invoco y el intérprete de PHP sabrá en cada momento qué método toString() tiene que invocar; si tiene que invocar el método toString() de la clase Estudiante o tiene que invocar el método toString() de la clase Profesor.

Yo aquí, no me tengo que preocupar de ello, PHP es el que se preocupa de ello.

Sin embargo en el estilo procedural, en el estilo con arrays, yo me tenía que preocupar de ello yo tenía que comprobar en cada momento
si tenía miembro de tipo Profesor o tenía un miembro de tipo Estudiantes e invocar en cada caso el método, el procedimiento adecuado, porque si no lo hacía así pues se cometía un error o el resultado final no era el esperado.

Vamos a ejecutarlo, este código y veremos que funciona correctamente. Y aquí lo tenemos, aquí se visualiza cada uno de los objetos, de tipo Profesor o de tipo Estudiante.

Y ahora otra ventaja de la orientación a objetos. En la orientación a objetos, otra vez, si he hecho un buen diseño, puedo evitar que se comentan, que se hagan cosas que yo no quiero permitir. Por ejemplo, en mi diseño nombre y apellidos los he definido como protegidos, significa que desde fuera de la clase no se pueden modificar. Por tanto, este bucle no se va a ejecutar correctamente, yo estoy intentando cambiar el nombre, ponerle un nombre vacío a todos mis objetos.

Este código debe de fallar. Sin embargo, esto en el estilo procedural, antes vimos en el otro vídeo que sí que era posible, vimos aquí como era posible a todos los miembros cambiarle el tipo, ponerle “estudiante” o oponerle un curso cinco, quinto que no es posible.

Esto, en orientación a objetos, se puede evitar, se fue impedir que se haga.

Bien, vamos a probarlo y veremos como PHP me tiene que mostrar un mensaje de error.

Vamos a recargarlo y ahí aparece el mensaje de error. El mensaje de error me dice que no se puede acceder a la propiedad protegida nombre.

Bien, para finalizar, pues hemos visto dos ventajas importantes de la orientación a objetos. Sí, hay que escribir quizás al principio un poco más de código, pero nos reporta el beneficio de que podemos, por ejemplo, luego escribir código más sencillo y significativo, más fácil de leer y también podemos controlar situaciones que no se deben de dar en nuestro código.

Ya para finalizar, me gustaría recordarte algunos de los sitios web en los que puedes encontrar más información sobre mí y sobre mi trabajo, y dos formas de contactar conmigo, a través de mi correo electrónico sergio.lujan@ua.es y a través de mi cuenta en Twitter @sergiolujanmora.

Recuerda que este vídeo forma parte del curso “Introducción al desarrollo web” que está disponible en la dirección idesweb.es.

Muchas gracias por tu atención.

PHP: ejemplo de página web con orientación a objetos (parte 1)

Vídeo: PHP: ejemplo de página web con orientación a objetos (parte 1)

Descarga de ficheros del ejemplo: iDESWEB: PHP: ejemplo de página web con orientación a objetos

Transcripción:

Hola, soy Sergio Luján Mora, profesor de informática de la Universidad de Alicante, y en este vídeo que forma parte del curso “Introducción al desarrollo web”, te voy a mostrar un ejemplo de desarrollo de una página web con orientación a objetos.

Si no conoces la sintaxis de la orientación a objetos en PHP, te invito a que veas los vídeos “PHP: orientación a objetos (PHP4)”, y “PHP: orientación a objetos (PHP5)”. En estos dos vídeos te explico lo mínimo que necesitas conocer sobre la orientación a objetos en PHP.

El siguiente ejemplo que te voy a mostrar lo voy a realizar con la sintaxis de orientación a objetos de PHP5.

En esta primera parte del vídeo voy a desarrollar el ejemplo con el estilo procedural. En el estilo procedural el código se encuentra en procedimientos o funciones.

Para almacenar los datos del programa que voy a realizar voy a utilizar arrays.

En el siguiente vídeo, transformaré este ejemplo en orientado a objetos y los arrays los sustituiré por clases y objetos.

¿Cuál de los dos estilos es el mejor, el procedural o el orientado a objetos?

Desde hace años, el estilo de programación que se aconseja es el orientado a objetos. Es el mejor para grandes proyectos en los que trabajan muchas personas al mismo tiempo. Pero esto no significa que el estilo procedural ya no se deba usar. En este ejemplo vamos a ver algunos de los problemas del estilo procedural, pero en ciertas situaciones es una muy buena opción.

Pasemos a ver el ejemplo.

Aquí tenemos el ejemplo que te voy a mostrar. El código ya lo tengo escrito para ir más rápido y también para no cometer errores durante la grabación del video.

Fíjate que no voy a construir una página web real, es decir, no voy a preocupar por ponerle el DOCTYPE, el <html>, etcétera, ya que el objetivo del vídeo no es hacer una página web real sino trabajar con PHP con las clases, con los objetos, etcétera.

He puesto aquí esta etiqueta <pre> para activar la visualización de texto preformateado. Esto me va a permitir que los saltos de línea que yo escriba, muestre desde PHP se respete.

En PHP primero he declarado una función llamada “e” que va a ser un alias de la función eco de PHP. Es la función que voy a emplear para mostrar, para visualizar algo en la página. Esta función añade a lo que yo quiero mostrar, a la cadena, le añade un salto de línea.

A continuación tengo declarado el array $comunidad. Este array es multidimensional, tiene en concreto dos dimensiones. En la primera dimensión vamos a encontrar una serie de arrays. Cada array representa un miembro de la comunidad universitaria.

Tenemos dos tipos de miembros: el tipo profesor y el tipo estudiante. Los dos tipos comparten alguna información, los dos tienen nombres y apellidos, como podemos ver aquí. Sin embargo, el tipo profesor tiene un campo propio, el cargo que ocupa el profesor y el tipo estudiante tiene un campo propio, el curso en el que estudia el estudiante.

Tenemos aquí cinco miembros de la comunidad universitaria. Fíjate que he empleado arrays asociativos, esta posición, este índice en el array no es un número sino que es una cadena. Lo primero que voy a hacer es visualizar este array en la página web para ver si se muestra como yo espero. Así que me voy a la página web y aquí lo tenemos, tal como se muestra.

Fíjate algo muy importante, la página que estoy haciendo la estoy ejecutando a través de localhost, no la puedo ejecutar directamente porque tiene código PHP. El array, como puedes ver, tiene cinco posiciones que van de la posición cero a la posición cuatro.

Lo siguiente que voy a hacer, voy a quitar este comentario, lo siguiente que voy a hacer es mostrar el array con un formato que yo quiero. Para ello voy a recorrer el array, el array $comunidad con un bucle foreach. Y entonces aquí nos encontramos el primer problema del estilo procedural. Tenemos dos tipos de miembros, el tipo profesor y el tipo estudiante. Cada uno tiene información diferente, así que vamos a necesitar dos funciones para mostrar cada uno de ellos. Si tuviésemos diferentes tipos, tres, cuatro, cinco, seis, necesitaríamos tres, cuatro, cinco, seis funciones para cada uno de los tipos.

Aquí tengo la primera función para mostrar el tipo profesor, la he llamado ProfesorToString(), es decir, me va a convertir un array de este tipo me lo va a convertir en una cadena, es lo que va a devolver esta función. $p va a ser el array de tipo profesor que va a recibir la función y se tienen que hacer algunas comprobaciones para hacer el código “a prueba de bombas”, para que no surjan problemas. Así que lo primero que voy a comprobar es si el array que me pasan es realmente un array; si la variable, el parámetro que han pasado $p es realmente un array.

Si es un array, lo siguiente que compruebo es que exista una posición llamada tipo, y si existe esa posición, lo siguiente que compruebo es que sea de tipo profesor, porque esta función es para mostrar un profesor. Y si es así entonces ya viene el código concreto para mostrar un profesor. Primero compruebo si tiene nombre y apellidos, si no tiene nombre y apellidos entonces el resultado, lo que voy a mostrar, es desconocido, no sabemos su nombre y sus apellidos y a continuación el cargo. Si no es así, si el nombre y los apellidos es distinto de cadena vacía, entonces el resultado es el nombre, coma apellidos, coma cargo.

Esto mismo lo tengo que repetir con el tipo estudiante. EstudianteToString recibe $e, recibe este parámetro y otra vez volvemos a realizar las mismas comprobaciones. Primero compruebo que sea un array, luego compruebo que esté definida la posición tipo, luego compruebo que sea de tipo estudiante y finalmente, si es así, ya muestro, en realidad ya devuelvo una cadena con el resultado y otra vez, si no hay nombres y apellidos, devuelvo desconocido y si sí que hay, pues devuelvo nombre, apellidos y el curso del estudiante que es lo que va a devolver la función EstudianteToString.

Bien, esto ya lo podemos probar, voy a poner ahora aquí un comentario, esto lo veremos después, así que ahora se va a ejecutar este código, va a recorrer el array y para cada miembro vamos a ver si tenemos que llamar a ProfesorToString si es de tipo profesor o a EstudianteToString si es de tipo estudiante.

Como he dicho antes, si tuviésemos más tipos, lo tendría que ir añadiendo aquí uno tras uno.

Bien, grabo el fichero y ejecuto la página. Me sale el array con el print_r() que ya lo teníamos antes, y aquí ya me sale la visualización en mi formato. Aquí tenemos un profesor, aquí tenemos un estudiante, otro estudiante, aquí tenemos un profesor y por último aquí tenemos este estudiante del cual no sabemos ni su nombre y apellidos ni su curso.

Bien, ahora ya empiezan los problemas. ¿Qué ocurre si en mi código pues por error, por ejemplo, realizo este bucle?

Con este bucle voy a cambiar todos los miembros de la comunidad universitaria y les voy a poner tipo estudiante. Pero quizás eso no se debería de poder hacer, quizás se debería comprobar que por ejemplo este miembro, que es de profesor, no puede cambiar de tipo.

Esto, en la programación procedural con arrays, es imposible, esto no se puede controlar, no se puede impedir que se hagan cosas como ésta. Y tampoco se puede impedir que se haga esto, por ejemplo le podemos poner que el curso de los estudiantes es quinto, cuando en realidad a lo mejor no es posible, no existe, el curso solamente existe de uno a cuatro, de primero a cuarto.

Como he dicho antes, todo esto no lo podemos impedir en la programación procedural, pero luego ya veremos que en la programación orientada a objetos si que lo podemos controlar.

Bien, vamos a probarlo y ahora veremos, bien primero tenemos que mostrarlo, voy a quitar este comentario, ahora explicaré esto para qué está, y vamos a probarlo.

Y ahora vemos como todos nuestros miembros, todo el contenido de nuestro array ha cambiado a tipo estudiante y a todos le ha puesto el curso quinto.

Y si ahora lo visualizamos pues efectivamente nos lo saca como que todos son estudiantes.

Bien, para finalizar este vídeo, te he dicho que te iba a comentar esto para qué estaba puesto. Bueno, no te lo digo, te lo dejo como ejercicio que averigües por qué está puesto esto aquí y qué ocurre si no lo ponemos, qué ocurre si yo esta línea la quito.

Como pista, fíjate que aquí le había puesto un ampersand en el bucle foreach. Este ampersand hace que miembro sea una referencia a las posiciones del array. Este ampersand está relacionado con esto y como digo, si no se pone, aquí ocurre algo curioso.

Ya para finalizar, me gustaría recordarte algunos de los sitios web en los que puedes encontrar más información sobre mí y sobre mi trabajo, y dos formas de contactar conmigo, a través de mi correo electrónico sergio.lujan@ua.es y a través de mi cuenta en Twitter @sergiolujanmora.

Recuerda que este vídeo forma parte del curso “Introducción al desarrollo web” que está disponible en la dirección idesweb.es.

Muchas gracias por tu atención.

Historia de HTML

Historia de HTML:

Transcripción:

Hola, soy Sergio Luján Mora, profesor de informática de la Universidad de Alicante, y en este vídeo que forma parte del curso “Introducción al desarrollo web”, te voy a hablar de la historia del lenguaje HTML.

Antes de empezar, me gustaría recordarte algunos de los sitios web en los que puedes encontrar más información sobre mí y sobre mi trabajo, y dos formas de contactar conmigo, a través de mi correo electrónico sergio.lujan@ua.es y a través de mi cuenta en Twitter @sergiolujanmora.

Si ya has visto las dos partes del vídeo “Historia de la Web: su nacimiento”, sabrás que Tim Berners-Lee es considerado el padre de la Web porque desarrolló las tres tecnologías fundamentales en las que se basa la Web:

HTML, HyperText Markup Language, el lenguaje de marcado o etiquetado que se emplea para crear, para escribir, los documentos o páginas web.
URL, Uniform Resource Locator, el localizador de recursos uniforme, el sistema de localización o direccionamiento de los documentos web.
Y HTTP, HyperText Transfer Protocol, el protocolo o lenguaje con el que se comunican el navegador y el servidor web y que se emplea para transmitir los documentos web por Internet.

Lo que nos interesa para este vídeo es que Tim Berners-Lee desarrolló la primera versión del lenguaje HTML. En este vídeo te voy a explicar la evolución del lenguaje HTML durante sus primeros años.

La mejor información sobre los primeros años del lenguaje HTML la podemos encontrar en el libro “Raggett on HTML4”, del año 1998.

Afortunadamente, existe una versión online del capítulo 2 de este libro, el capítulo que está dedicado a contar la historia de HTML.

Dave Raggett, uno de los autores de este libro, fue el editor de la especificación del lenguaje HTML durante muchos años, así que lo que nos cuenta en su libro lo sabe por haber sido protagonista de ello en primera persona.

Tim Berners-Lee desarrolló el lenguaje HTML a partir de SGML, Standard Generalized Markup Language, un estándar ISO del año 1986 que se emplea para la organización y etiquetado de textos.

El lenguaje SGML sirve para especificar las reglas de etiquetado de documentos y no impone en sí ningún conjunto de etiquetas en especial. Por tanto, SGML es equivalente al actual XML.

Como podemos ver en este ejemplo, un documento creado según SGML se parece bastante a HTML, o mejor dicho, HTML se parece a SGML, ya que SGML es anterior a HTML. El uso de una pareja de etiquetas para marcar partes del texto en HTML está tomado directamente de SGML, al igual que ciertas etiquetas como <p>, los encabezados <h1>, <h2>, etc., o las etiquetas de lista como <ol>, <ul> y <li>, que eran muy comunes en lenguajes creados a partir de SGML.

Sin embargo, lo que SGML no incluía, y sí que es una invención propia de Tim Berners-Lee es la etiqueta <a> con el atributo href para los enlaces o hipervínculos.

Recordemos que noviembre de 1990 se suele fijar como el nacimiento de la Web: Tim Berners-Lee publicó su primer sitio web y realizó la primera conexión desde un navegador mientras trabaja en el CERN, el laboratorio europeo de investigación en física de partículas en Suiza.

Voy a emplear el siguiente diagrama para seguir la evolución del lenguaje HTML. En la parte superior se muestra la evolución del lenguaje HTML, mientras que en la parte inferior se muestra la evolución de los navegadores más populares. Por ahora nos vamos a fijar en los primeros años del lenguaje HTML, hasta la publicación de la versión 4.

Las primeras versiones de HTML no fueron estandarizadas, en parte porque su uso no estaba muy extendido, así que no era necesaria una estandarización formal.

El primer intento de estandarización lo encontramos en el borrador “Hypertext Markup Language” de junio de 1993, escrito por Tim Berners-Lee y Daniel Conolly. Este documento se considera la primera versión del lenguaje HTML, la 1.0. Daniel Conolly desarrolló el primer DTD de HTML, como podemos leer en este mensaje de junio de 1992. Esta primera versión de HTML no disponía de algunos elementos que son imprescindibles hoy en día en las páginas web, como las tablas y los formularios.

Y por otro lado, permitía crear documentos que hoy en día no son válidos, como este ejemplo en el que no aparecen ni la etiqueta <head> ni la etiqueta <body>, y la etiqueta <title> está escrita al mismo nivel que el resto del contenido de la página.

En julio de 1993 se comenzó a trabajar en la especificación de la siguiente versión de HTML, que dio lugar a HTML+ en noviembre de 1993, que nunca llegó a estandarizarse. HTML+ estaba compuesto de encabezados, párrafos, listas, figuras, tablas, formularios, texto preformateado y fórmulas matemáticas. La principal novedad de HTML+ es que incorporaba por primera vez las tablas y los formularios.

Por cierto, si se revisa el documento de HTML+ se pueden encontrar algunas cosas curiosas, como la propuesta de la etiqueta <FIG> con la etiqueta <CAPTION> para definir figuras. ¿Y por qué es curioso?

Muy sencillo, estás dos etiquetas finalmente no formaron parte del estándar de HTML, sin embargo, en HTML5, la nueva versión de HTML, incorpora como novedades las etiquetas <figure> y <figcaption>, que son muy parecidas a <fig> y <caption>.

Otra curiosidad de HTML+ es que incorporaba la posibilidad de definir ecuaciones matemáticas en HTML.

Esta característica al final no se incluyó en HTML, pero dio lugar a un lenguaje totalmente independiente, llamado MathML que ya va por la tercera versión.

Quizás te estés preguntando, ¿llegó a existir un navegador que aceptase las nuevas etiquetas de HTML+?

Sí, por supuesto, se llamaba Arena, y era un navegador desarrollado como prueba de concepto para mostrar las nuevas posibilidades de HTML.

En octubre de 1994 se funda el W3C, el World Wide Web Consortium, que a partir de entonces se encargará del desarrollo de las tecnologías que mueven la Web.

Y por fin llegamos a noviembre de 1995, cuando se publica HTML 2.0, la primera versión de HTML que fue realmente un estándar, en concreto, fue un Request for Comments, aún no era una recomendación del W3C.

Mientras tanto, empezó a fraguarse la primera guerra de los navegadores, entre Microsoft y Netscape.

Un elemento de esa guerra fue la inclusión de ciertas características especiales en los navegadores para distinguirlos de la competencia. Así, por ejemplo, Netscape inventó la etiqueta <blink>, mientras que Microsoft inventó la etiqueta <marquee>. Ambas etiquetas no han formado parte del estándar en ningún momento y no se deben emplear.

En enero de 1997 se publicó HTML 3.2, la primera versión estandarizada por el W3C.

Y en diciembre de 1999 se publicó la última revisión, HTML 4.01.

¿Qué pasó a continuación?

El W3C abandonó el desarrolló de HTML y concentró todos sus esfuerzos en el desarrollo de XML, un metalenguaje que define unas reglas para definir otros lenguajes.

En enero de 2000 se publicó XHTML 1.0, una reformulación de HTML 4 utilizando como base XML 1.0. XHTML 1.0 era como HTML 4.01, tenía las mismas etiquetas, pero imponía unas reglas más estrictas para que los documentos fueran válidos.

Y una revisión de XHTML 1.0 fue publicada en agosto de 2002.

Sin embargo, XHTML no triunfó y la gente seguía usando HTML. ¿Por qué? Seguramente porque XHTML era muy estricto y la gente no estaba preparada para ello.

Así que, en el año 2004, un grupo llamado WHATWG y formado por Apple, Mozilla y Opera, se forma y comienza el desarrollo de un HTML más cercano a la gente. El W3C rectifica, cancela el desarrollo de XHTML, y se une a WHATWG para desarrollar HTML5.

Si quieres saber más sobre el nacimiento de HTML5 y cómo fue que el W3C canceló el desarrollo de XHTML, te recomiendo la lectura del artículo “The Web is Reborn”.

En la actualidad, enero de 2013, HTML5 se encuentra en el estado de recomendación candidata y aunque todavía no es un estándar, ya se está trabajando en la siguiente versión 5.1, que incorporará aquello que no esté incluido en la versión 5.

La hoja de ruta que se ha marcado el W3C establece que HTML 5.0 será una especificación oficial a finales del año 2014, y la versión 5.1 a finales del año 2016.

Y ya por último, si quieres leer alguna cosa más sobre la historia del lenguaje HTML, por ejemplo, para contrastar todo lo que te he contado aquí, te recomiendo estas dos lecturas.

Recuerda que este vídeo forma parte del curso “Introducción al desarrollo web” que está disponible en la dirección idesweb.es.

Muchas gracias por tu atención.