Advertisement
  1. Code
  2. PHP

Aprendiendo OOP en PHP lo antes posible!

Scroll to top
Read Time: 12 min

Spanish (Español) translation by Luis Chiabrera (you can also view the original English article)

PHP es mucho más que un lenguaje de scripting. Es un lenguaje completo capaz de crear aplicaciones muy complejas. Al aprovechar todo el poder de la programación orientada a objetos, puede reducir la cantidad de tiempo que pasa codificando y usarla para crear mejores sitios web. Este tutorial te mostrará cómo.




¿Qué es la POO?

OOP significa Programación Orientada a Objetos. La programación orientada a objetos es un paradigma de programación en el que se crean "objetos" para trabajar. Estos objetos se pueden adaptar a sus necesidades específicas, para servir a diferentes tipos de aplicaciones mientras se mantiene el mismo código base. Muy útil por cierto.

¿Qué es un objeto?

Un objeto es simplemente una copia o instancia de una "clase". Una clase puede definirse como una "caja negra" desde donde creamos nuestros objetos y accedemos a sus atributos (variables) y métodos (funciones). La analogía más común que se da cuando se explican las clases y la POO es cómo conduce un automóvil: básicamente, tiene 2 o 3 pedales, una palanca de cambios y un volante. No necesita (y lo más probable es que no quiera) saber cómo funciona el automóvil cuando presiona los pedales. Solo quieres que tu auto vaya hacia adelante y hacia atrás, a la izquierda ya la derecha. Y OOP es precisamente eso. No necesita saber cómo funcionan los métodos de una clase (si no lo implementó usted mismo), simplemente lo que hacen. La OOP también es útil si tiene un gran número de objetos del mismo tipo en un sistema: solo tiene que crear los objetos y luego manipularlos de la misma manera, sin volver a escribir ningún código. Además, un objeto es capaz de mantener su estado (valores variables y similares) durante la ejecución del programa.

Además, un objeto es capaz de mantener su estado (valores variables y similares) durante la ejecución del programa.

OOP en PHP

PHP 5 (aunque la mayoría de las ideas en este artículo también se aplican a PHP 4) tiene un gran soporte para la programación orientada a objetos al proporcionar una creación de clase fácil. PHP proporciona todos los paradigmas que otros implementos de lenguajes OOP "verdaderos" (Python y JAVA, por ejemplo), como herencia, polimorfismo y encapsulación.

Herencia

La idea básica detrás de la herencia es que los objetos similares comparten propiedades comunes. Entonces, al crear una clase "genérica", podemos tener un plan para construir nuestras clases subsiguientes. Imagina, si así lo deseas, las propiedades de un automóvil: color, número de ruedas, potencia, número de asientos, etc. Al tener esta plantilla, podemos especializar aún más nuestros automóviles extendiendo esta clase: crear un auto de carreras que tenga una propiedad "nitro" o un camión que tenga una propiedad "trailer". La conclusión es: cree una clase más genérica que contenga la mayoría de los atributos comunes y tendrá mucho menos trabajo para definir otros objetos solo ligeramente diferentes. En lugar de reescribir todo el código, simplemente extiende sus propiedades, ahorrando mucho tiempo en el proceso.

Diagrama de herencia para nuestras clases de coches.

Encapsulacion

Como se explicó anteriormente, una de las principales ventajas de usar objetos es que no necesitamos revelar todos sus miembros (atributos o funciones); Sólo las interfaces necesarias para trabajar con él. Los detalles que no son útiles para el uso de estos objetos deben ocultarse del resto de los objetos. Esto es lo que se conoce como encapsulación.

Niveles de visibilidad

  • público: significa que un miembro de la clase es visible y utilizable / modificable por todos
  • privado: significa que un miembro de la clase solo es utilizable / modificable por la propia clase
  • protegido: significa que un miembro de la clase solo es utilizable / modificable por la propia clase y eventuales subclases

NOTA: De forma predeterminada, en PHP, un miembro de la clase es público a menos que se declare privado o protegido. Echa un vistazo a un ejemplo aquí.

Polimorfismo

El polimorfismo es una característica de la POO que le permite al programador asignar un significado o uso diferente a algo en diferentes contextos, específicamente, para permitir que un miembro de la clase realice diferentes tareas dependiendo del contexto en el que se usó. Imagina que tienes una clase de persona y dos subclases de persona: japonés y americano. Ambos implementan una función llamada talk (), pero con diferentes lenguajes y contextos sociales. Y mientras que ambos son básicamente personas (como se derivan de la clase Person), su implementación de la función talk () es muy diferente. Básicamente, tiene dos objetos de la clase Persona en los que la función talk () funciona de manera diferente.

Ensuciándonos las manos

Ok, ahora para la acción real. Crearemos una clase simple para manejar la manipulación de imágenes y la extracción de información. Durante la duración de este tutorial, asumiré que tiene una comprensión básica de PHP (variables, creación de funciones, trabajo con declaraciones de flujo de control y bucles). La lectura del manual de GD PHP eliminará cualquier duda que pueda tener sobre las funciones de manejo de imágenes.

Paso 1: Creando nuestra clase

Comenzamos por definir nuestra clase:

1
<?php
2
class Image {
3
}
4
?>

Esto solo le dice a PHP que comenzaremos a definir una nueva clase, llamada "Imagen". Ahora vamos a definir el constructor de la clase. Un constructor es simplemente la función que se llama cuando se crea un nuevo objeto. En PHP 5, esto se puede lograr mediante dos métodos diferentes: crear una función pública con el mismo nombre de la clase (PHP 4 y en adelante) o creando una función llamada "__construct ()" (solo PHP 5):

Paso 2: Creando el constructor de la clase.

Las siguientes dos piezas de código hacen exactamente lo mismo:

1
<?php
2
class Image {
3
  public function Image() {
4
		echo "We just created and object!";
5
	}
6
}
7
$image = new Image(); // prints "We just created and object!"

8
?>
1
<?php
2
class Image {
3
	function __construct() {
4
		echo "We just created and object!";
5
	}
6
}
7
$image = new Image(); // prints "We just created and object!"

8
?>

NOTA: Un constructor de clase es siempre público.

Los constructores de clases deben usarse para garantizar que el objeto creado tenga una cantidad mínima de datos con los que trabajar; En nuestro caso, la imagen deseada.

Como tal, lo primero que tenemos que hacer es leer la imagen, cualquiera que sea su tipo. Actualmente, la biblioteca GD admite varios tipos de imágenes, como jpg, png, gif, bmp y otros; Solo tenemos que leer la imagen y determinar su tipo.

1
<?php
2
class Image {
3
	function __construct($filename) {
4
		
5
		// read the image file to a binary buffer

6
		$fp = fopen($filename, 'rb') or die("Image '$filename' not found!");
7
		$buf = '';
8
		while(!feof($fp))
9
			$buf .= fgets($fp, 4096);
10
		
11
		// create image

12
		imagecreatefromstring($buf);
13
	}
14
}
15
$image = new Image("image.png"); // If everything went well we have now read the image

16
?>

Entonces, ¿qué hemos hecho? Para abrir la imagen tan fácilmente como sea posible, utilizaremos la función imagecreatefromstring de GD (que toma una cadena de datos binaria como entrada), en lugar de imagecreatefromjpeg, imagecreatefrompng o imagecreatefromgif, por ejemplo.

Entonces intentamos abrir un archivo de imagen y asignarle el puntero a $fp, y, en caso de fallo, terminar la ejecución del programa.

1
$fp = fopen($filename, 'rb') or die("Image '$filename' not found!");

A continuación, creamos una cadena vacía para mantener nuestros datos ...

1
$buf = '';

... y lea todo el archivo, concatenando los datos leídos con nuestros contenidos de cadenas recién creados.

1
while(!feof($fp))
2
	$buf .= fgets($fp, 4096);

Ahora solo tenemos que crear nuestra imagen usando los datos que acabamos de leer ...

1
imagecreatefromstring($buf);

... y crea un objeto para usar todas estas funciones.

1
$image = new Image("image.png");

NOTA: los archivos jpg, png, gif y la mayoría de las imágenes deben leerse en modo binario, por lo tanto, el "rb" se pasa como el segundo argumento de la función fopen. "r" significa solo lectura y "b" significa binario.

Paso 3: Definiendo atributos y métodos de clase

En su forma actual nuestra clase no es muy útil. Así que agregaremos algunos atributos y métodos para hacerlo más útil. Comenzaremos por 1: definiendo algunas variables internas (observe la declaración de visibilidad "privada" antes de cada variable)

1
<?php
2
class Image {
3
	
4
	// class atributes (variables)

5
	private $image;
6
	private $width;
7
	private $height;
8
	private $mimetype;
9
	
10
	function __construct($filename) {
11
		
12
		// read the image file to a binary buffer

13
		$fp = fopen($filename, 'rb') or die("Image '$filename' not found!");
14
		$buf = '';
15
		while(!feof($fp))
16
			$buf .= fgets($fp, 4096);
17
		
18
		// create image and assign it to our variable

19
		$this->image = imagecreatefromstring($buf);
20
		
21
		// extract image information

22
		$info = getimagesize($filename);
23
		$this->width = $info[0];
24
		$this->height = $info[1];
25
		$this->mimetype = $info['mime'];
26
	}
27
}
28
$image = new Image("image.png"); // If everything went well we have now read the image

29
?>

Y 2: un método para mostrar la imagen.

1
<?php
2
class Image {
3
4
	.
5
	.
6
	.
7
	
8
	public function display() {
9
		header("Content-type: {$this->mimetype}");
10
		switch($this->mimetype) {
11
			case 'image/jpeg': imagejpeg($this->image); break;
12
			case 'image/png': imagepng($this->image); break;
13
			case 'image/gif': imagegif($this->image); break;
14
		}
15
		//exit;

16
	}
17
}
18
$image = new Image($_GET['image']); // If everything went well we have now read the image

19
?>

En este paso, acabamos de crear algunos atributos de clase (imagen, ancho, altura y tipo MIME) para mantener los datos del objeto. Luego hicimos algunas modificaciones para asignar la imagen creada a nuestro atributo de clase $imagen ...

1
$this->image = imagecreatefromstring($buf)

... y extrajo la información de la imagen a nuestras variables de clase restantes (lea la documentación en getimagesize para comprender completamente cómo se lee la información de la imagen):

1
// extract image information

2
$info = getimagesize($filename);
3
$this->width = $info[0];
4
$this->height = $info[1];
5
$this->mimetype = $info['mime'];

A continuación, creamos una función que envía la imagen al navegador definiendo los encabezados apropiados (lea más sobre los encabezados http aquí) y use la función apropiada (con la instrucción de cambio) para generar la imagen según el tipo de imagen original (para este tutorial solo admitiremos jpg, png y gif pero, como dije antes, GD admite una multitud de otros formatos. Lea la documentación de php para más información.

Entonces, ¿qué es esto de "$this"? "$ this", en PHP, se refiere a la clase en sí, y se usa para señalar atributos o funciones de la clase. Como tal, $ this-> image apunta al atributo de clase denominado "$ image" y $ this-> image = ... cambia el valor del atributo de clase. Si escribiera $ image = ... simplemente estaría creando una nueva variable local llamada "$ image", disponible exclusivamente durante la duración de la función. Esta es una de las principales cosas a las que se debe prestar atención al crear clases en PHP.

Nuestro método de visualización no es muy útil (¡todavía!).

Paso 4: Definiendo nuestra subclase "Miniatura"

En este momento nuestra clase no es muy útil. Claro, podemos leer nuestra imagen y mostrarla, pero eso es todo. Ahora crearemos una subclase para crear nuestras miniaturas. (Realmente no necesitamos crear una subclase, pero lo haremos por el bien del tutorial, para demostrar la herencia y el polimorfismo). Por lo tanto, para que la herencia funcione correctamente necesitamos cambiar ligeramente la definición de nuestra superclase (Imagen). Solo necesitamos cambiar la visibilidad de nuestras variables de clase de "privado" a "protegido". Y ahora vamos a crear el constructor de nuestra subclase.

1
<?php
2
class Image {
3
	
4
	// class atributes (variables)

5
	protected $image;
6
	protected $width;
7
	protected $height;
8
	protected $mimetype;
9
	
10
	.
11
	.
12
	.
13
}
14
15
class Thumbnail extends Image {
16
	
17
	function __construct($image, $width, $height) {
18
		
19
		// call the super-class contructor

20
		parent::__construct($image);
21
		
22
		// modify the image to create a thumbnail

23
		$thumb = imagecreatetruecolor($width, $height);
24
		imagecopyresampled($thumb, $this->image, 0, 0, 0, 0, $width, $height, $this->width, $this->height);
25
		$this->image = $thumb;
26
	}
27
}
28
?>

Entonces, ¿qué estamos haciendo exactamente aquí? Creamos una nueva clase, derivada de nuestro original, lo que significa que podemos acceder a todos sus atributos y métodos públicos y protegidos. Llamamos al constructor de clase superior, responsable de leer la imagen y extraer su información. El constructor de subclase no llama a su constructor de superclase, por lo que necesitamos llamarlo explícitamente.

Ahora creamos una nueva imagen para nuestra miniatura, con el ancho y la altura aprobados:

1
$thumb = imagecreatetruecolor($width, $height);

Vuelva a muestrear (redimensionar) la imagen original en la nueva, para crear la miniatura:

1
imagecopyresampled($thumb, $this->image, 0, 0, 0, 0, $width, $height, $this->width, $this->height);

Y finalmente modifique la imagen original para que contenga la miniatura en lugar de la imagen a tamaño completo:

1
$this->image = $thumb;

¿Y adivina qué? Realmente no necesitamos escribir una nueva función para mostrar la miniatura porque se aplica el mismo principio, ya sea que esté mostrando una imagen de tamaño completo o una miniatura. ¡Después de todo, sigue siendo una imagen! ¡Así que solo necesitamos llamar a nuestra función de visualización (), definida en la súper clase, y hemos terminado!

Nuestra clase completa y subclases respectivas.

Y así concluye nuestro tutorial. Como ejercicio, le sugiero que implemente una función para guardar las miniaturas generadas en el disco en lugar de enviarlas al vuelo (¿Dónde debería implementar esa función? ¿En la súper o subclase?). Buena suerte y verifique el código postal proporcionado para un ejemplo de uso y las clases completas desarrolladas aquí (necesita tener un servidor con PHP para probarlo).

  • Suscríbase a la fuente RSS de NETTUTS para obtener más información y artículos de desarrollo web diarios.


Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.