Paamayim Nekudotayim y la palabra final en la programación orientada a objetos

Tal vez te estés preguntando qué coño significa el concepto Paamayim Nekudotayim y lo qué supone para la programación. Pues tranquilo por que en este nuevo capitulo del curso de programación orientada a objetos te lo voy a explicar de forma detallada junto con la palabra reservada final. Un dos por uno en un solo artículo, todo un lujazo 😉

Paamayim Nekudotayim durante el Sabbat

Paamayim Nekudotayim es la traducción hebrea para “doble dos-puntos”, token muy utilizado en la programación para hacer referencia a elementos estáticos, constantes de clase o para sobrescribir las propiedades y los métodos de cualquier clase durante la herencia.

Pero lo mas probable es que estés prestando mas atención a este nombre de difícil memorización que a su significado técnico. Pues bien, la anécdota que hay detrás de el y por que recibe este nombre es una chorrada.

Muchos lenguajes de programación conviven con frameworks específicos para ellos y en PHP no podía ser de otra manera. Si todavía no sabes cuál es la diferencia entre lenguaje de programación y framework recuerda esto. El lenguaje es la base y el framework es un conjunto de herramientas y abstracciones construidas que nos facilitan el trabajar con la base, es decir, el lenguaje de programación.

Siempre ha existido el debate de qué es mejor para un programador si especializarse en un lenguaje o en un framework. Pues bien, sinceramente creo que es mejor dominar un lenguaje debido a que los frameworks están sujetos a modas y sobre todo que si aprendes bien un lenguaje de programación después podrás comprender los mecanismos internos de cualquier framework basado en ese lenguaje.

Te vas a encontrar con muchos gilipollas gurús que se las dan de framework master pero después no tienen ni puta idea de cómo hace la resolución de ámbito el motor del lenguaje, por ejemplo…

Pues bien, que me pierdo, Paamayim Nekudotayim surgió cuando Zeev Suraski y Andi Gutmans creadores del framework Zend Engine tuvieron que nombrar al operador de resolución de ámbito en PHP y como te habrás fijado, estos dos pollos no tienen nombres típicos de Albacete, son israelíes y como es lógico utilizaron su lengua materna para darle nombre a algo en lo que estaban trabajando.

Esa es la historia, fin del tema. Ahora sí, vamos a entrar a nivel de detalle técnico para explicar qué es esto.

Como decía antes, el Paamayim Nekudotayim es la forma que tenemos si queremos hacer referencia y usar ciertos elementos de las clases.

Ya lo has visto anteriormente sobre todo cuando explicábamos qué son las constantes de clase. Cuando defines una constante y la quieres utilizar por narices vas a tener que usar el “doble dos-puntos”. Por ejemplo:
https://gist.github.com/gorkamu/199da13787caa67e9edfcddf40f8481f.js
Para pintar el valor de la constante BLOG estamos usando el operador de resolución de ámbito, nuestro querido Paamayim Nekudotayim y a lo mejor te pienses que solo se puede utilizar para acceder a constantes desde fuera de la clase. Pues no. También lo podemos utilizar dentro de la misma clase cuando por ejemplo queremos acceder a elementos estáticos de la misma.

https://gist.github.com/gorkamu/0c9271716ddbb3482aa226184ab2d101.js
Este ejemplo es muy bueno por que se puede ver que accedemos a elementos estáticos desde dentro y desde fuera de la clase. El primer caso es cuando hacemos una llamada al método cualEsMiBlog desde fuera de la definición de la clase utilizando el Paamayim Nekudotayim ya que el método está definido como estático.

El otro ejemplo es cuando dentro de la definición del método estático estamos accediendo al valor de la constante de clase. Lo hacemos también usando el operador de resolución de ámbito.

Ya tenemos dos elementos que cubren el Paamayim Nekudotayim:

  • Constantes de clase.
  • Elementos estáticos de clase.

Pero todavía queda una tercera aplicación para el “doble dos-puntos” y se utiliza cuando queremos invocar propiedades y métodos de una clase padre desde una clase hija. Mira:
https://gist.github.com/gorkamu/b334afe1d346d31a614e3069a674a737.js
¿Lo ves no? Para poder utilizar el método saluda desde la clase hija, en este ejemplo Gorkamu y PutoAmo es necesario hacer una llamada al método padre utilizando la palabra reservada parent junto con el Paamayim Nekudotayim y seguido del nombre de la propiedad o método que queremos invocar.

¿Sencillito verdad? Venga, pues pasemos ahora al otro concepto de este artículo…

Usando la palabra reservada final

Aunque todavía no he hablado extensamente sobre el concepto de herencia en la programación orientada a objetos ya hemos visto una primera aproximación en este artículo y he puesto varios ejemplos durante la serie de artículos. Sin ir mas lejos en este post hay uno.

Pues bien, cuando salió la versión 5 PHP, de entre todas las novedades que presentó, se introdujo la palabra reservada final y que se utiliza para impedir que una clase hija que forma parte de una arquitectura basada en la herencia pueda sobrescribir el método de su clase padres.

Es como si cogiéramos al motor de PHP y le dijéramos: “Oye cuando vayas a procesar esta clase que hereda de esta otra clase comprueba que la primera contiene este método, este y este pero que en ningún caso tenga el método que tiene la palabra final“.

Si por un casual se te va la pinza y sobrescribes un método que está definido como final, cuando ejecutes el script vas a recibir un bonito pete al igual que ocurre si intentas definir una propiedad como final.

Únicamente las clases y los métodos pueden ser definidos así y para el caso de las clases se aplica el mismo concepto. Si una clase contiene la palabra final implica que ésta no puede ser heredada por nadie.

Es posible que con esta explicación tan chapucera te hayas quedado con cara de WTF así que vamos a ver un ejemplo que seguro que lo entiendes mucho mejor 😉
https://gist.github.com/gorkamu/4ce57bb1b7f1f1340a37a5a8425d3287.js
Pues ahí tenéis el último ejemplo del artículo en el que se perfectamente cómo la ejecución del programa peta si intentas sobrescribir un método declarado como final de una clase padre desde una clase hija y ya solo me queda decir lo que digo siempre al final de los posts.

Si tenéis dudas o queréis hacer alguna pregunta o sugerencia tenéis los comentarios de debajo para ello y si por el contrario eres mas de utilizar las redes sociales hazme llegar tu feedback a través de twittah mediante el siguiente banner.

[xyz-ips snippet=”FAQS-GORKAMU-TW-YELLOW”]

Hala a mamarla!

Métodos mágicos en la programación orientada a objetos

Como cantó Alfredo Mercurio en su album Kind Of Magic, hoy vamos a hablar de magia y la magia en la programación orientada a objetos la podemos encontrar gracias a los métodos mágicos, valga la redundancia, así que vamos a ver un listado de diferentes métodos mágicos que podemos utilizar en nuestras aplicaciones para hacerlas mas ricas. Ale a darle…

¿Qué son los métodos mágicos?

Lo primero que tenemos que tener claro sobre los métodos mágicos es que son métodos que se invocan en nuestra aplicación cuando suceden ciertos eventos y que podemos aprovechar para realizar acciones en nuestros objetos.

Es como cuando automáticamente Miquel Iceta se pone a bailar sin poder remediarlo cada vez que escucha La Gozadera sintiendo el ritmo in the body.

Pues lo mismo pasa con los métodos mágicos, existe un desencadenador y una acción a realizar.

En PHP tenemos un conjunto de 15 métodos mágicos que se agrupan por su finalidad y cuyos nombres son reservados por el motor del lenguaje lo que quiere decir que no podremos crear nosotros otros métodos que se llamen igual.

Un método mágico es fácil de reconocer porque su nombre viene precedido de dos barras bajas y según las buenas prácticas en la programación se recomienda no utilizar este tipo de nombrar métodos a no ser que tengamos que utilizar algunos de estos métodos mágicos.

Métodos __sleep() y __wakeup()

Tipicamente utilizamos el método mágico __sleep() para confirmar datos pendientes o para hacer funcionalidades similares a la limpieza de datos. Como a lo mejor esto no se entiende mucho tenemos que saber que cuando vamos a serializar un objeto, el método serialize() va a buscar si existe este método mágico en nuestra clase para ejecutarlo antes de la serialización por lo que podríamos utilizarlo como si se tratase un de evento de tipo PRE_EVENT.

Si escribes este método mágico en tu clase pero haces que no devuelva nada, cuando sea ejecutado va a devolver un NULL y si intentas serializar un NULL ahí si que vas a tener un pete de tres pares de cojones de tipo E_NOTICE.

Al igual que cuando se serializa un objeto se invoca al método __sleep(), pues cuando se deserializa un objeto mediante unserialize() también se ejecuta otro método mágico y en este caso se trata del __wakeup().

El uso típico que se da al método __wakeup() es restablecer la conexión con la base de datos que se haya podido perder durante el proceso de serialización/deserialización.
https://gist.github.com/gorkamu/9a0a14ead73179730cf295c65c963e3d.js

Método mágico __toString()

Este método me gusta especialmente y permite a las clases definir como se tienen que comportar cuando se les trata como si fuera un objeto de tipo string. Por ejemplo, si hacemos un echo de un objeto es este método el encargo de imprimir los valores de sus propiedades.

Obviamente no es obligatorio imprimir los valores de sus propiedades, puedes hacer que devuelva un saludo por ejemplo pero lo típico es eso y siempre ha de devolver un string, sino petará con el error fatal E_RECOVERABLE_ERROR.
https://gist.github.com/gorkamu/d55f7dabbb58bcf0b44a6b3a1f60e9ed.js

Método __invoke()

Este método se ejecuta cuando se utiliza un objeto como si fuera una función. Puede parecer un poquito lioso pero con el siguiente ejemplo lo vas a ver muy claramente.
https://gist.github.com/gorkamu/8afcca0e6c9e0814522b95ad4eb17e54.js

Método __set_state()

De entre todos los métodos mágicos este es ejecutado en aquellas clases que han sido exportadas mediante var_export(). ¿Y qué coño hace var_export() te preguntarás?

Pues es una función que obtiene información estructurada sobre la variable que le pasemos como argumento, el resultado que obtenemos con var_export() es parecido a var_dump() salvo que el código que se obtiene es código PHP válido.

Así pues, cuando en nuestro código hagamos una llamada a var_export() podremos controlar la salida de este si definimos su comportamiento en el método mágico __set_state().

Internamente al llamar a var_export() y a diferencia de otros métodos mágicos, no se comprueba si existe __set_state() en nuestra clase por lo que es nuestra responsabilidad comprobar que solamente se reimporten los objetos cuyas clases declaren este método mágico.
https://gist.github.com/gorkamu/93005c2f3e58345fd222f46667d4f414.js

Método mágico __debugInfo()

Si el método __set_state() se ejecuta cuando se llama a var_export(). El método __debugInfo() se ejecutará cada vez que hagamos una llamada a var_dump() así de simple. Por defecto al llamar a var_dump() y no definir el método mágico en nuestra clase se mostrarán todas las propiedades de nuestra clase, las públicas, las protegidas y las privadas.

Este método mágico es una buena oportunidad para controlar qué propiedades de la clase han de mostrarse.
https://gist.github.com/gorkamu/bdcb95d367aa619bc33105210fea6477.js

Método __clone()

En artículos anteriores ya hemos hablado del proceso de clonación de objetos. Pues este es el método mágico que se invoca cuando se clona un objeto. Pero a diferencia de otros métodos mágicos que actúan como un evento de tipo PRE_EVENT este método se ejecutará después de que la clonación se haya realizado para permitirnos hacer cambios sobre las propiedades del objeto, como si de un evento POST_EVENT se tratase.
https://gist.github.com/gorkamu/9aa957ea198f2e4e13c729e92bd5b9e6.js

Métodos mágicos __isset() y __unset()

Cuando queremos evaluar si un nodo existe en un array o cuando queremos saber si una variable tiene contenido o esta vacía, lo solemos hacer con las funciones isset() y empty() respectivamente. Pues bien el método mágico __isset() es invocado automáticamente (si existe) cuando hacemos uso de estas dos funciones.

Por otro lado, si en nuestra clase hemos definido el método mágico __unset(), este se ejecutará cuando hagamos uso de la función unset() sobre un miembro de nuestra clase.

Utilizamos la función unset() para destruir una variable dada. Esta función se comportará de una manera o de otra en función del ámbito y del tipo de variable. Para saber cómo se comportará puedes echar un vistazo a este link en el que se cuenta con detalle el funcionamiento de la función.

Métodos __set() y __get()

Utilizamos estos métodos mágicos cuando queremos redefinir el comportamiento al establecer y acceder a valores de propiedades inaccesibles y lo hacemos sobrecargando los métodos.

Para que se entienda, si quieres que cada vez que se establezca un valor para una propiedad de una clase se imprima un mensaje por pantalla, tendríamos que sobreesccribir el método __set() y escribir allí el nuevo comportamiento.

Con el método mágico __get() pasa lo mismo pero para cuando accedes al valor de una propiedad.

Métodos útiles que podemos utilizar para crear los getter y setters de una clase de una forma dinámica sin tener que escribir cada conjunto para cada propiedad de una clase, por ejemplo…
https://gist.github.com/gorkamu/d5c736c208db994e3b25a0bac8767601.js

Métodos mágicos __call() y __callStatic()

El método __call() es invocado cuando intentamos acceder a métodos inaccesibles en el contexto de un objeto mientras que el método __callStatic() se invoca cuando accedemos a un método inaccesible en un contexto estático.

Como a lo mejor esto es un poquito güatdefak de entender, estoy seguro que con el siguiente ejemplo lo ves perfectamente.
https://gist.github.com/gorkamu/90f84a044b1c777683994ad734e906fb.js

Métodos __construct() y __destruct()

De estos métodos ya hablamos en artículos previos al curso y son invocados cuando instanciamos un objeto a partir de una clase o cuando destruimos un objeto respectivamente.

Tal vez el método destructor no lo utilices mucho, pero si tienes cierta experiencia en la programación orientada a objeto tendrás ya los huevos pelados de utilizar el constructor para inicializar variables de tu clase.
https://gist.github.com/gorkamu/8e9b8b3d0e01a967f8b3f271b4bd79f8.js

Es importante saber que si tienes una clase padre con un constructor que acepta dos argumentos mientras que la clase hija tiene un constructor con cinco no te va a fallar, así que tranquilo. Además para ejecutar el constructor de la clase padre desde el de la clase hija tendrás que hacerlo de la siguiente forma:

parent::__construct()

Por otro lado, el método destructor de una clase se ejecutará siempre cuando el motor de PHP ya no encuentre referencia alguna al objeto, así pues tipicamente los podemos utilizar para cerar conexiones a bases de datos o liberar memoria por ejemplo.
https://gist.github.com/gorkamu/c2ac43faec6e340f49f8492e865f7167.js

El método mágico destructor será invocado siempre sin ninguna excepción incluso cuando se detenga la ejecución del script mediante la función exit() pero si se llama a esta función dentro de un destructor se provocará que dejen de ejecutarse el resto de rutinas restantes a la finalización. Recuérdalo.

Pues nada, con esto ya hemos tocado el tema de los métodos mágicos. Si tienes dudas déjamelas a través de los comentarios o mediante twitter siguiendo el siguiente banner 😉

[xyz-ips snippet=”FAQS-GORKAMU-TW-YELLOW”]

Hala a mamarla!

Traits en la programación orientada a objetos

Continuamos con otro artículo mas sobre el curso de programación orientada a objetos. Si estas siguiendo los post día a día segurísimo que ya tienes unos conocimientos bastante avanzados y sino ¿a qué esperas gandul? Hoy vamos a explicar qué son los traits y cómo podemos utilizarlos así que… vamos allá!

¿Qué son los Traits?

Lo primero que tenemos que saber es que los traits son una característica propia de PHP y que fueron implementados en su versión 5.4. En otros lenguajes de programación te puedes encontrar con aproximaciones a los traits pero no como tal lo vamos a ver con PHP.

Los traits son un método que podemos utilizar para reutilizar código, ya sabes filosofía DRY y todo eso…

Como por su propia naturaleza PHP no implementa la herencia múltiple, podemos utilizar esta característica para solventar ese problema.

Así pues la naturaleza de un trait es reducir las limitaciones de la herencia simple permitiendo que nosotros, los programadores, podamos reutilizar fragmentos de código en un conjunto de clases independientes y jerárquicas una y otra vez y toooodas las veces que queramos, todo un lujazo para evitar duplicar código y trabajar mas 😛

Los traits son parecidos a las clases. Ellos agrupan funcionalidades muy específicas y de una forma coherente. Imagina que tienes una función que se conecta a la base de datos y escribe en una tabla de log la fecha y el nombre de cada una de las clases cada vez que se instancian.

Pues si no existieran los traits tendrías que escribir esta funcionalidad, con su complejidad, en todas las clases y sería un error porque si quisieras sustituir algo de la función tendrías que ir clase a clase y cambiando lo que quisieras on the fly y luego revisar que no te has olvidado nada y que no la has cagado en ninguna parte, un coñazo vamos…

Creando un solo ficherito con la funcionalidad y después añadiéndolo a tus clases como un trait ya tenemos apañao el problema.

Decía antes que un trait es como si fuera una clase, como si fuera ya que no lo es exactamente y por lo cual jamás vas a poder instanciar directamente un trait. Piensa en ellos como en un añadido a la herencia tradicional que nos habilita la composición horizontal de comportamientos, quiero decir, puedes añadir tantas funcionalidades transversales a las clases como te de la gana y sin tener que recurrir a una arquitectura compleja de herencia.

Pero… ¿cómo hago un trait?

Bueno pues si quieres empezar a abstraer los comportamientos de tu aplicación (trabajo difícil pero que denota inteligencia) y comenzar a crear traits no te asuste que es super sencillo. Mira el siguiente ejemplo que lo vas a ver todo mucho mas claro.
https://gist.github.com/gorkamu/b12c4da18d0952e8d2ba11158e2a126d.js

¿Ves? En el trait del ejemplo podemos agrupar aquellas funcionalidades que van a ser comunes para un conjunto de clases. En este trait hemos puesto los movimientos de andar, correr y nadar. Movimientos que van a realizar todos los animales de nuestro universo y después para que estos movimientos estén disponibles en nuestros animales solo tenemos que hacer uso de la palabra reservada use dentro de la clase.

Por suerte no solo podemos usar un trait por clase sino que podemos incluir tantos traits como nos de la gana, eso si separandolos entre ellos por punto y coma y utilizando use.

Sencillo que no?

¿Pero qué pasa si en el ejemplo que he puesto, tuviéramos un método que se llamase correr dentro de la clase Animal (clase padre) y otro igual dentro del trait?

Pregunta del millón y según la lógica de la programación todo nos indica a pensar que este escenario provocaría un pete en la aplicación. Pues no.

Aquí entra en juego lo que se llama el orden de procedencia y es que los miembros, ya sean constantes o métodos heredados desde una clase base se sobrescriben cuando se inserta otro miembro que se llama igual desde un trait.

Así pues y para que lo veas claro, si tenemos un esquema de una clase padre, una clase hija y un trait con métodos que se llaman igual, la clase hija va a sobrescribir los métodos del trait que a su vez va a sobrescribir los métodos de la clase padre.

Apúntate bien esta anotación porque puede caer en examen 😛
https://gist.github.com/gorkamu/5d7bb69fe3bb5aa68a8a17c7273cf2d8.js
Hablábamos antes de lo posibles petes en el orden de procedencia al utilizar métodos con el mismo nombre entre una clase padre y un trait pero existe una problemática y es que si decidimos dar el mismo nombre a dos métodos diferentes que se encuentren en dos o mas traits eso si que nos va a dar un pete y de los gordos, un error fatal siempre y cuando no lo hayamos prevenido mediante el uso de insteadof.

Aquí tienes un poquito mas de info sobre la resolución de conflictos en los traits.

Pero todavía hay un montón de cosas chulas que podemos hacer con los traits.

Origen, inception, traits que tienen traits…

Al igual que con las clases podemos definirnos una arquitectura jerárquica en nuestros traits y hacer que un trait implemente otro trait o un conjunto de traits e ir bajando en diferentes niveles de funcionalidades agrupadas.

Cuando un trait usa otro trait en su definición este puede estar formado parcial o completamente de los miembros definidos en esos otros traits.

Miembros abstractos y estáticos en los traits

No me canso de repetirlo, un trait es como una clase y por ende podemos hacer casi las mismas cosas que con las clases como por ejemplo definirnos nuestros miembros abstractos para que al utilizar el trait en una clase este le obligue a implementar los métodos que hayamos definido.

Pero también podemos utilizar y definir variables estáticas, métodos estáticos y propiedades.

A diferencia con los nombres de los métodos y el orden de procedencia, si definimos en el trait una propiedad tenemos que saber que no podemos volver a definir una propiedad con el mismo nombre en la clase que va a hacer uso del trait o de lo contrario PUM! vamos a obtener un bonito pete.

Por último y para cerrar el tema de los traits os voy a enseñar otra cosa muy chula que podemos hacer con ellos y es modificar la visibilidad de cualquier método de un trait desde la clase. Pero.. ¿cómo? Magia!

magic en los traits

Al hacer referencia a un trait en una clase mediante la palabra reservada use, podemos indicar entre corchetes el método al que queramos cambiar su visibilidad mediante el operador as.

Que tenga su utilidad, por supuesto, pero yo soy de la opinión que al igual que pasa con el casting de tipos, si tenemos que estar cambiando la visibilidad de los métodos es que tal vez no hayamos definido bien la aplicación y tengamos que darle una vuelta…

Pero es una opinión y a continuación tienes un ejemplo de esto que te acabo de contar.
https://gist.github.com/gorkamu/e2485407891179d4d658da8dd92bec3d.js
Hala, pues nada chachos, a seguir estudiando programación orientada a objetos y si tenéis alguna duda hacédmela saber en los comentarios o en twitter a través del siguiente banner.

[xyz-ips snippet=”FAQS-GORKAMU-TW-YELLOW”]

A mamarla!

Namespaces en la programación orientada a objetos

Seguimos con otro artículo mas sobre la programación orientada a objetos y hoy concretamente toca aprender qué son y cómo podemos utilizar los namespaces. Algo de mucha utilidad si estas siguiendo el curso y sobre todo si ya has visto el artículo dedicado a la autocarga de clases. Así que vamos para allá…

¿Qué son los namespaces?

Su traducción mas literal sería espacios de nombre, pero entiendo que esto no te diga nada así que vamos a ver una forma de entenderlo.

Imagina que estás re ordenando tu escritorio ya que lo tienes lleno de fotos, archivos y juegos. Como sería normal en una persona ordenada, empezarías a crear carpetas y directorios en el que agrupar los distintos ficheros por tipo por ejemplo o por fecha yo que sé, en cualquier caso estas agrupando ficheros relacionados bajo un criterio definido.

Así pues podemos tener el siguiente árbol de directorios:

  • /home/usuario/gorkamu/Escritorio/fotos/fotovacaciones.png
  • /home/usuario/gorkamu/Escritorio/no-mirar-aqui/esto-no-es-porno.mpg

Como ves hemos organizado nuestros ficheros según dos criterios, ficheros que no nos importan que vean y ficheros que no queremos que otras personas vean (vale, ya sé que no es la mejor solución pero es un ejemplo coño)

Dentro del directorio de fotos podemos tener tantas fotografías como nos de la gana pero lo que nunca podemos tener son dos ficheros con el mismo nombre dentro del mismo directorio.

Pues extendiendo este concepto a la programación orientada a objetos conseguimos los namespaces, se entiende no?

Los namespaces los utilizamos para agrupar de una manera lógica nuestras clases y evitar los conflictos entre nombres debido a que podemos utilizar alias en ellos para renombrar una clase.

Definiendo namespaces

Aunque podemos definir cualquier script mediante los espacios de nombre, en la práctica solo se ven afectadas por los namespaces las clases, las interfaces, los traits, las funciones y las constantes. Si queremos definir un espacio de nombres para nuestra clase tenemos que haces uso de la palabra reservada namespace y siempre al principio del script.

No puede existir otra cosa antes salvo la sentencia declare utilizada para declarar la codificación del fichero.

<?php

namespace AplicacionLibreriaComponents as Componentes;

class PredectiveSearch 
{
...
}

¿Ves el ejemplo? Pues así de sencillo es definir un namespace. Ah y le hemos dado un alias como ves por la palabra as. Esto viene guay por si tienes diferentes namespaces con el mismo nombre pero en “rutas” distintas, para que no pete y tal… Y viene a ser como manejan los sitemas Unix los enlaces simbólicos

Como he dicho mas arriba, utilizamos los namespaces para “agrupar” clases, interfaces, funciones, traitrs y constantes y parece lógico que cada una de estas estructuras tenga únicamente un único espacio de nombres, algo así como el camino hacia su casa, pero… ¿qué pasa si te digo que podemos hacer que puedan tener varias casas? Por ejemplo, la residencia habitual en Madrid y luego el chabolo en Torrevieja.

Pues de hecho podemos declarar varios namespaces para estas estructuras sin que se rompa nada, mira el ejemplo anda:
https://gist.github.com/gorkamu/45baf2690e990d059d54c4e2f89610b3.js

Como ves podemos utilizar varios namespaces dentro del mismo fichero. Existen varias sintaxis diferentes para hacer esto y de ellas esta es la menos mala. Digo esto porque se desaconseja su uso con las buenas practicas. Un fichero únicamente debería tener un solo espacio de nombres pero bueno hay que conocer la mierda para tratar de evitarla.

En cualquier caso, tenemos que conocer como funciona el motor de PHP a la hora de resolver espacios de nombres y es que y es que para referenciar el nombre de una clase podemos hacerlo de diferentes formas:

  • Con nombres no cualificados, es decir, si el namespace actual es AplicacionLibreria la clase se resolvería con: $search = new PredectiveSearch()
  • Con nombres cualificados o con el nombre de la clase con prefijo, por ejemplo: $seach = new LibreriaPredectiveSearch()
  • Con nombres completamente cualificados o el nombre de la clase con prefijo con el prefijo de operador global: $seach = newAplicacionLibreriaPredectiveSearch()

Es un pelín lioso pero si utilizáis IDEs ultrainteligentes como PHPStorm no os tenéis que preocupar de esto ya que os lo resolverá el solito 😛

PHP ofrece dos mecanismos para acceder de una forma bastante abstracta a elementos que se encuentren en un namespace, esto es mediante la palabra reservada namespace y mediante la constante reservada __NAMESPACE__ cuyo valor será el espacio de nombres que hayas definido para ese fichero.

<?php
namespace AplicacionLibreria;

echo '"'.__NAMESPACE__.'"'; // imprime "AplicacionLibreria"

Es importante saber que si no se define ningún namespace, todas las clases, funciones, métodos, interfaces y constantes tendrán un ámbito global.

Como curiosidad no está de mas saber como PHP resuelve los espacios de nombres con estas seis reglas:

  • Cualquier elemento con un nombre completamente cualificado se resuelve durante la compilación.
  • Los elementos con nombres cualificados o no cualificados (no completamente cualificado) se resuelve durante la compilación en función de las reglas de importación presentes.
  • Dentro de un espacio de nombres, todos los nombres cualificados no traducidos según la reglas de importación llevan antepuesto el espacio de nombres actual.
  • Los elementos con nombres no cualificados son traducidos en la compilación según las reglas de importación actuales.
  • Dentro de un namespace, las llamadas a funciones con nombres sin cualificar se resuelven durante la ejecución.
  • Dentro de un namespace, las llamadas a funciones con nombres no cualificados o cualificados (no completamente cualificados) se resuelven durante la ejecución.

Así pues con estas reglas y un poquito de sentido común vais a ser capaz de construir aplicaciones muy organizadas, algo primordial cuando la complejidad crece. Se que el tema de los namespaces no es tan sencillo como definir una “ruta” al principio del fichero y a correr, por eso os voy a dejar este enlace con preguntas y respuestas típicas contestadas por si os liáis y también lo que os digo siempre, si tenéis cualquier duda, necesitáis mas ejemplos o simplemente me queréis poner a parir podéis hacerlo en los comentarios mas abajo o en twitter a través del siguiente banner.

[xyz-ips snippet=”FAQS-GORKAMU-TW-YELLOW”]

Hala a mamarla!

Autocarga de clases en la programación orientada a objetos

Si estas siguiendo a pies juntillas los artículos dedicados a la programación orientada a objetos es muy posible que ya tengas unos conocimientos técnicos bastante avanzados, de hecho es posible hasta que ya hayas hecho algún programita y si has seguido las buenas prácticas habrás creado un fichero por cada clase no? Es lo típico vamos… Y no te has encontrado con el problema de querer utilizar varias clases en un script y ver que el comienzo del fichero se te llenan de mas y mas requires e include ?

Jajajaja ya te contesto yo. Si. A no ser que hayas utilizado lo que vamos a ver en este artículo que no es nada mas y nada menos que…

Usando la autocarga de clases

La autocarga de clases viene a solucionar precisamente el problema anterior. Tener que incluir todas las clases que vayamos a utilizar en cada uno de nuestros scripts. Tal vez para scripts pequeñitos o POC no sea un problema pero ya te digo yo que cuando estas desarrollando una aplicación empresarial grande se vuelve un coñazo.

Desde la versión 5 de PHP se incluye un mecanismo para auto cargar las clases automáticamente y es mediante la función spl_autoload_register() que se encarga de registrar cualquier número de cargadores.

Esto tiene varias ventajas como el hecho de que podemos hacer que se carguen clases e interfaces automáticamente si no están definidas actualmente. Haciendo uso de los autocargadores estamos dando una última oportunidad al motor de PHP de cargar los recursos necesarios antes de que pete por omisión.

Lo chulo de la función que gestiona la autocarga de clases es que internamente hace uso del método mágico __autoload() que es proporcionada por la spl. Si en tu script aparece esta función (damos por hecho que si aparece es porque estás haciendo autocarga de clases) es necesario que la función esté explicitamente registrada en la cola __autoload para que no falle.

Ahora bien, como sabes, cuando desarrollamos con PHP podemos hacer scripts que se presenten en el navegador como páginas web o podemos hacer utilidades para la consola. Si señores, podemos hacer nuestros propios programitas con PHP para correrlos desde la terminal, el CMD, la consola o como quieras llamarlo.

Pues si haces una utilidad para el Command Line Interface has de saber que la autocarga de clases no te va a funcionar si lo utilizas en el modo interactivo. Echa un vistazo al enlace anterior para saber que es el modo interactivo de la CLI anda 😉
https://gist.github.com/gorkamu/6abe2d3c7a99b9f96883983ca1aca4dc.js

Como ves en el ejemplo no estoy haciendo uso de ningún include o require, tan solo hago una llamada a la función spl_autoload_register.

Pues nada chachos esta vez ha sido un artículo cortito, si tienes dudas o necesitas mas ejemplos o ejercicios pídemelos en los comentarios o en twitter a través del siguiente banner .

[xyz-ips snippet=”FAQS-GORKAMU-TW-YELLOW”]

Hala a mamarla!

Clases anónimas en la programación orientada a objetos

En los artículos anteriores sobre programación orientada a objetos hemos visto cómo crear nuestras propias clases, con sus propiedades y métodos e instanciarlas. Pues hoy os vengo a contar cómo crear clases anónimas y que usos podemos hacer de ellas que sin duda son muchos, otro pasito mas hacia el dominio de la programación orientada a objetos. Así que vamos para allá…

¿Qué son las clases anónimas?

Las clases anónimas aunque ya existían en otros lenguajes desde hace tiempo, por ejemplo en Java se utiliza mucho, en PHP fueron introducidas en la versión 7. Decíamos que las clases “normales” son las plantillas predefinidas que después crearán objetos con ciertas características y acciones disponibles pues bien, las clases anónimas son un sistema para crear objetos on the fly, es decir objetos sencillos y únicos.

Es decir, si no necesitas tener una entidad o un objeto que persistir o una clase que sea fundamental para tu lógica de negocio, las clases anónimas te pueden servir para tratar algo por un breve periodo de tiempo como un evento por ejemplo. Es decir, utilizaremos clases anónimas cuando necesitemos que se definan y destruyan en tiempo de ejecución ahorrando así en memoria y mejorando el rendimiento de nuestra aplicación.

¿Creo que se entiende no?

Bueno pues las clases anónimas pueden hacer casi las mismas cosas que el resto de clases y esto es:

  • Pueden aceptar argumentos a través de sus constructores.
  • Pueden heredar de otras clases.
  • Pueden implementar interfaces.
  • Pueden utilizar traits.
  • No se define nombre para clase anónima.
  • Todos los objetos creados por una clase anónima son instancias de la misma clase.

Como el tema en general ya es bastante abstracto creo que lo mejor que se puede hacer para entender el concepto de clase anónima es utilizar ejemplos así que…
https://gist.github.com/gorkamu/d8e34772b80210c1cae1069318b7a5f9.js

Como veis en el ejemplo, antes de PHP 7 necesitábamos tener definida una clase Logger ocupando espacio reservado en memoria. Pues bien, con las clases anónimas eso ya no es necesario, se crea la clase cuando es necesario y siempre en tiempo de ejecución.

¿Pero y qué pasa si queremos utilizar argumentos o heredar de una clase o implementar una interfaz como decíamos antes?
https://gist.github.com/gorkamu/8152132f616b3d913963bc8a960d7c8b.js

Un aspecto importante a tener en cuenta en relación con las clases anónimas es que si tenemos una clase “normal” y metemos (o anidamos) una clase anónima dentro de esta, no podremos utilizar los métodos ni propiedades de la clase “normal” dentro de la anónima pero por suerte existen mecanismos para hacerlo:

  • Si queremos utilizar los métodos y propiedades protegidos de la clase “normal” en la clase anónima tendremos que hacer que la clase anónima herede de la clase “normal”.
  • Si queremos utilizar las propiedades privadas de la clase “normal” dentro de la anónima, tendremos que pasárselos al constructor de la clase anónima.

Fíjate bien en el siguiente ejemplo:
https://gist.github.com/gorkamu/812c87a119c7649446f182f6832517ba.js

Por último decir que antes os contaba que una clase anónima no define ni tiene nombre, pues era un poquito mentira ya que aunque nosotros no definamos un nombre como tal, las clases anónimas se crean en tiempo de ejecución y es el motor de PHP (digamos compilador) el que se encarga de darle un nombre y una posición en memoria a la que acceder por lo que dónde antes teníamos esto:

echo get_class(new class {});

Internamente tendremos esto:

class@anonymous/in/oNi1A0x7f8636ad2021

Por cierto, no utilicéis este nombre para referenciar, simplemente es un nombre aleatorio basado en un hash que se utiliza internamente. Si tienes necesidad de llamar, referenciar, instanciar una clase anónima es mejor que sigas otra estrategia y te construyas una clase “normal”.

 

Bueno, como se que el tema es bastante jodido para alguien que está empezando a estudiar programación orientada a objetos, si tienes alguna pregunta o necesitas mas ejemplos puedes dejarme tus comentarios un poquito mas abajo o también puedes hacerme llegar tu feedback a través de Twitter mediante el siguiente banner y encantado que estaré de echaros una mano al cuello 😛

[xyz-ips snippet=”FAQS-GORKAMU-TW-YELLOW”]

Hala a mamarla!

Interfaces en la programación orientada a objetos

Pues hoy vamos a hablar de las interfaces en la programación orientada objetos. Si estas siguiendo la serie de artículos dedicados a aprender sobre programación POO ya habrás visto como crear objetos, clases, clases abstractas y habrás aprendido sobre métodos, propiedades y su visibilidad, en fin… un conjunto de conceptos teóricos que te estarán dando una nueva perspectiva sobre la tecnología, o eso espero vamos…

Y hoy precisamente toca eso, ver las interfaces y cómo y cuando podemos implementarlas así que…vamos a ello!

¿Qué son las interfaces?

Las interfaces vienen a ser como una declaración de funcionalidades obligatorias que tienen que realizar aquellas clases que implementen la interface. A diferencia de como vimos con las clases abstractas, las interfaces no declaran sus métodos nunca, tan solo definen los métodos. Esto es, en una interface aparecerá pues el nombre del método junto con su visibilidad y la definición de argumentos para jamás pueden describir código, entonces sería una clase abstracta.

Otra diferencia respecto al uso entre interfaces y clases abstractas es que una clase cualquiera puede implementar tantas interfaces como le de la gana pero únicamente puede heredar de una clase, ya sea abstracta o no, al menos en PHP y esto es lo que se conoce como herencia simple.

Cuando veamos el artículo de herencia de objetos veremos las diferencias entre herencia múltiple y herencia simple.

Volviendo al tema de las interfaces tenemos que saber que en el sentido estricto de la definición, una interface es como si fuera una hoja de ordenes diciéndonos qué es lo que hay que hacer pero no como. Una interface estará formada pues únicamente por constantes y la definición de sus métodos, que jamás serán abstractos (sino hablaríamos de clase abstracta)

Una interface es el claro ejemplo de la abstracción.

https://gist.github.com/gorkamu/7fb35daa09e7562ed31e39c8b1d7968a.js

Al implementar una interface en una clase se nos está obligando a implementar siempre todos los métodos que defina, nos guste o no, aunque existe una excepción que no se suele utilizar y es que si una clase abstracta implementa una interface, esta no esta obligada a implementar los métodos de la interface.

Para hacer uso de una interface tendremos que hacerlo mediante el operador implements junto al nombre de la clase, tal y como hemos visto cuando heredamos (o extendemos) de otra clase. Pero que esto no te despiste porque no es exclusivo que las interfaces solo se utilicen con implements y las clases con extends ya que las interfaces también pueden heredar de otras interfaces.

Hemos dicho que una interface está formada por la definición de sus métodos y por constantes, pues bien estas constantes funcional igual que si fueran constantes de clases pero se diferencian en que estas no puede ser sobrescritas por la clase/interface que la herede o de lo contrario nos dará un error.

Las interfaces suponen junto con la determinación de tipos de una buena forma de asegurarse de que un determinado objeto contiene ciertos métodos y para ello el operador instanceof() juega un papel muy importante. Checkea el enlace anda 😉

Pues nada amigüitos, se que el tema es complejo debido a que estamos tocando temas bastante abstractos así que si tienes alguna pregunta no dudes en dejármela en los comentarios o en twitter a través del siguiente banner.

[xyz-ips snippet=”FAQS-GORKAMU-TW-YELLOW”]

Hala a mamarla!

Clases abstractas en la programación orientada a objetos

Echa la vista atrás y mira cuantas cosas has tenido que aprender si has seguido esta serie de artículos. Si te has leído cada uno ya serás capaz de crear clases y objetos, inicializar y destruir valores con sus constructores y destructores respectivamente, habrás aprendido los diferentes tipos de datos que tenemos y su visibilidad entre otras cosas. Pues bien, en esta entrada vamos a ver qué son las clases abstractas en la programación orientada a objetos.

¿Qué son las clases abstractas?

Una clase abstracta es aquella que no se puede instancias. Si una clase posee un método abstracto por narices ha de ser abstracta también. Por lo general utilizamos las clases abstractas para definir comportamientos comunes o generales pero sin especificar como lo hacen. Es habitual que los métodos de estas clases abstractas no tengan cuerpo de declaración, es decir, solo tienen la definición del método, el nombre y la visibilidad vaya.

¿Pero esto como puede ser? Pues muy sencillo, imagínate a las clases abstractas como simples guiones o conjunto de TODOs para otras clases. En ellas se indican que tareas hay que hacer pero no cómo hacerlas y serán las clases hijas que hereden de las clases abstractas las que decidan cómo hacer esas tareas.

Por ejemplo, mi padre decide que su coche esta muy sucio y me ordena que debo lavarlo, pero no me indica como. Puedo llevarlo a un túnel de lavado, puedo darle con la manguera o puedo coger un barreño de agua, jabón y un cepillo y limpiarlo a mano, uuuff… que pereza…

Pues en este ejemplo mi padre sería la clase abstracta y sus ordenes los métodos abstractos. Cómo decida implementar yo sus ordenes (soy la clase hija) es problema mio.

Pero no solo sirven para definir comportamientos comunes, también sirven para asignar diferentes características y propiedades comunes a las clases hijas.

Vuelve a pensar en mi padre, una característica que heredaré por ser su hijo es su apellido y su tendencia a ser morenos de pelo, aquí ya entramos en genética, pero tal vez lo que no herede son sus gustos musicales, mientras que él escucha a Sabina yo puedo deleitarme con ACDC, por ejemplo…

Tan solo aquellas características y propiedades comunes que definen a un conjunto de clases jerárquicas deberán de ser heredadas, no así las propiedades exclusivas de una única clase. ¿Se entiende no?

Pues bien, con este tipo de clases hay ciertas reglas, características o normas que tenemos que tener en cuenta:

  • Si se definen métodos abstractos en una clase abstracta, todas las clases que hereden de ella han de implementar todos esos métodos.
  • Las clases abstractas si que pueden heredar de otras clases y no tienen porque ser estas abstractas también.
  • El número y tipo de datos de los argumentos de una clase abstracta han de respetarse siempre en las clases hijas.
  • Si una clases esta formada solo por métodos abstractos y constantes entonces es una interface.

En otros lenguajes de programación y no solo en PHP, las clases abstractas están muy relacionadas con el polimorfismo, pero vamos a ver qué es el polimorfismo porque tiene un nombre muy chulo pero puede liar un poquillo…

Cómo utilizar las clases abstractas con el polimorfismo

Agárrate bien los machos porque el polimorfismo junto con la encapsulación y la herencia son las tres patas fundamentales de la programación orientada a objetos, bueno y los objetos claro.

Tal y como sugiere su nombre, el polimorfismo indica muchas formas y en programación esto se puede referir a diferentes comportamientos en función del contexto en el que se este ejecutando la clase.

Pero esto es bastante abstracto, mejor si lo vemos con un ejemplo y para ello vamos a hacer una jerarquía de clases.
https://gist.github.com/gorkamu/d312262a1d38caf4b0da251a31ec19cf.js
Tal y como ves en el ejemplo, he creado cuatro clases:

  • Una clase abstracta que representa el concepto de animal con el método moverse().
  • Una clase Gorrino que hereda de la clase Animal y que implementa el método moverse().
  • Una clase Pajarico que hereda de la clase Animal y que implementa el método moverse().
  • Una clase Acción que tiene un método andar() al que se le pasa un objeto del tipo Animal y ejecuta el método moverse().

Pues bien, hemos metido un animal de cada clase en un array y lo recorremos. Cada uno de los animales se lo pasamos a la acción para que se mueva y sus resultados son los siguientes:

// El gorrino corre
// El pajarico vuela

Vale y a lo mejor te estés preguntando por el polimorfismo y dónde se encuentra en este script. Pues se encuentra en nada mas y nada menos que en la definición del método anda() de la clase Accion. Hemos dicho que espera que le pasemos un argumento del tipo Animal y el método únicamente comprobará que lo que le pasemos herede de esa clase y le dará igual si se trata de un Gorrino o de un Pajarico.

Pues eso es el polimorfismo y ese es el uso que podemos hacer de las clases abstractas. Bueno no es el unico obviamente pero si el mas fácil de ver y explicar 😛

Si después de esto y a medida que programes eres capaz de abstraer tus programas significará que has entendido a la perfección el problema que estas tratando de resolver por lo que enhorabuena aunque no te agobies que se necesita practica y a veces es mejor dar una solución concreta que lucirte haciendo un programa to guapo pero alargando los tiempos de entrega 😉

Se que el tema es bastante difícil de ver y entender si es la primera vez que te encuentras con ello así que si necesitas mas explicaciones o ejemplos por favor pídemelos en los comentarios o en twitter a través del siguiente banner.

[xyz-ips snippet=”FAQS-GORKAMU-TW-YELLOW”]

Hala a mamarla!

Objetos en la programación orientada a objetos

Ya hemos visto en artículos anteriores que son los objetos en la programación orientada a objetos pero en este artículo quiero entrar en detalle con una definición bastante aproximada de qué es un objeto y ver diferentes acciones que podemos hacer con ellos como la clonación o la comparación entre ellos, así que… vamos allá.

¿Qué son los objetos en la programación orientada a objetos?

Pues bueno, si eres nuevo y llegas a este tipo de programación lo primero que pensarás es que deben de ser algo importante dentro de este paradigma y así es ya que dentro de la POO son el pilar fundamental y los utilizamos para representar objetos cotidianos de la vida real. Pero antes de entrar mas en el barro vamos a ver qué es lo que dice la wikipedia

En el paradigma de programación orientada a objetos (POO, o bien OOP en inglés), un objeto es una unidad dentro de un programa de computadora que consta de un estado y de un comportamiento, que a su vez constan respectivamente de datos almacenados y de tareas realizables durante el tiempo de ejecución. Un objeto puede ser creado instanciando una clase, como ocurre en la programación orientada a objetos, o mediante escritura directa de código y la replicación otros objetos, como ocurre en la programación basada en prototipos.

Así es, imagínate a un objeto como una estructura no como un valor. Una estructura como un conjunto de valores y de posibles acciones que puede realizar encapsuladas en una única unidad. Para que lo visualices piensa en el número 5. Imagínate que por el hecho de ser un número contiene por si mismo su símbolo, positivo en este caso, y puede sumarse una unidad y restarse una unidad.

Por lo cual el objeto del número que hemos descrito sería tal que así:
https://gist.github.com/gorkamu/970503dd8b0398a5a016d1005501c9b6.js

Lo interesante de los objetos es que cuando los utilizamos en funciones y los pasamos como argumento, no estamos pasando su valor como si se tratase de un tipo de dato como un integer por ejemplo. Un objeto no es un valor. Al pasarlos a una función como argumento estamos pasando su referencia.

Si recuerdas post anteriores, pasar un argumento por referencia significa que lo que modifiquemos dentro de la función se verá afectado fuera de la función también y esto es así porque la referencia es el identificador que indica donde se encuentra ese valor u objeto en memoria. No se hace una copia vaya…

Con los objetos todos son referencias, cuando los pasamos a una función o los devolvemos o se asigna a otra variable, todas las distintas variables guardan una copia de ese identificador que apunta al mismo objeto.

Pero… ¿y qué cosas podemos hacer con los objetos?

Comparación de objetos

Si tenemos dos objetos, podemos evaluar que estos sean iguales o no. Cuando comparamos dos instancias, se realiza una comparación de bajo nivel mirando que todos los valores y atributos sean iguales y que pertenezcan a la misma clase. Podemos realizar dos tipos de comparaciones utilizando diferentes operadores:

  • Operador de comparación: se comparan de forma sencilla las variables y que ambas instancias pertenezca a la misma clase. Para ello utilizamos el operador doble igual (==)
  • Operador de identidad: dos objetos son iguales si sus variables son idénticas sí y sólo sí hacen referencia a la misma instancia de la misma clase. . Para ello utilizamos el operador triple igual (===)
Offtopic:

En Java tenemos los métodos mágicos __equals(),__compareTo() y __compare() para comparar objetos. Aquí mas información

https://gist.github.com/gorkamu/a8615b0270aa92ebe67e3c85a3d9b098.js
Clonación de objetos

Otra acción que podemos hacer con ellos es clonarlos. A veces no nos interesa hacer una copia de un objeto realizando una replicación completa de sus propiedades sino que nos interesa hacer una replica que genere una nueva instancia de ese primer objeto y aquí es donde entra la clonación.

Si queremos hacerlo tenemos que utilizar la palabra reservada clone que internamente hace una llamada al método mágico __clone() del objeto. Si en lugar de utilizar la palabra reservada intentas hacer una llamada al método mágico no te va a dejar realizarlo.
https://gist.github.com/gorkamu/bc27596742d258345e5a37ada0a64a40.js

Serialización de objetos

Te estarás preguntando que qué coño es la serialización ¿no? Pues no es otra cosa que el proceso de representar mediante un string, texto vamos, un objeto. Cuando serializamos uno de ellos lo que pasa es que obtenemos en formato texto el nombre de la clase junto con los valores de ese objeto.

Podemos llevarlo a cabo mediante la función serialize() que tal y como indica su documentación genera una representación almacenable de un valor que no pierde ni su tipo ni su estructura.

Por otro lado, si ya tenemos en un string la representación de un objeto y queremos volver a convertir esa representación a objeto podemos hacerlo mediante la función unserialize() que realiza el proceso contrario a serialize()

Todo este proceso de serializar y deserializar un objeto forma parte del sistema de sesiones de php. Cuando registramos un objeto en la sesión este se serializa automáticamente y automáticamente también se deserializa para cada petición.
https://gist.github.com/gorkamu/ff9fe51208d71a9da53eff56b41703ce.js

Iteración de objetos

La iteración de objetos es el proceso que permite recorrer e iterar cada una de las propiedades de un objeto. Imagina que tienes el objeto de una clase y quieres saber que valores tienen sus propiedades, podrías hacerlo con la función serialize() claro pero no sería una buena practica, lo haríamos a través de un bucle foreach, aunque únicamente devolverá todas las propiedades public si no lo implementamos en una función dentro de la clase.

Ejemplo:
https://gist.github.com/gorkamu/430cc2f1f23246dd146a707dd92628e5.js

Como se ve en el script, el bucle que se encuentra fuera de la clase únicamente tendrá acceso a las propiedades públicas y sin embargo mediante la función iterar() podemos acceder a todas las propiedades, públicas, protegidas y privadas.

También podemos hacer uso de interfaces para realizar este propósito e implementar la interfaz Iterator. Esta interfaz nos da la herramientas para poder decidir y definir como ha de iterarse un objeto y que valores serán utilizados.
https://gist.github.com/gorkamu/40c297d225121156ee65b9c4afc7a843.js

Pues nada chachos, con este post hemos definido qué son los objetos en la programación orientada a objetos y qué acciones podemos hacer con y sobre ellos. Se que el tema es duro y espesito así que si tienes alguna pregunta no dudes en hacérmela a través de los comentarios o poniéndome un tweet mediante el siguiente banner y te prometo que te responderé lo antes posible.

[xyz-ips snippet=”FAQS-GORKAMU-TW-YELLOW”]

 

Hala a mamarla!

Tipos de datos y argumentos en la programación orientada a objetos

Si estás siguiendo esta serie de artículos relacionados con la programación orientada a objetos ya tendrás unos datos mínimos necesarios para empezar a crear tus pequeños scripts. Pues bien, hoy vamos a explicar qué tipos de datos podemos utilizar en nuestros programas y cómo pasárselos a nuestras funciones o métodos, lo que se conoce como paso de argumentos vaya…

¿Qué son y cuántos tipos de datos existen?

Gran pregunta. Ya sabes lo que es una variable, pero si por un casual has caído en el post sin haber leído los artículos anteriores (te recomiendo que te los leas) imagina que una variable es como una caja vacía. En función del tamaño de la caja vas a poder guardar diferentes cosas en ella, desde un boli, a una pelota, una televisión o un conjunto de otras cajas mas pequeñitas.

Pues una variable es eso, una caja en la que guardar datos y los objetos que he dicho antes son los diferentes tipos de datos. Si por ejemplo intentas guardar una televisión en una caja que está pensada para guardar bolígrafos vas a comprobar que es imposible. Pues eso también pasa en la programación.

Internamente las variables son espacios de memoria reservada y para optimizar la memoria siempre se reserva el espacio que necesita el tipo de dato que contendrá la variable, es decir, si quiero guardar la tele en mi armario voy a reservar una caja que tenga el tamaño de la televisión que me interesa almacenar.

En los lenguajes de programación fuertemente tipados esto se respeta to the limit, con ellos no puedes guardar un tipo de dato diferente al tipo de dato con el que has declarado la variable. C y C++ es un lenguaje de programación con un tipado fuerte y me gusta especialmente ya que aunque el ritmo de programación sea mas lento que en comparación con otros lenguajes te aseguras que tu programa es robusto ya que por ejemplo te quitas la preocupación de que se pueda guardar una televisión en una cajita de bolígrafos.

Sin embargo también existen los lenguajes con un tipado débil, como PHP hasta su versión 7 y… y… Estos lenguajes son mas laxos a la hora de permitir guardar datos diferentes en las variables, de hecho esto puede ser una ventaja a la hora de programar pero también te exige estar mas atento a medida que escribes para no cagarla.

Pues bien, en PHP tenemos los siguientes tipos de datos:

Tipo de dato Descripción Valores Ejemplo
Boolean Es el tipo mas simple de todos y su valor representa una verdad. true/false $var = true;
Integer Es un número entero y puede especificarse con notación decimal (base 10), hexadecimal (base 16), octal (base 8) o binaria (base 2), opcionalmente precedidos por un signo (- o +). Números enteros $var = 1;
Floats Es un número decimal o número de punto flotante. Números decimales $a = 1.234;
$b = 1.2e3;
$c = 7E-10;
Strings Texto o cadena de caracteres. Texto $var = ‘Gorkamu’;
Arrays Estructura que puede guardar un conjunto de otros datos. En realidad es un mapa ordenado en el existen nodos con una clave y un valor. Conjunto de valores $var = [1 => ‘Hola’, 2 => ‘Gorka’];
Object Un objeto de una clase que se crea con la palabra reservada new Objeto $var = new Gorkamu();
NULL Sin valor null $var = null;
Atención

Los arrays son complejos, por favor revisa este documento para saber mas de ellos.

Mantén esta tablita a mano que a medida que aprendes y vas adquiriendo soltura con los tipos de datos te será muy útil.

Ya has aprendido a crear variables con diferentes tipos de datos, ahora toca pasarle esos valores a las funciones y métodos que programes.

Pasando argumentos a funciones y métodos

Bien, en este artículo anterior habrás aprendido que son los métodos y/o funciones, en el fondo es lo mismo y lo mas importante, habrás aprendido a crearlos. Pues ahora vamos a ver cómo pasarle datos a esas funciones.

Si te cuesta un poco visualizarlo imagínate una cadena humana en la que el primero de la fila tiene un bol lleno de palomitas y tiene que pasárselo al último que le ha pedido unas pocas. Siguiendo la cadena, el bol de palomitas ira pasando de persona en persona hasta llegar al último. Pues cada persona es una función o método que recibe algo (el bol de palomitas) y devuelve algo (el bol de palomitas)

Es posible que algún miembro de la fila manipule el bol de palomitas, tal vez alguno se lo pasará al siguiente sin hacerle nada, otro cojera un puñado, otro le echará un poquito mas de sal y si por desgracia en la cadena humana tenemos a un gordo fanegas es muy posible que se coma el bol de palomitas y no llegue nada.

¿Ha quedado claro no? xD

Pues eso, en PHP podemos pasar tantos valores, de ahora en adelante argumentos, como nos de la gana. Tendremos que separarlos por comas y existen tres formas diferentes de pasar los argumentos a las funciones.

Paso de argumentos por valor

Es el paso de argumentos por defecto. Cuando pasas un argumento a la función y el valor de este argumento cambia dentro de la función, su valor original, el de fuera de la función no se verá afectado.
https://gist.github.com/gorkamu/ff4a0be97e0c2f654d1eaf4d3a765c52.js

Paso de argumentos por referencia

Cuando pasas un argumento por referencia, si cambias o modificas su valor dentro de la función su valor original, fuera de la función, también se verá afectado. Para indicar que un argumento se pasa por valor lo tenemos que hacer indicándolo con el ampersand (&)
https://gist.github.com/gorkamu/ab2daeca875374646377f0283e52852c.js

Puede ser útil para modificar valores en funciones sin tener que indicar un return.

Paso de argumentos predeterminados

Si definimos una función que acepte argumentos es posible que nos interese que alguno de ellos tenga un valor por defecto. Si a la hora de llamar a esa función no le pasamos valor para ese argumento, el argumento tomará el valor por defecto dentro la función. Por el contrario, si a la función le indicamos un valor para argumento, ese argumento tomará dentro de la función el valor que hemos pasado.
https://gist.github.com/gorkamu/5b460caf1c7e957d98ca70de8df1d0d1.js
Otra cosa interesante que podemos hacer respecto a los argumentos de una función es definir una lista de longitud variable, esto es, en la declaración de la función no tenemos porque indicar uno por uno los argumentos que vamos a pasar. Si utilizamos el token “…” antes del argumento, PHP ya sabrá que se trata de una lista variable aunque eso si, todos los argumentos pasados han de ser del mismo tipo.
https://gist.github.com/gorkamu/2686a295c7209d525843af22e1740bfa.js
Pues nada chavales, a practicar y a realizar un huevo de ejercicios para que estos son conceptos se posen en tu cabecita y ya sabes, si tienes dudas dejame un comentario y te la resolveré o ponme un tweet a través del siguiente banner 😉

[xyz-ips snippet=”FAQS-GORKAMU-TW-YELLOW”]

Hala a mamarla!