{"id":136,"date":"2013-12-19T09:00:05","date_gmt":"2013-12-19T08:00:05","guid":{"rendered":"https:\/\/blogs.ua.es\/idesweb\/?p=136"},"modified":"2013-12-18T10:21:25","modified_gmt":"2013-12-18T09:21:25","slug":"php-ejemplo-de-pagina-web-con-orientacion-a-objetos-parte-2","status":"publish","type":"post","link":"https:\/\/blogs.ua.es\/idesweb\/2013\/12\/19\/php-ejemplo-de-pagina-web-con-orientacion-a-objetos-parte-2\/","title":{"rendered":"PHP: ejemplo de p\u00e1gina web con orientaci\u00f3n a objetos (parte 2)"},"content":{"rendered":"<p>V\u00eddeo:\u00a0<a href=\"http:\/\/www.youtube.com\/watch?v=M-hlzCzw7TA\">PHP: ejemplo de p\u00e1gina web con orientaci\u00f3n a objetos (parte 2)<\/a><\/p>\n<p>Descarga de ficheros del ejemplo:\u00a0<a href=\"http:\/\/hdl.handle.net\/10045\/34635\">iDESWEB: PHP: ejemplo de p\u00e1gina web con orientaci\u00f3n a objetos<\/a><\/p>\n<p>[kml_flashembed movie=&#8221;http:\/\/www.youtube.com\/v\/M-hlzCzw7TA&#8221; width=&#8221;560&#8243; height=&#8221;315&#8243; wmode=&#8221;transparent&#8221; \/]<\/p>\n<p><strong>Transcripci\u00f3n:<\/strong><\/p>\n<p>Hola, soy Sergio Luj\u00e1n Mora, profesor de inform\u00e1tica de la Universidad de Alicante, y en este v\u00eddeo que forma parte del curso \u201cIntroducci\u00f3n al desarrollo web\u201d, te voy a mostrar un ejemplo de desarrollo de una p\u00e1gina web con orientaci\u00f3n a objetos.<\/p>\n<p>En la primera parte de este v\u00eddeo, vimos un peque\u00f1o programa que estaba escrito con el estilo procedural y que trabajaba con datos almacenados en un array.<\/p>\n<p>En esta segunda parte, voy a transformar ese c\u00f3digo en orientado a objetos, con clases y objetos.<\/p>\n<p>Algo muy importante en la programaci\u00f3n orientada a objetos es el dise\u00f1o orientado a objetos.<\/p>\n<p>Utilizar la programaci\u00f3n orientada a objetos sin un buen dise\u00f1o previo es el camino adecuado para que cualquier proyecto acabe en un desastre.<\/p>\n<p>En mi ejemplo el dise\u00f1o es muy sencillo. Tenemos una clase llamada Persona, que posee dos propiedades ocultas llamadas nombre y apellidos.<\/p>\n<p>De esta clase hereda la clase Profesor, que a\u00f1ade la propiedad cargo. Y tambi\u00e9n existe la clase Estudiante, que a\u00f1ade la propiedad curso.<\/p>\n<p>Pasemos a ver el ejemplo.<\/p>\n<p>Aqu\u00ed 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\u00e9 en el v\u00eddeo anterior. Y a la derecha tenemos el ejemplo realizado con orientaci\u00f3n a objetos, es decir, con clases y con objetos.<\/p>\n<p>Lo he puesto as\u00ed en paralelo para comparar el c\u00f3digo en una opci\u00f3n y en la otra, procedural a la izquierda y en orientado a objetos a la derecha.<\/p>\n<p>Aqu\u00ed tenemos otra vez la funci\u00f3n e() que usaba en el ejemplo anterior.<\/p>\n<p>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\u00f3n de los constructores y destructores.<\/p>\n<p>F\u00edjate que en la funci\u00f3n constructor y en la funci\u00f3n destructor llam\u00f3 a la funci\u00f3n e(), esta funci\u00f3n que tengo declarada aqu\u00ed, para simplemente mostrar un mensaje y saber que se ha ejecutado el constructor de la clase Persona o el destructor de la clase Persona.<\/p>\n<p>Lo importante es que la clase Persona tiene un constructor que inicializa el nombre y los apellidos que est\u00e1n declarados como protected.<\/p>\n<p>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\u00e9n tenemos la funci\u00f3n toString() que me va a convertir una Persona en una cadena, toString(). Y aqu\u00ed igual que hac\u00eda antes compruebo si tiene nombre y apellidos; si no tiene devolver\u00e9 desconocido, y si tiene devolver\u00e9 el nombre y los apellidos.<\/p>\n<p>De la clase Persona hereda la clase profesor como podemos ver aqu\u00ed. La clase profesor va a ser todo lo que sea la clase Persona m\u00e1s ciertas cosas. En concreto la clase Profesor a\u00f1ade una propiedad m\u00e1s, 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\u00ed no tengo que inicializarlo a mano, digamos, yo se lo puedo pasar al constructor de la clase base y entonces se ejecutar\u00e1 este c\u00f3digo. 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\u00e1s complejos podr\u00eda ser necesario invocar al destructor.<\/p>\n<p>Y luego tenemos la funci\u00f3n toString(). F\u00edjate aqu\u00ed ya aparece una ventaja: yo no tengo que volver a escribir el c\u00f3digo necesario para mostrar el nombre y los apellidos puede invocar al m\u00e9todo toString() de la clase base y simplemente a\u00f1adirle aquello que a\u00f1ade la clase profesor, aquello que es particular de la clase Profesor.<\/p>\n<p>Esto mismo he realizado con la clase Estudiante que tambi\u00e9n hereda de la clase Persona y en este caso le a\u00f1ade la propiedad Curso.<\/p>\n<p>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\u00e9todo toString() que llamar\u00e1 al m\u00e9todo toString() de la clase base, de Persona y a lo que devuelve le a\u00f1ade el curso.<\/p>\n<p>F\u00edjate que tanto la clase Profesor como la clase Estudiante, invocan las dos al m\u00e9todo toString() de la clase base Persona.<\/p>\n<p>Bien, una vez visto el c\u00f3digo de estas tres clases vamos a ver nuestros datos. Nuestros datos los almaceno en un array. En realidad, podr\u00eda aqu\u00ed, si hubiese sido orientaci\u00f3n a objetos pura, deber\u00eda de haber creado otra clase de tipo contenedor o lista para almacenar todos estos objetos que estoy creando. Pero no quer\u00eda complicar el ejemplo creando una cuarta clase. Pero como digo, se podr\u00eda haber hecho.<\/p>\n<p>En el array almacenamos nuestros objetos que se crean con new y el nombre de la clase. Aqu\u00ed tenemos dos objetos de tipo Profesor y tres objetos de tipo Estudiante. Y le paso los par\u00e1metros para inicializar cada uno de los objetos.<\/p>\n<p>F\u00edjate que el c\u00f3digo, personalmente yo creo que es m\u00e1s f\u00e1cil de leer que el c\u00f3digo del estilo procedural con el array, y adem\u00e1s hay que escribir menos. Vale, antes he tenido que escribir m\u00e1s con las clases, pero luego veremos la ventaja.<\/p>\n<p>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\u00e1gina y vemos aqu\u00ed en primer lugar temor la traza de las llamadas a los constructores. F\u00edjate 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\u00ed se repite para los cinco objetos.<\/p>\n<p>Esto mismo luego se repite al final del c\u00f3digo, al final de la p\u00e1gina 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.<\/p>\n<p>Bien, f\u00edjate el array tiene cinco posiciones, de la cero a la cuatro, cinco objetos, en cada posici\u00f3n tenemos un objeto. Aqu\u00ed nos dice que es un objeto de tipo Profesor y aqu\u00ed nos dice que es un objeto de tipo Estudiante.<\/p>\n<p>Y cada uno tiene pues sus campos, sus propiedades. El profesor tiene nombre, apellidos y cargo; y el estudiante tiene nombre, apellidos y curso.<\/p>\n<p>Bien, volvamos ahora al c\u00f3digo y voy a descomentar este fragmento. Bien, f\u00edjate 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\u00f3n del array, simplemente tengo que invocar el m\u00e9todo toString() que lo he declarado siempre como p\u00fablico, lo puedo invocar desde fuera de la clase.<\/p>\n<p>Este c\u00f3digo de aqu\u00ed equivale a este bucle que ten\u00eda aqu\u00ed. F\u00edjate que ya tenemos un ahorro, un ahorro de c\u00f3digo, de l\u00edneas.<\/p>\n<p>En la orientaci\u00f3n objetos yo no me tengo que preocupar por el tipo del objeto. S\u00ed he definido bien mis clases, he hecho un buen dise\u00f1o, como todas las clases tienen el m\u00e9todo toString(), yo lo invoco y el int\u00e9rprete de PHP sabr\u00e1 en cada momento qu\u00e9 m\u00e9todo toString() tiene que invocar; si tiene que invocar el m\u00e9todo toString() de la clase Estudiante o tiene que invocar el m\u00e9todo toString() de la clase Profesor.<\/p>\n<p>Yo aqu\u00ed, no me tengo que preocupar de ello, PHP es el que se preocupa de ello.<\/p>\n<p>Sin embargo en el estilo procedural, en el estilo con arrays, yo me ten\u00eda que preocupar de ello yo ten\u00eda que comprobar en cada momento<br \/>\nsi ten\u00eda miembro de tipo Profesor o ten\u00eda un miembro de tipo Estudiantes e invocar en cada caso el m\u00e9todo, el procedimiento adecuado, porque si no lo hac\u00eda as\u00ed pues se comet\u00eda un error o el resultado final no era el esperado.<\/p>\n<p>Vamos a ejecutarlo, este c\u00f3digo y veremos que funciona correctamente. Y aqu\u00ed lo tenemos, aqu\u00ed se visualiza cada uno de los objetos, de tipo Profesor o de tipo Estudiante.<\/p>\n<p>Y ahora otra ventaja de la orientaci\u00f3n a objetos. En la orientaci\u00f3n a objetos, otra vez, si he hecho un buen dise\u00f1o, puedo evitar que se comentan, que se hagan cosas que yo no quiero permitir. Por ejemplo, en mi dise\u00f1o 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\u00edo a todos mis objetos.<\/p>\n<p>Este c\u00f3digo debe de fallar. Sin embargo, esto en el estilo procedural, antes vimos en el otro v\u00eddeo que s\u00ed que era posible, vimos aqu\u00ed como era posible a todos los miembros cambiarle el tipo, ponerle \u201cestudiante\u201d o oponerle un curso cinco, quinto que no es posible.<\/p>\n<p>Esto, en orientaci\u00f3n a objetos, se puede evitar, se fue impedir que se haga.<\/p>\n<p>Bien, vamos a probarlo y veremos como PHP me tiene que mostrar un mensaje de error.<\/p>\n<p>Vamos a recargarlo y ah\u00ed aparece el mensaje de error. El mensaje de error me dice que no se puede acceder a la propiedad protegida nombre.<\/p>\n<p>Bien, para finalizar, pues hemos visto dos ventajas importantes de la orientaci\u00f3n a objetos. S\u00ed, hay que escribir quiz\u00e1s al principio un poco m\u00e1s de c\u00f3digo, pero nos reporta el beneficio de que podemos, por ejemplo, luego escribir c\u00f3digo m\u00e1s sencillo y significativo, m\u00e1s f\u00e1cil de leer y tambi\u00e9n podemos controlar situaciones que no se deben de dar en nuestro c\u00f3digo.<\/p>\n<p>Ya para finalizar, me gustar\u00eda recordarte algunos de los sitios web en los que puedes encontrar m\u00e1s informaci\u00f3n sobre m\u00ed y sobre mi trabajo, y dos formas de contactar conmigo, a trav\u00e9s de mi correo electr\u00f3nico sergio.lujan@ua.es y a trav\u00e9s de mi cuenta en Twitter @sergiolujanmora.<\/p>\n<p>Recuerda que este v\u00eddeo forma parte del curso \u201cIntroducci\u00f3n al desarrollo web\u201d que est\u00e1 disponible en la direcci\u00f3n idesweb.es.<\/p>\n<p>Muchas gracias por tu atenci\u00f3n.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>V\u00eddeo:\u00a0PHP: ejemplo de p\u00e1gina web con orientaci\u00f3n a objetos (parte 2) Descarga de ficheros del ejemplo:\u00a0iDESWEB: PHP: ejemplo de p\u00e1gina web con orientaci\u00f3n a objetos [kml_flashembed movie=&#8221;http:\/\/www.youtube.com\/v\/M-hlzCzw7TA&#8221; width=&#8221;560&#8243; height=&#8221;315&#8243; wmode=&#8221;transparent&#8221; \/] Transcripci\u00f3n: Hola, soy Sergio Luj\u00e1n Mora, profesor de inform\u00e1tica de la Universidad de Alicante, y en este v\u00eddeo que forma parte del curso \u201cIntroducci\u00f3n &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/blogs.ua.es\/idesweb\/2013\/12\/19\/php-ejemplo-de-pagina-web-con-orientacion-a-objetos-parte-2\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;PHP: ejemplo de p\u00e1gina web con orientaci\u00f3n a objetos (parte 2)&#8221;<\/span><\/a><\/p>\n","protected":false},"author":40,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[676],"tags":[],"class_list":["post-136","post","type-post","status-publish","format-standard","hentry","category-sin-categoria"],"_links":{"self":[{"href":"https:\/\/blogs.ua.es\/idesweb\/wp-json\/wp\/v2\/posts\/136","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.ua.es\/idesweb\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.ua.es\/idesweb\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.ua.es\/idesweb\/wp-json\/wp\/v2\/users\/40"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.ua.es\/idesweb\/wp-json\/wp\/v2\/comments?post=136"}],"version-history":[{"count":1,"href":"https:\/\/blogs.ua.es\/idesweb\/wp-json\/wp\/v2\/posts\/136\/revisions"}],"predecessor-version":[{"id":137,"href":"https:\/\/blogs.ua.es\/idesweb\/wp-json\/wp\/v2\/posts\/136\/revisions\/137"}],"wp:attachment":[{"href":"https:\/\/blogs.ua.es\/idesweb\/wp-json\/wp\/v2\/media?parent=136"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.ua.es\/idesweb\/wp-json\/wp\/v2\/categories?post=136"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.ua.es\/idesweb\/wp-json\/wp\/v2\/tags?post=136"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}