viernes, 14 de noviembre de 2014

[Parte 1] Programacion orientada a objetos con PHP


Introducción 

En esta parte aprenderemos un poco de Programación orientada a objetos, aunque PHP no es tan poderoso en esta parte como otros lenguajes de programación, sabremos que metodología utilizar cuando estemos realizando un proyecto ya sea de procedimiento o programación orientada a objetos.

Teoria de la programación orientada a objetos

Lo primero que hay que entender sobre la programacion orientada a objetos es que no presenta una nueva sintaxis, sino una nueva forma de pensar al resolver un problema. El error mas comun de los programadores que están empezando con el uso de programación orientada a objetos es aplicar incorrectamente la teoría de la programación orientada a objetos. PHP le puede decir donde esta un error sintactico pero un error lógico no...

Toda la programacion se reduce a tomar acciones con los datos: un usuario introduce datos en un formulario HTML, el código PHP que valida; son enviados correos electrónicos; se almacena en una base de datos; y así sucesivamente. Estos son simplemente verbos (acciones) y sustantivos (datos). Con la programacion de procedimiento el foco esta en los verbos: hacer esto, entonces esto, luego esto... En la programacion orientada a objetos se centra en los sustantivos: ¿con que tipo de cosas trabajara la aplicacion? En ambos enfoques, lo que se necesita para identificar tanto los sustantivos y los verbos requeridos, la diferencia esta el foco. En el diseño de la aplicacion.

Las dos condiciones mas importantes para la programación orientada a objetos son la clase y objeto. Una clase es una definicion generalizada de una cosa. Piense en clases como los planos. Un objeto es una aplicación especifica de esa cosa. Piense en objetos como la casa construida usando el plano como guía. Para programar usando POO (programacion orientada a objetos), tu diseñas tus clases, y luego las pones en practica como objetos en tus programas cuando sea necesario.

Uno de los principios de la programación orientada a objetos es la modularidad: rompiendo las aplicaciones en subpartes especificas. Los sitios webs hacen muchas, muchas cosas: interactuar con las bases de datos, manejar formularios, enviar mensajes de correo electronico, generar HTML, etc. Cada una de estas cosas puede ser un modulo, es decir, una clase. Al separar elementos no relacionados (aunque interactuando), usted puede desarrollar código de forma independiente, realizar mantenimiento y actualizaciones menos sucias, y simplicar la depuracion.

En cuanto a la modularidad es la abstraccion: las clases deben ser definidas en terminos generales. Esto es un error de principiante comun y comprensible. A modo de ejemplo, en lugar de diseñar una clase para interactuar con la base de datos MySQL, debe hacer uno que interactua con una base de datos especifica. A partir de ahi, el uso de la herencia y el primer orden, que le defina una clase mas especial para MySQL. Esta clase podria lucir y actuar como una clase de base de datos general, pero algunas de sus funciones se irian modificando para requisitos particulares.

Otro principio de la programación orientada a objetos es la encapsulacion: separar y ocultar como se logra algo. Una clase diseñada adecuadamente puede hacer lo que tiene que hacer sin que tu sepas como lo esta haciendo. Acopladas con la encapsulacion es el control de acceso o visibilidad, que dicta como los componentes estan disponibles en la clase. 

Estos son los principales conceptos detrás de la programación orientada a objetos. 

En cuanto a los aspectos negativos a la POO. El uso de los objetos puede ser menos eficiente que un enfoque de procedimiento. La diferencia de rendimiento entre el uso de un objeto no puede ser imperceptible en algunos casos, pero usted debe ser consciente de este efecto secundario potencial. 

Una segunda cuestion que se plantea. El mal uso y excesivo de los objetos.

Definiendo una clase

La programacion orientada a objetos comienza con clases, una clase debe de ser una definicion abstracta de una cosa: ¿Que información debe de ser almacenada y que funcionalidad debe hacer posible con esa informacion? Una clase usuario deberia ser capaz de almacenar informacion como el nombre de usuario, Identifiacion, Correo electronico, y asi sucesivamente. La funcionalidad de un usuario podria ser iniciar sesion, cerrar sesion, cambiar contraseña, y mucho mas.

Sintacticamente, una definicion de clase comienza con la palabra Class. La palabra class es una palabra reservada. Despues de el nombre de la clase que es escrito comenzando con una mayuscula como convencion, la definicion de la clase se coloca dentro de unas llaves:

Class Nombredelaclase{  }
Las clases contienen variables y funciones, que son referidos como atributos (o propiedades y metodos), respectivamente. Colectivamente, las propiedades y métodos de la clase son sus miembros.

Las funciones son faciles de agregar a una clase:


Class Nombredelaclase {
        function nombredelafuncion(){
            // codigo
        }
    }
Los metodos que se definen dentro de una clase se definen igual que una funcion fuera de la clase. Ellos pueden tomar argumentos, tener valores por defecto, devolver valores, y asi sucesivamente. 

Las propiedades dentro de las clases son un poco diferente fuera de la clase. En primer lugar, todas las propiedades deben estar precedidas de una palabra clave que indica la visibilidad de la variable. Las opciones son public, private y protected. Por lo pronto estos valores no significaran nada para usted hasta que vea herencia, por lo cual usaremos para todo public.


Class Nombredelaclase {
        public $var1, $var2;
        function nombredelafuncion(){
            // codigo
        }
    }
Como se muestra aqui las propiedades de la clase se enumeran antes que cualquier definicion de metodo. La segunda distincion entre las propiedades y las variables normales es que si una propiedad se inicializa con un valor establecido, ese valor debe ser un valor literal y no un resultado de una expresion:


class ClaseBuena{
        public $var1 = 123;
        public $var2 = 'cadena';
        public $var3 = array(1,2,3);
    }

class ClaseMala{
        // esto no funciona
        public $hoy = getdate();
        public $cuadrado = $num * $num;
    }
Tenga en cuenta que usted no tiene que inicializar las propiedades con un valor. Y, aparte de la declaracion de las variables, todos los otros codigos de una clase va dentro de sus metodos. No se pueden ejecutar sentencias fuera de un metodo de una clase.

class ClaseMala{
        // esto no funciona
        public $num = 2;
        public $cuadrado;
        $square = $num * $num; // NO!
    }
Con todo esto en mente vamos a crear una clase, de forma facil y casi inutil para asegurarse de que hemos estado trabajando de manera correcta. La clase dira "Hola Mundo" en diferentes idiomas.

<?php
 class HolaMundo {
  function diHola($lenguaje = 'Espanol'){
   echo '<p>';
   switch ($lenguaje) {
    case 'Dutch':
     echo 'Hallo, Wereld!';
     break;
    case 'French':
     echo 'Bonjour, mode!';
     break;
    case 'German':
     echo 'Hallo, Welt!';
     break;
    case 'Italian':
     echo 'Ciao, mondo!';
     break;
    case 'Ingles':
     echo 'Hello, World!';
     break;
    case 'Espanol':
    default:
     echo 'Hola, Mundo!';
     break;
   }
echo '</p>'; 
 }
 }
?>


1.- Comenzamos definiendo la clase: class HolaMundo { usamos una sintaxis "uper case camel" donde cada palabra comienza con mayuscula

2.- Definimos el metodo: function diHola($lenguaje = 'Espanol'){ La clase actual no contiene propiedades (variables) estos deben ser declarados antes que los metodos. Este metodo se llama diHola() y usa "lower case camel" comenzando siempre con letra minuscula esto es usado como convencion.
3.- Agregamos un switch alternando en el lenguaje: 
switch ($lenguaje) {
                case 'Dutch':
                    echo 'Hallo, Wereld!';
                    break;
                case 'French':
                    echo 'Bonjour, mode!';
                    break;
                case 'German':
                    echo 'Hallo, Welt!';
                    break;
                case 'Italian':
                    echo 'Ciao, mondo!';
                    break;
                case 'Ingles':
                    echo 'Hello, World!';
                    break;
                case 'Espanol':
                default:
                    echo 'Hola, Mundo!';
                    break;
            }


El switch cambia dependiendo del lenguaje que eligamos, como lenguaje por defecto tenemos el Español.
Los metodos de la clase tambien pueden tener una visibilidad, precediendo la definicion de la funcion con la palabra clave adecuada. Si no se indica, todos los metodos todos los metodos tienen la palabra clave asumida:

public function Nombredelafuncion(){ }

La clase stdClass esta en uso internamente por PHP y no puede ser declarada en su propio codigo.

Creando un objeto

Usando POO es un proceso de dos pasos. Lo primero es la definicion de la clase, que acabas de hacer cuando escribiste la clase HolaMundo. El segundo paso es hacer uso de esa clase por la creación de un objeto (o una instancia de la clase).

Volviendo a la analogia de la clase usuario, una instancia de esta clase puede ser para el usuario con un nombre de usuario arthusu. El usuario podria tener propiedades para el mismo, ID 138, y una direccion de correo electronico arthusu@most-security.com, esta es una instancia de la clase usuario. Un segundo ejemplo, Zangetsu, tiene ese nombre de usuario, el ID 2, y un correo electronico Zangetsu@most-security.com. Estos son objetos separados de la misma clase, pero con diferente especificacion. 

La creacion de un objeto es muy facil en PHP ya despues de haber definido la clase. Para ello solo requerimos de la palabra clave new.

$objeto = new Nombredelaclase();

Ahora la variable $objeto existe y es de tipo Nombredelaclase (en lugar de tipo cadena o array). Mas tecnicamente ponemos, $objeto en una instancia Nombredelaclase.

Para llamar a los metodos de la clase, se utiliza esta sintaxis:

$objeto->nombreMetodo();

El -> puede ser llamado el operador del objeto. Si un metodo tiene argumentos, usted puede proporcionarselos dentro del parentesis, como cualquier otra llamada a una funcion:

$objeto->nombreMetodo('valor',32,true);

Para acceder a las propiedades de un objeto utilizamos:

$objeto->nombrePropiedad;

Tenga en cuenta que al llamar a la propiedad no utilizamos el signo dolar $ como prefijo, lo cual nos causaria errores de analisis:

$objeto->$nombrePropiedad; // Error!

(Como se vera mas adelante, la capacidad de hacer referencia a un metodo o alguna propiedad de un objeto, depende de la visibilidad del mismo). Una vez que haya terminado con el objeto puede eliminarlo, como se hace con cualquier otra variable:

unset($objeto);


<!DOCTYPE html>
<html lang="es">
<head>
 <meta charset="utf-8" />
 <title>Hola, Mundo!</title>
</head>
<body>
<?php
 // Incluimos la definicion de la clase:
 require('HolaMundo.php');

 // Creamos el objeto:
 $obj = new HolaMundo();
 // Llamamos al metodo diHola():
 $obj->diHola();

 // Decimos Hola en diferents lenguajes:
 $obj->diHola('Dutch');
 $obj->diHola('French');
 $obj->diHola('Italian');

 // Eliminamos el objeto:
 unset($obj);
?>
</body>
</html>

1.- Incluimos la definicion de la clase: require('HolaMundo.php');
Con el fin de acceder a la clase, utilizamos require en lugar de include ya que asi se pararia el script en caso de que la clase no se haya incluido.
2.- Creamos un nuevo objeto: $obj = new HolaMundo();
Esta linea de codigo se explica por si misma, la variable $obj puede ser el nombre que usted desee $holaMundo, $prueba, etc.
3.- Invocamos al metodo diHola(): $obj->diHola(); 
Esta linea del codigo llama a el metodo diHola() y como no tiene ningun argumento arroja el lenguaje por defecto que es Español.
4.- Llamamos el metodo diHola() y le damos varios lenguajes como argumento:
$obj->diHola('Dutch');
$obj->diHola('French');
$obj->diHola('Italian');
6.- Borramos el objeto completamente: unset($obj);
Tecnicamente no tiene que borrar el objeto ya que se borra en cuanto el script termina, pero es una buena practica de programacion poner esto en orden.

Los nombres de las clases no distinguen entre mayusculas y minusculas. Sin embargo los nombres del objeto, al igual que cualquier variable de PHP, distinguen entre mayusculas y minusculas.


El atributo $this

La clase HolaMundo en realidad hace algo, lo cual es bueno, pero es un ejemplo bastante minimo. La clase incluye un metodo, pero no contiene ninguna propiedad (variables). 

Las propiedades:

* Son variables
* Deben ser declaradas como public, private o protected 
* Si se inicializan se debe de dar un valor estatico (no el resultado de una expresion)

Esas son las reglas para la definicion de propiedades en una clase, pero utilizando esas propiedades requiere una pieza mas de informacion. Como ya se ha explicado, a traves del objeto, se puede acceder a las propiedades del objeto con el operador de notacion (->).

$objeto->nombrePropiedad;

La cuestion es que dentro de la propia clase (es decir, dentro de los metodos de una clase), debe utilizar una sintaxis alternativa para acceder a las propiedades de la clase. No se puede hacer esto:

class ClaseMala{
        public $var;
        function hacer(){
            // Esto no trabaja:
            print $var;
        }
    }


El metodo hacer() no puede acceder a $var de esa manera. La solucion es una variable especial llamada $this. La variable $this en una clase siempre se refiere a la instancia actual (es decir, al objeto involucrado). Dentro de un metodo se puede hacer referencia a la instancia de una clase y sus propiedades utilizando la sintaxis $this->nombrePropiedad. En lugar de sobre explicar este concepto. Vamos hacer una practica. El siguiente ejemplo definira una clase que representa un rectangulo.

<?php
 /* 
  Esta pagina define la clase rectangulo
  La clase contiene dos atributos ancho y alto.
  Esta clase contiene 4 metodos:
  - establecerTamano()
  - obtenerArea()
  - obtenerPerimetro()
  - esCuadrado()
 */

 class Rectangulo{
  // declaramos las propiedades:
  public $ancho = 0;
  public $alto = 0;

  // Metodo para establecer las dimensiones:
  function establecerTamano($w = 0, $h= 0){
   $this->ancho = $w;
   $this->alto = $h;
  }

  // Metodo para calcular y devolver el area.
  function obtenerArea(){
   return ($this->ancho * $this->alto);
  }

  // Metodo para calcular y devolver el perimetro.
  function obtenerPerimetro(){
   return (($this->ancho + $this->alto) * 2 );
  }

  // Metodo para determinar el area del rectangulo:
  function esCuadrado(){
   if($this->ancho == $this->alto){
    return true; // Es cuadrado
   }
  }
 }
?>

1.- Definimos la clase rectangulo: class Rectangulo{ 
2.- Declaramos las propiedades:
public $ancho = 0;
public $alto = 0;
La clase tiene dos propiedades para el rectangulo alto y ancho, ambas se inicializan en 0.
3.- Creamos un metodo para establecer las dimensiones del rectangulo:
function establecerTamano($w = 0, $h= 0){
            $this->ancho = $w;
            $this->alto = $h;
        }

Toma dos valores el alto y el ancho y se inicializan en cero para posibles inconveniencias, establecemos las propiedades los argumentos que le demos al metodo.
4.- Creamos un metodo que calcule y retorne el area del rectangulo:
function obtenerArea(){
            return ($this->ancho * $this->alto);
        }

Este metodo no necesita tomar ningun argumento, ya que accede directamente a las propiedades ancho y alto utilizando $this para referirse, y hace una multiplicacion.
5.- Creamos un metodo para devolver y calcular el perimetro: 
function obtenerPerimetro(){
            return (($this->ancho + $this->alto) * 2 );
        }

Este metodo es como obtenerArea(), a excepcion de que utiliza una formula diferente.
6.- Creamos un metodo que indique si el rectangulo tambien es cuadrado:
function esCuadrado(){
            if($this->ancho == $this->alto){
                return true; // Es cuadrado
            }
        }

Este metodo compara si el ancho es igual al alto, y si son los mismos devuelve true en otro caso false.


Vamos a usar la clase Rectangulo:

<!DOCTYPE html>
<html lang="es">
<head>
 <meta charset="utf-8">
 <title>Rectangulo</title>
</head>
<body>
<?php
 /*
 Esta pagina usa la clase rectangulo
 Esta pagina muestra un grupo de informacion acerca del rectangulo.
 */

 // incluimos la definicion de la clase:
 require('Rectangulo.php');

 // Definimos las variables necesarias:
 $ancho = 42;
 $alto = 7;

 // Imprimimos un poco de introduccion:
 echo "<h2>Con el ancho de $ancho y el alto de $alto ...</h2>";

 // Creamos un nuevo objeto:
 $r = new Rectangulo();

 // Asignamos dimensiones al rectangulo:
 $r->establecerTamano($ancho,$alto);

 // Imprimimos el area:
 echo '<p>El area del rectangulo es:'. $r->obtenerArea() .'</p>';

 // Imprimimos el perimetro:
 echo '<p>El perimetro del rectangulo es:'. $r->obtenerPerimetro() .'</p>';

 // ¿Es esto un cuadrado?
 echo '<p>Este rectangulo: ';
 if ($r->esCuadrado()) {
  echo "tambien";
 }else{
  echo "no";
 }
 echo ' es cuadrado</p>';

 // Eliminamos el objeto:
 unset($r);
?>
</body>
</html>
1.- Incluimos la definicion de la clase: require('Rectangulo.php'); 
2.- Definimos las variables necesarias y imprimimos una introduccion:
$ancho = 42;
    $alto = 7;

    // Imprimimos un poco de introduccion:
    echo "<h2>Con el ancho de $ancho y el alto de $alto ...</h2>";


3.- Creamos un objeto y asignamos las dimensiones del rectangulo:
$r = new Rectangulo();

    // Asignamos dimensiones al rectangulo:
    $r->establecerTamano($ancho,$alto);

4.- Imprimimos el area del rectangulo:
echo '<p>El area del rectangulo es:'. $r->obtenerArea() .'</p>';
5.- Imprimimos el perimetro del rectangulo:
echo '<p>El perimetro del rectangulo es:'. $r->obtenerPerimetro() .'</p>';
6.- Indicamos si el rectangulo tambien es cuadrado:
echo '<p>Este rectangulo: ';
    if ($r->esCuadrado()) {
        echo "tambien";
    }else{
        echo "no";
    }
    echo ' es cuadrado</p>';

7.- Eliminamos el objeto:
unset($r);

Tener métodos de obtener y establecer en una clase es muy común. Los métodos que comienzan con establecer son para asignar valores para las propiedades de la clase. Los métodos que comienzan con obtener son usados para devolver valores: o bien las propiedades o los resultados de los calculos.

Los metodos pueden llamarse unos a otros, tal como seria en cualquier otra funcion, pero usted tendra que usar $this de nuevo. Lo siguiente es innecesario pero valido:

function obtenerArea(){
        if($this->esCuadrado()){
            return ($this->ancho * $this->alto);
        }else{
            return ($this->ancho * $this->alto);
        }
    }



Creacion de constructores

Un constructor es un tipo especial de metodo que difiere de los estandar de tres maneras:

* Su nombre es siempre __construct
* Es de forma automatica e inmediatamente llamado cada vez que un objeto de esa clase se crea.
* No puede tener una sentencia return.

La sintaxis para definir un constructor  es por lo tanto:

class NombreClase{
        public $var;
        function __construct(){
            // Codigo de la funcion
        }
    }


Un constructor podria ser utilizado para conectarse a una base de datos, establecer cookies, o establecer valores iniciales. Basicamente vamos a usar los constructores, para hacer cualquier cosa que siempre deba y hacer primero, cuando se haga un objeto de esta clase.

Debido a que el constructor es todavia mas que otro metodo, puede tomar argumentos y valores, para que se le puedan proporcionar valores cuando el objeto es creado.

class Usuario{
        function __construct($id){
            // codigo de la funcion
        }
    }
    $me = new Usuario(2345);


La clase Rectangulo podria beneficiarse de tener un constructor que asigne las dimensiones cuando el Rectangulo se crea.

<?php
 /* 
  Esta pagina define la clase rectangulo
  La clase contiene dos atributos ancho y alto.
  Esta clase contiene 4 metodos:
  - establecerTamano()
  - obtenerArea()
  - obtenerPerimetro()
  - esCuadrado()
 */

 class Rectangulo{
  // declaramos las propiedades:
  public $ancho = 0;
  public $alto = 0;

  function __construct($w = 0, $h = 0){
   $this->ancho = $w;
   $this->alto = $h;
  }

  // Metodo para calcular y devolver el area.
  function obtenerArea(){
   return ($this->ancho * $this->alto);
  }

  // Metodo para calcular y devolver el perimetro.
  function obtenerPerimetro(){
   return (($this->ancho + $this->alto) * 2 );
  }

  // Metodo para determinar el area del rectangulo:
  function esCuadrado(){
   if($this->ancho == $this->alto){
    return true; // Es cuadrado
   }
  }
 }
?>

Como vez hemos agregado la funcion __construct y hemos eliminado la funcion establecerTamano() ya que practicamente hacen lo mismo, solo que es mejor con __construct ya que si no llamasemos a al metodo establecerTamano() habria un error en los demas metodos, pero como estamos utilizando __construct() se inicia siempre aunque no le demos valores, con los valores por defecto de 0.

Al llamarlo lo hacemos de la siguiente forma:

<!DOCTYPE html>
<html lang="es">
<head>
 <meta charset="utf-8">
 <title>Rectangulo</title>
</head>
<body>
<?php
 /*
 Esta pagina usa la clase rectangulo
 Esta pagina muestra un grupo de informacion acerca del rectangulo.
 */

 // incluimos la definicion de la clase:
 require('Rectangulo.php');

 // Definimos las variables necesarias:
 $ancho = 142;
 $alto = 7;

 // Imprimimos un poco de introduccion:
 echo "<h2>Con el ancho de $ancho y el alto de $alto ...</h2>";

 // Creamos un nuevo objeto:
 $r = new Rectangulo($ancho,$alto);

 // Imprimimos el area:
 echo '<p>El area del rectangulo es:'. $r->obtenerArea() .'</p>';

 // Imprimimos el perimetro:
 echo '<p>El perimetro del rectangulo es:'. $r->obtenerPerimetro() .'</p>';

 // ¿Es esto un cuadrado?
 echo '<p>Este rectangulo: ';
 if ($r->esCuadrado()) {
  echo "tambien";
 }else{
  echo "no";
 }
 echo ' es cuadrado</p>';

 // Eliminamos el objeto:
 unset($r);
?>
</body>
</html>

Un constructor como el que se acaba de agregar a la clase Rectangulo, se llama un constructor por defecto, ya que proporciona valores predeterminados para sus argumentos. Esto significa que un objeto Rectangulo puede ser creado utilizando cualquiera de estas dos formas:

$r = new Rectangulo($ancho,$alto);
$r = new Rectangulo();

Usted puede llamar directamente a un constructor (aunque raramente se necesita):

$o = new AlgunaClase();
$o->__construct();

Con el ejemplo de Rectangulo, esto dejaria deshacerse del metodo establecerTamano() sin perder la capacidad de cambiar el tamaño del Rectangulo.

En PHP 4 como en otros lenguajes de programacion (como c++), un constructor se declara mediante la creacion de un metodo con el mismo nombre de la clase.






Creando destructores

El corolario de un constructor es un destructor. Mientras que un constructor es invocado automaticamente cuando el objeto es creado, el destructor es llamado cuando el objeto se destruye. Esto puede ocurrir cuando se quita abiertamente el objeto:


    $obj = new NombreClase();
    unset($obj); // llama tambien al destructor


O esto puede ocurrir cuando termina un script (en el punto en que PHP libera memoria utilizada por las variables). El destructor se crea de este modo:

class NombreClase{
        // Propiedades y metodos
        function __destruct(){
            // codigo de la funcion
        }
    }


Los destructores no se diferencian de los constructores y otros metodos en que no pueden tomar argumentos.

Vamos a ver un ejemplo de cuando los constructores y destructores son llamados:

<!DOCTYPE html>
<html lang="es">
<head>
 <meta charset="utf-8">
 <title>Constructores y Destructores</title>
</head>
<body>
<?php
 /*
 Esta pagina define una clase demo y una funcion demo()
 Ambas seran usadas para mostrar cuando los constructores y destructores son
 llamados.
 */

 // Definimos la clase:

 class Demo{
  // Sin propiedades

  // Constructor:
  function __construct(){
   echo '<p>En el constructor</p>';
  }

  // Destructor:
  function __destruct(){
   echo '<p>En el destructor</p>';
  }
 } // Fin de la clase Demo

 // Definimos una funcion prueba():
 function prueba(){
  echo '<p>En la funcion. Creamos un nuevo objeto...</p>';
  $f = new Demo();
  echo '<p>A punto de salir de la funcion.</p>';
 }

 // Creamos un objeto:
 $o = new Demo();

 // Llamos a la funcion prueba():
 echo '<p>Llamando a la funcion...</p>';
 prueba();

 // Eliminamos el objeto:
 echo '<p>A punto de eliminar el objeto...</p>';
 unset($o);

 echo '<p>Terminamos el script</p>';

?>
</body>
</html>

Autocarga de clases

Cuando se define una clase en un script que hace referencia a otro script, usted tiene que asegurarse de que el segundo script incluye el primero, o habra errores. 
Con este fin PHP 5 es compatible con la funcion especial llamada __autoload (tenga en cuenta que las funciones en PHP que comienzan con dos _ guiones bajos son especiales). La funcion __autoload() se invoca cuando el codigo intenta crear una instancia de un objeto de una clase que aun no se ha definido. El objetivo de la funcion __autoload() es incluir el archivo correspondiente. En forma mas simple esto podria ser:

function __autoload($class){
        require($class . '.php');
    }

Para cada nuevo tipo de objeto creado en el siguiente codigo, la funcion sera invocada:

    $obj = new Clase();
    $yo = new Humano();
    $r = new Rectangulo();

Gracias a la funcion __autoload() esas tres lineas incluiran automaticamente: Clase.php, Humano.php y Rectangulo.php (dentro del directorio actual). Tenga en cuenta que esta funcion __autoload() se define fuera de cualquier clase; en su lugar, es colocado al crear una nueva instancia para un objeto. 

El diseño de clases con UML

Esto es una introduccion al Lenguaje Unificado de Modelado (UML) una forma de representar graficamente sus diseños POO. 

Una clase en su nucleo tiene tres componentes:

* El nombre
* Las propiedades
* Los metodos

UML representa una clase graficamente mediante la creacion de un diagrama de clases: una caja de tres partes para cada clase, con el nombre de la clase en la parte superior. La siguiente seccion de la caja identificara las propiedades de la clase, y el tercero seria enumerar los metodos. 

Nombre de la clase
Propiedad
Propiedad
Metodo()
Metodo()

Para las propiedades, el tipo de propiedad (por ejemplo: cadena, matriz, etc.) aparece despues del nombre de la propiedad, como en:
UsuarioId:number
Usuario:string

Si la propiedad tiene un valor predeterminado, podria reflejar eso tambien:
ancho:number = 0

Para definir un metodo en un diagrama de clase, seria comenzar con el nombre de metodo, colocando sus argumentos y tipos dentro del parentesis. Esto es normalmente seguido por el tipo del valor que el metodo devuelve:
diHola(langueje:string):void 

El metodo diHola() no devuelve nada, por lo que su tipo de retorno es nulo.

Beneficios de un diseño de clase

Al hacer un diseño formal de clases UML puede parecer a primera vista mas que hacer un ejercicio mas que cualquier otra cosa, pero hay un monton de beneficios para crear uno. En primer lugar si usted esboza el diseño antes de hacer el codigo, puede mejorar las posibilidades de que el codigo sea correcto desde el inicio. En otras palabras, si pone esfuerzo en su diseño visual, y reflexiona sobre si el diseño refleja plenamente el numero de veces que tendra que actualizar sus definiciones de clase en el camino. 
En segundo lugar, un principio de programacion orientada a objetos es la encapsulacion: separar y ocultar como se logra algo. Un UML, con su lista de propiedades, metodos y argumentos, puede actuar como una guia de usuario para esas clases. 
Cualquier codigo que requiere clases que han sido modeladas debe ser capaz de utilizar las clases, sus metodos y propiedades, sin tener que mirar el codigo subyacente. De hecho, se puede distribuir el UML, junto con el codigo como servicio a los clientes.

Con esto en mente usted puede completar el diagrama de clases para la clase HolaMundo


HolaMundo
diHola(lenguaje: string):void

 Para la clase Rectangulo:



Rectangulo
Ancho:number = 0
alto:number = 0
__construct(ancho:number = 0, alto:number = 0):void
obtenerTamano(ancho:number = 0, alto:number = 0):void
obtenerArea():number
obtenerPerimetro():number
esCuadrado():Boolean

Asegurese de actualizar el diseño de su clase en caso de mas adelante cambiar su definicion de clase.

Mejorando la documentacion con phpDocumentor

Junto con la creacion de un diseño de clases UML, otro tema es la creacion de una mejor documentacion utilizando phpDocumentor (http://www.phpdoc.org/). Un codigo correctamente documentado genera menos errores, esto nos causa menos inconvenientes con los clientes que lo van a usar, con los compañeros de trabajo, hasta con los que te ayudaran a mejorar el codigo, y para ti mismo.

Aunque se puede documentar su codigo utilizando comentarios simples, hay dos beneficios obvios para la adoptacion de un enfoque formal phpDocumentor:

* Transmite mucho mejores practicas y estilos recomendados
* phpDocumentor generará documentacion, en HTML y otros formatos para usted. El HTML generado tambien puede ser un recurso valioso para cualquier persona que utilice su codigo, en especial sus clases.

phpDocumentor crea documentacion para la lectura del codigo PHP y sus comentarios. Para facilitar ese proceso deberia empezar a escribir sus comentarios en una forma que phpDocumentor lo comprenda. Para empezar usted debe utilizar la sintaxis del docblock de la documentacion:

    /*
    *
    * Descripcion corta
    *
    *
    * Descripcion larga
    */



La descripcion corta debe ser una sola descripcion de linea. La descripcion larga puede ir atraves de multiples lineas e incluso utilizar algunas HTML. Ambas son opcionales.

Cada etiqueta precedida por @ y phpDocumentor soporta varios tipos, depende de lo que utilice sera lo que esta documentando. 

Un bloque de documentacion se puede colocar antes de cualquiera que de lo siguiente:

* Definicion de una clase
* Definicion de una funcion o metodo
* Declaracion de variables
* Definicion de constantes
* Inclusion de archivos

Un docblock debe ser escrito en la parte superior del script, con el fin de documentar todo el archivo.
Editamos el archivo HolaMundo documentandolo de la siguiente manera:

<?php
 /**
 * Esta pagina define la clase HolaMundo
 *
 *
 * La clase Holamundo dice "Hola, Mundo" en diferentes lenguajes
 *
 *
 * La clase HolaMundo es mas para
 * propositos de demostracion
 * No es buena realmente para utilizar en POO.
 */

 class HolaMundo {
  /**
  * La funcion dice "Hola, Mundo!" en diferentes lenguajes
  * @param string $lenguaje Por defecto es "Ingles"
  * @returns void
  */
  function diHola($lenguaje = 'Espanol'){
   echo '<p>';
   switch ($lenguaje) {
    case 'Dutch':
     echo 'Hallo, Wereld!';
     break;
    case 'French':
     echo 'Bonjour, mode!';
     break;
    case 'German':
     echo 'Hallo, Welt!';
     break;
    case 'Italian':
     echo 'Ciao, mondo!';
     break;
    case 'Ingles':
     echo 'Hello, World!';
     break;
    case 'Espanol':
    default:
     echo 'Hola, Mundo!';
     break;
   }
   echo '</p>';
  }
 }
?>

Instalamos phpDocumentor utilizando el canal de PEAR:

pear channel-discover pear.phpdoc.org
pear install phpdoc/phpDocumentor
 
 
Si no sabes como instalar PEAR desde la terminal usamos:

sudo apt-get install php-pear

Nos movemos al directorio donde se encuentra el archivo de clase HolaMundo:

cd /var/www

En mi caso esa era la ruta.
Documentamos un solo archivo utilizando:

phpdoc -f HolaMundo.php -t docs/

Esto nos generara la documentacion en el directorio docs/ del archivo HolaMundo.
Al terminar abrimos docs/ y el archivo index.html donde vendra la documentacion del archivo:




Yo no estoy utilizando la version mas nueva, pero para saber como se ve en realidad pueden ver la demo de la web oficial: http://demo.phpdoc.org/Clean/

Hasta aqui terminamos esta parte, nos vemos en la proxima.

Creado para Most-Security.com, Son libres de distribuir utilizando siempre la pagina donde se ha creado.
 

No hay comentarios:

Publicar un comentario en la entrada