jueves, 30 de octubre de 2014

Archivo de conexión a la base de datos de magento

Llevo unos días investigando Magento, de hecho me siento como un explorador de siglos pasados intentando descubrir donde esta la Fuente de la Juventud, pero sin éxito alguno.
La cuestión es que me han solicitado que haga un plugin con una funcionalidad muy especifica y con cierto grado de complejidad en el algoritmo, cosa que esta solventada, el problema proviene cuando tenemos que conectar con la base de datos, la cual no es relacional si no EAV (ya os hablare de eso en otra entrada), por lo que hacer consultas es practicamente imposible si no eres un especialista en Magento.

Aun así y tras muchos intentos y búsquedas, aunque no haya dado con la Fuente, si es cierto que he encontrado otras cosas, como por ejemplo el archivo donde esta la información para la conexión a la base de datos, cuya dirección es:
/magento/app/etc/local.xml

En este archivo podemos encontrar un pequeño código, no os asusteis no es muy grande donde una de sus fracciones, que se puede ver a golpe de vista es la siguiente:
<connection>
 <host><![CDATA[nombreHost]]></host>
 <username><![CDATA[nombreUsuario]]></username>
 <password><![CDATA[password]]></password>
 <dbname><![CDATA[nombreDB]]></dbname>
 <active>1</active>
<connection>

Se puede observar los datos que hay y donde están, por lo que es relativamente sencillo obtenerlos para poder acceder a nuestra base de datos desde un plugins php que utilicemos.
Los datos son por orden:
  • nombre del host
  • nombre de usuario
  • password
  • nombre de la base de datos
  • si esta o no esta activa
Además si cambian los valores de nuestra base de datos podemos hacerlo desde aquí.

miércoles, 29 de octubre de 2014

PHP (09) BBDD (01) Bases de datos

En este primer articulo sobre las bases de datos, vamos a dar algunas definiciones e ideas de que es y como funcionan las bases de datos en PHP.
Los siguientes estarán enfocados a MySQL, una de las bases de datos más extendidas, pero si se conoce como funciona la conexión y su trabajo, se descubrirá que las demás BBDD funcionan de forma similar.

Se podría definir una base de datos, de forma muy burda, pero que de momento nos vale como: Una colección de tablas donde se encuentran los datos.
De forma más acertada podríamos utilizar decir que:

Unas base de datos es un almacén (físico/virtual) donde se albergan los datos de forma ordenada, representando los aspectos del mundo real que le interesen al diseñador, ya que las bases de datos se crean con un propósito especifico.
            Los datos pueden ser desde los libros de una biblioteca a números de teléfono, direcciones, expedientes académicos, historiales clínicos...
Un ejemplo muy sencillo de esto podría ser una agenda con nombres y teléfonos, lo cual nos daría dos campos (nombre y teléfono).

Aunque aquí no hablaremos del lenguaje SQL estrictamente, si es necesario que demos un pequeño repaso, para que aquello profanos que nos siguen puedan dejar su situación y continuar con el tutorial de forma satisfactoria.

SQL (Structured Query Lenguage) ó (Lenguaje de consulta estructurado) es el lenguaje que se utiliza para acceder a las bases de datos. PHP puede introducirlo en su código y de este modo se hace lo que se podría considerar el sumun de la programación en PHP.

Para comenzar este repaso rápido por SQL supongamos que tenemos una tabla llamada agenda con los siguientes campos:
Nombre         Teléfono
Miguel         123456789
Antonio        987654321
María          386943724

Para poder observar los datos de la tabla, es necesario realizar una consulta SQL, que es una instrucción. Por ejemplo, si quisiéramos mostrar todos los datos de nuestra tabla, deberíamos de escribir:
SELECT * FROM agenda

Esta consulta nos mostraría todos los valores de la tabla.
Pero PHP necesita algo más que la consulta, ya que para interactuar con MySQL, necesita la función mysql_query() de una forma similar a esta: (no te preocupes si no lo entiendes, es solo un ejemplo y haremos muchos ejercicios en los próximos articulos.)
$query = "SELECT * FROM agenda";
$result = mysql_query($query) or die("Falló la consulta: " . mysql_error());

Todo esto que puede parecer muy grande, en realidad es muy sencillo, e incluso divertido, ya que es donde radica la mayor parte de la potencia de PHP yse pueden hacer cosas realmente espectaculares, de hecho la inmensa mayoría de los CMS actuales funcionan por este proceso.

MySQL

Para instalar MySQL en tu ordenador, es muy sencillo, tan solo tienes que tener instalado el XAMP o un programa similar según tus gustos y sistema operativo, o bien puedes hacerlo a mano en linux, aunque yo no lo recomiendo
Una vez que lo tenemos instalado es fácil acceder a él y crear una pequeña base de datos para comenzar a trabajar con PHP, de hecho hay multitud de información en la red sobre como hacerlo y espero poder hacer un vídeo en los próximos días para que veáis como se hace paso a paso, y utilizar un script de PHP para empezar a hacer consultas.

martes, 28 de octubre de 2014

PHP (07) POO (09) Métodos estáticos (04) Miembros estáticos y herencias

Para terminar con los métodos estáticos, vamos a ver de forma sencilla como funcionan las herencias entre ellos, siendo algo muy sencillo.
Para empezar vamos a declarar dentro de nuestra clase Mensaje una propiedad que se llame $adios, y que sea estática:
<?php
 class Mensaje
 {
  static $adios = 'Espero verle pronto';
  public static function saludo()
  {
   echo '<h3>Saludos desde Netrunning</h3>';
  }

  public static function personal($nombre)
  {
   echo '<h3>Hola ' . $nombre . ' Bienvenido!!!!';
  }
 }

 Mensaje::saludo();
 Mensaje::personal('Pepe');

?>

Y ahora declaramos una clase Despedida que herede de Mensaje, y en ella un método que estático que acceda a nuestra propiedad, y finalmente llamamos a este método:
<?php
 class Mensaje
 {
  static $adios = 'Espero verle pronto';
  public static function saludo()
  {
   echo '<h3>Saludos desde Netrunning</h3>';
  }

  public static function personal($nombre)
  {
   echo '<h3>Hola ' . $nombre . ' Bienvenido!!!!</h3>';
  }
 }

 class Despedida extends Mensaje
 {
  public static function mostrar_despedida()
  {
   echo '<p>' . Mensaje::$adios . '</p>';
  }
 }

 Mensaje::saludo();
 Mensaje::personal('Pepe');
 Despedida::mostrar_despedida();

?>

Con tan solo observarlos y conociendo ya como funcionan las herencias se puede intuir el resultado:

Saludos desde Netrunning

Hola Pepe Bienvenido!!!!

Espero verle pronto


PHP (07) POO (09) Métodos estáticos (03) Propiedades en métodos estáticos

Se pueden emplear propiedades trabajando con la clase en código y no con un objeto, siempre que estas propiedades sean estáticas.
Para ello lo único que hay que hacer es declarar la propiedad como estática, y un método set publico y estático.
<?php
 class Matematica
 {
  static $dato;

  public static function set_dato($valor)
  {
  ... 
  }
 }

?>

De este modo se pueden almacenar datos en $dato, pero no podemos utilizar $this-> ya que no tenemos un objeto de la clase, pero eso PHP lo solventa con la palabra reservada self, que se utiliza para trabajar con métodos y propiedades estáticos.
Su uso quedaría así:
<?php
 class Matematica
 {
  static $dato;

  public static function set_dato($valor)
  {
   self::$dato = $valor;
  }
 }

?>

De esta forma ya tenemos nuestro dato guardado, y para usarlo se hace utilizando la expresión self::$dato como vemos a continuación:
<?php
 class Matematica
 {
  static $dato;

  public static function set_dato($valor)
  {
   self::$dato = $valor;
   echo '<p>mostrando self::$dato = ' . self::$dato . '<p>';
  }
 }

 Matematica::set_dato(6);

?>

Lo cual nos da como resultado:
mostrando self::$dato = 6

Pero puede resultar tedioso estar todo el tiempo utilizando la secuencia del self, de modo que se puede guardar como si de una variable se tratase, y trabajar con ella de la forma habitual:
<?php
 class Matematica
 {
  static $dato;

  public static function set_dato($valor)
  {
   self::$dato = $valor;
   echo '<p>mostrando self::$dato = ' . self::$dato . '<p>';
   $numero = self::$dato;
   echo '<p><b>Ahora $numero es self::$dato = </b>' . $numero . '</p>';
   $cuadrado = $numero * $numero;
   echo '<p>' . $numero . '<sup>2</sup> = ' . $cuadrado . '</p>';
  }
 }

 Matematica::set_dato(6);

?>

En este caso hemos guardado el valor dentro de de una variable llamada $cuadrado, con la cual hemos hecho un cálculo y nos da como resultado:
mostrando self::$dato = 6
Ahora $numero es self::$dato = 6
62 = 36

lunes, 27 de octubre de 2014

PHP (07) POO (09) Métodos estáticos (02) Paso de datos a un método estático

Sin lugar a dudas, el lector de esta serie de artículos, donde hemos hablado de funciones, clases, metodos... intuirá de forma inmediata como se pasa un dato a un método estático, pero para aquellos que deseen confirmar sus sospechas o que no hayan seguido todo el "manual", lo veremos paso a paso.
Lo primero que haremos sobre nuestro script es crear un nuevo método estático, donde se necesite un argumento:
<?php
 class Mensaje
 {
  public static function saludo()
  {
   echo '<h3>Saludos desde Netrunning</h3>';
  }

  public static function personal($nombre)
  {
   echo '<h3>Hola ' . $nombre . ' Bienvenido!!!!';
  }
 }

 Mensaje::saludo();

?>

Una vez que tenemos el método preparado, tan solo hay que llamarlo como un método estático y publico con su argumento, de este modo:
<?php
 class Mensaje
 {
  public static function saludo()
  {
   echo '<h3>Saludos desde Netrunning</h3>';
  }

  public static function personal($nombre)
  {
   echo '<h3>Hola ' . $nombre . ' Bienvenido!!!!';
  }
 }

 Mensaje::saludo();
 Mensaje::personal('Pepe');

?>


De este modo llamamos al método y le enviamos el dato que necesita, ejecutandose normalmente y dándonos como resultado:

Saludos desde Netrunning

Hola Pepe Bienvenido!!!!

PHP (07) POO (09) Métodos estáticos (01) Creación

Cuando creamos un método estático, lo que estamos haciendo es que podamos acceder a él directamente sin necesidad de crear un objeto de la clase, es decir hacerlo llamando a la clase y el método.
Por ejemplo se puede crear una clase llamada Mensajes, en la cual vamos a incluir un método estático con un mensaje para que aparezca por pantalla:
<?php
 class Mensaje
 {
  public static function saludo()
  {
   echo '<h3>Saludos desde Netrunning</h3>';
  }
 }

?>

Hemos creado método saludo() publica, para que todo el código tenga acceso a él, y estático para que se pueda acceder sin necesidad de utilizar un objeto de la clase.
Pero para acceder al método no podemos utilizar el operador -> ya que no tenemos un objeto de la clase, en su lugar utilizaremos los dobles dos puntos :: ya conocidos por nosotros, y que reciben el nombre de Paamayim Nekudotayim que viene a significar dos puntos dobles en hebreo.

De este modo nuestro pequeño script quedaría así:
<?php
 class Mensaje
 {
  public static function saludo()
  {
   echo '<h3>Saludos desde Netrunning</h3>';
  }
 }

 Mensaje::saludo();

?>

Y el resultado sería:

Saludos desde Netrunning

domingo, 26 de octubre de 2014

PHP (07) POO (08) Carga automática de clases

Hasta ahora hemos visto todo lo relacionado con objetos dentro del mismo archivo, sin embargo la planificación en proyectos grandes donde las clases pueden ser muy grandes con multitud de métodos... pueden resultar más interesante, al igual que cuando hablamos de los includes, que tengamos nuestras clases en diferentes archivos, para que de ese modo pueda estar el código más estructurado y sencillo de entender.

Para este propósito PHP incluye una función que puede ser utilizada de forma muy sencilla, se trata de __autoload().
Su uso como veremos a continuación es sumamente sencillo y nos ayudará muchísimo a la hora de organizar nuestro trabajo.
function __autoload($nombre_clase)
{
 require $nombre_clase . '.php';
}

Vemos que esta función recibe el nombre de una clase como argumento y una vez recibido le añade la extensión del archivo .php y lo requiere, por lo que solo lo carga cuando es necesario.

De este modo podríamos tener dos archivos adicionales que recibirían el nombre de las clases, el primero llamado Person.php:
<?php
 class Person
 {
  var $nombre;
  var $edad;
  
  function set_nombre($dato)
  {
   $this->nombre = $dato;
  }
  
  function get_nombre()
  {
   return $this->nombre;
  }

  function set_edad($dato)
  {
   $this->edad = $dato;
  }
  
  function get_edad()
  {
   return $this->edad;
  }
 }

?>

Y el segundo llamado Ciudad.php:
<?php
class Ciudad extends Person
 {
  var $ciudad;

  function set_ciudad($dato)
  {
   $this->ciudad = $dato;
  }
  
  function get_ciudad()
  {
   return $this->ciudad;
  }

 }
?>

Aparte de nuestro index.php, donde tiene lugar la acción:
<?php
 function __autoload($nombre_clase)
 {
  require $nombre_clase . '.php';
 }

 $persona1 = new Ciudad;
 $persona1->set_nombre('Antonio');
 $persona1->set_edad('20');
 $persona1->set_ciudad('Burgos');

 echo '<p>Mostrando nombre con $persona1->get_nombre: ' . $persona1->get_nombre() . '</p>';
 echo '<p>Mostrando edad con $persona1->get_edad: ' . $persona1->get_edad() . '</p>';
 echo '<p>Mostrando ciudad con $persona1->get_ciudad: ' . $persona1->get_ciudad() . '</p>';

?>

Una vez que tenemos los tres archivos (que deben de estar en la misma carpeta), tan solo hace falta ejecutar el index.php y tendremos el siguiente resultado:
Mostrando nombre con $persona1->get_nombre: Antonio
Mostrando edad con $persona1->get_edad: 20
Mostrando ciudad con $persona1->get_ciudad: Burgos

Algo realmente sencillo.
Con todo lo visto hasta ahora ya estamos listos para afrontar la POO avanzada a partir del próximo articulo.

PHP (07) POO (07) Sobrecarga de métodos

Seguramente si conoces otros lenguajes de programación como JAVA, este apartado te resulte extraño, ya que PHP sobrecarga los métodos de forma muy diferente a como se hace de forma común a otros lenguajes.
Para ello se utiliza un método llamado __call() al que se le pasa como argumentos; el nombre del método y una lista con los argumentos que este método necesitaría. Este método __call, recibe aquellos métodos que no están definidos de forma independiente, comprobando que estén definidos en su interior.
function __call($metodo, $argumentos)
{
 ...
}  

De este modo imaginemos que queremos introducir una sobrecarga en nuestro método set_name, donde podría introducirse el nombre y los apellidos. Deberemos de crear nuestro método __call en relación a este objetivo.
Lo primero que habría que discernir es si el método pasado por argumento es el correcto, haciéndolo con un if:
function __call($metodo, $argumentos)
{
 if ($metodo = 'set_nombre'){
  ...
 }
}

De este modo controlamos que el método tenga el nombre correcto, pero ahora hay que comprobar el número de argumentos y que se debe de hacer en cada caso, ya que como se ha dicho $argumentos es una lista o array.
function __call($metodo, $argumentos)
{
 if ($metodo = 'set_nombre'){
  if (count($argumentos) == 1){
   $this->nombre = $argumentos[0];
  }
  if (count($argumentos) == 2){
   $this->nombre = $argumentos[0];
   $this->apellido = $argumentos[1];
  }
 }
}

El código comprueba el número de elementos enviados en la lista y dependiendo de cuantos haya crea el objeto con o sin apellido. (Recordemos que los arrays tienen como primer elemento el cero.)

De este modo ahora podemos comprobar como funciona con el siguiente código, donde se crean dos objetos, cada uno con un número diferente de argumentos:
<?php
 class Person
 {
  var $nombre;
  var $apellido;
  var $edad;

  //Funcion __call que recoge el nombre sobrecargado
  function __call($metodo, $argumentos)
  {
   if ($metodo = 'set_nombre'){
    if (count($argumentos) == 1){
     $this->nombre = $argumentos[0];
    }
    if (count($argumentos) == 2){
     $this->nombre = $argumentos[0];
     $this->apellido = $argumentos[1];
    }
   }
  }

  //Aquí comienzan los geters y seters de las propiedades. 
  function get_nombre()
  {
   return $this->nombre;
  }
  function get_apellido()
  {
   return $this->apellido;
  }

  function set_edad($dato)
  {
   $this->edad = $dato;
  }
  
  function get_edad()
  {
   return $this->edad;
  }
 }
 $persona1 = new Person;
 $persona1->set_nombre('Antonio');
 $persona1->set_edad('20');

 $persona2 = new Person;
 $persona2->set_nombre('Manuel', 'Gonzalez');
 $persona2->set_edad('28');

 echo '<h3>Persona1</h3>';
 echo '<p>Mostrando con $persona1->get_nombre: ' . $persona1->get_nombre() . '</p>';
 echo '<p>Mostrando con $persona1->get_edad: ' . $persona1->get_edad() . '</p>';
 echo '<h3>Persona2</h3>';
 echo '<p>Mostrando con $persona2->get_nombre: ' . $persona2->get_nombre() . '</p>';
 echo '<p>Mostrando con $persona2->get_apellido: ' . $persona2->get_apellido() . '</p>';
 echo '<p>Mostrando con $persona2->get_edad: ' . $persona2->get_edad() . '</p>';
?> 

En este código podemos ver como esta incluido nuestro método sobrecargado, y como creamos los dos objetos, el que solo lleva un argumento y el que lleva los dos.
Después solicitamos los datos de ambos objetos y obtenemos el siguiente resultado:

Persona1

Mostrando con $persona1->get_nombre: Antonio
Mostrando con $persona1->get_edad: 20

Persona2

Mostrando con $persona2->get_nombre: Manuel
Mostrando con $persona2->get_apellido: Gonzalez
Mostrando con $persona2->get_edad: 28

Como dije al principio, la forma de realizar los métodos sobrecargados en PHP es algo distinta a como se hace en otros lenguajes, pero no es mucho más difícil, tan solo hay que saber controlar el flujo a través de las instrucciones if.
Pero si reflexionamos sobre esto, llegamos a la conclusión de que con un método __call() se pueden controlar todos los métodos para crear un objeto... pero eso lo dejo en vuestras manos...

PHP (07) POO (06) Herencias (05) Sobreescribir métodos

Por sobreescribir métodos se considera que desde una clase heredada, se define un método que se llama igual que otro de la clase padre, de este modo cuando lo invocamos desde un objeto al que llamamos, es al de la clase hijo, haciendo que se ejecute ese código.
En el siguiente ejemplo puede verse claramente:
<?php
 class Person
 {
  var $nombre;
  var $edad;

  function __construct($nombre, $edad)
  {
   $this->nombre=$nombre;
   $this->edad=$edad;
  }

  function set_nombre($dato)
  {
   $this->nombre = $dato;
  }
  
  function get_nombre()
  {
   return $this->nombre;
  }

  function set_edad($dato)
  {
   $this->edad = $dato;
  }
  
  function get_edad()
  {
   return $this->edad;
  }
 }

 class Ciudad extends Person
 {
  var $ciudad;

  function __construct($nombre, $edad, $ciudad)
  {
   parent::__construct($nombre, $edad);
   $this->ciudad=$ciudad;
  }

  function set_ciudad($dato)
  {
   $this->ciudad = $dato;
  }
  
  function get_ciudad()
  {
   return $this->ciudad;
  }

  function get_nombre(){
   $this->nombre = strtoupper($this->nombre);
   return $this->nombre;
  }


 }

 $persona1 = new Ciudad('Angel', '24', 'Cordoba');

 echo '<p>Mostrando nombre con $persona1->get_nombre: ' . $persona1->get_nombre() . '</p>';
 echo '<p>Mostrando edad con $persona1->get_edad: ' . $persona1->get_edad() . '</p>';
 echo '<p>Mostrando ciudad con $persona1->get_ciudad: ' . $persona1->get_ciudad() . '</p>';
?>

Se ha introducido un función llamada get_nombre() en el hijo, de modo que cuando la llamamos es esta la que se ejecuta, en la cual para diferenciarla de la que se encuentra en el padre hemos transformado el string en mayúsculas, obteniendo como resultado:
Mostrando nombre con $persona1->get_nombre: ANGEL
Mostrando edad con $persona1->get_edad: 24
Mostrando ciudad con $persona1->get_ciudad: Cordoba

sábado, 25 de octubre de 2014

PHP (07) POO (06) Herencias (04) Acceso a métodos del padre

Cuando queremos llamar a un método del padre, por norma general no es un problema, ya que al haber heredado todos los métodos y propiedades de este, es posible acceder a ellos de forma normal, pero puede ocurrir que el padre tenga algunos métodos protegidos (protected), para ello debemos utilizar la expresión parent:: tal y como vimos con los constructores.
De este modo, podemos hacer el método publico y acceder al método o la propiedad.
En el siguiente ejemplo vemos como los métodos de la clase padre están protegidos y como se puede acceder a ellos a través de la clase heredada:
<?php
 class Person
 {
  var $nombre;
  var $edad;

  protected function set_nombre($dato)
  {
   $this->nombre = $dato;
  }
  
  protected function get_nombre()
  {
   return $this->nombre;
  }

  protected function set_edad($dato)
  {
   $this->edad = $dato;
  }
  
  protected function get_edad()
  {
   return $this->edad;
  }
 }

 class Ciudad extends Person
 {
  var $ciudad;

  function set_ciudad($dato)
  {
   $this->ciudad = $dato;
  }
  
  function get_ciudad()
  {
   return $this->ciudad;
  }

  function set_nombre_publico($dato)
  {
   parent::set_nombre($dato);
  }

  function get_nombre_publico()
  {
   return parent::get_nombre();
  }

  function set_edad_publico($dato)
  {
   parent::set_edad($dato);
  }

  function get_edad_publico()
  {
   return parent::get_edad();
  }

 }

 $persona1 = new Ciudad;
 $persona1->set_nombre_publico('Mateo');
 $persona1->set_edad_publico('27');
 $persona1->set_ciudad('Madrid');

 echo '<p>Mostrando nombre con $persona1->get_nombre_publico: ' . $persona1->get_nombre_publico() . '</p>';
 echo '<p>Mostrando edad con $persona1->get_edad_publico: ' . $persona1->get_edad_publico() . '</p>';
 echo '<p>Mostrando ciudad con $persona1->get_ciudad: ' . $persona1->get_ciudad() . '</p>';
?>


En este script se observa como los métodos de la clase padre están protegidos, y como aparecen los métodos para hacerlos publicos a través de nuevos métodos en la clase heredada por medio de parent:: que son los accesibles a la hora de crear y acceder a los datos del objeto.
De hecho el resultado obtenido aquí sería:
Mostrando nombre con $persona1->get_nombre_publico: Mateo
Mostrando edad con $persona1->get_edad_publico: 27
Mostrando ciudad con $persona1->get_ciudad: Madrid


Pero la herencia puede tener diferentes niveles, ¿y que ocurriría si un padre tuviera un método protegido y se quisiera acceder desde una clase que herede de otra que herede el padre? (vamos que sería la nieta)
Pues en este caso ya no nos valdría la forma que hemos visto, pero para resolverlo es tan sencillo como cambiar la palabra parent, por el nombre de la clase que tiene el método protegido:
function set_nombre_publico($dato)
{
 Person::set_nombre($dato);
}

Tan sencillo como eso, de hecho, se puede utilizar este método para las herencias directas.

jueves, 23 de octubre de 2014

PHP (07) POO (06) Herencias (03) Constructores y herencias

Como ya hemos visto, la forma ideal de crear un objeto es a través de un constructor, pero con lo que hemos visto hasta ahora no podemos crearlo desde una clase heredada, aunque la solución es muy sencilla, para ello la clase padre debe de tener su propio constructor, por lo que he añadido el siguiente método a nuestro ejemplo (en definitiva es el mismo que de si de una clase independiente se tratara):
function __construct($nombre, $edad)
{
 $this->nombre=$nombre;
 $this->edad=$edad;
}


Una vez que tenemos el constructor en la clase padre hay que hacer que la clase heredada pueda acceder a ella, de modo que introducimos el siguiente método constructor:
function __construct($nombre, $edad, $ciudad)
{
 parent::__construct($nombre, $edad);
 $this->ciudad=$ciudad;
}

Aquí vemos que el constructor de la clase heredada tiene tres argumentos, los dos que va a necesitar para el padre y el que requiere ella misma.
A continuación se utiliza la instrucción:
parent::__construct($nombre, $edad);

que accede al constructor del padre, enviando los dos argumentos que necesita, y finalmente añade al objeto la propiedad de la clase propiamente dicha, creando de este modo el objeto de forma natural.

En el siguiente ejemplo se ve como funciona todo el script de forma sencilla y practica:
<?php
 class Person
 {
  var $nombre;
  var $edad;

  function __construct($nombre, $edad)
  {
   $this->nombre=$nombre;
   $this->edad=$edad;
  }

  function set_nombre($dato)
  {
   $this->nombre = $dato;
  }
  
  function get_nombre()
  {
   return $this->nombre;
  }

  function set_edad($dato)
  {
   $this->edad = $dato;
  }
  
  function get_edad()
  {
   return $this->edad;
  }
 }

 class Ciudad extends Person
 {
  var $ciudad;

  function __construct($nombre, $edad, $ciudad)
  {
   parent::__construct($nombre, $edad);
   $this->ciudad=$ciudad;
  }

  function set_ciudad($dato)
  {
   $this->ciudad = $dato;
  }
  
  function get_ciudad()
  {
   return $this->ciudad;
  }

  function set_nombre_publico($dato)
  {
   $this->set_nombre($dato);
  }

 }

 $persona1 = new Ciudad('Angel', '24', 'Cordoba');

 echo '<p>Mostrando nombre con $persona1->get_nombre: ' . $persona1->get_nombre() . '</p>';
 echo '<p>Mostrando edad con $persona1->get_edad: ' . $persona1->get_edad() . '</p>';
 echo '<p>Mostrando ciudad con $persona1->get_ciudad: ' . $persona1->get_ciudad() . '</p>';
?>

Como se puede ver, la creación del objeto se hace igual que siempre; el nombre del objeto, new, la clase a la que pertenece, y todos los argumentos que necesita para su creación.
De este modo obtenemos el siguiente resultado:
Mostrando nombre con $persona1->get_nombre: Angel
Mostrando edad con $persona1->get_edad: 24
Mostrando ciudad con $persona1->get_ciudad: Cordoba

miércoles, 22 de octubre de 2014

Python (06) Listas

Aunque ya se han tocado la listas de forma superficial y más tarde para mostrar como se hace un array bidimensional, ahora vamos a aprender mucho más sobre como funcionan y su control, sobre todo por que puede resultar extremadamente interesante.

Métodos

Empezaremos analizando algunos de sus metodos:
  • list.append (i) Agrega un elemento al final de la lista
  • list.extend (l) Agrega a la lista todos los elementos de una lista dada
  • list.insert (x, i) Inserta un elemento i delante de la posición x, por lo que list.insert (3, 'Pi') insertará Pi delante de la posicion 3.
  • list.remove (i) Elimina el primer elemento de la lista que coincida con i, pero si no hay ninguno nos dará un error
  • list.pop (x) Elimina el elemento de la posición solicitada y lo devuelve, en caso de no añadir la posición lo hará de la última.
  • list.clear() Elimina todos los elementos de una lista
  • list.index(i) Devuelve el número de veces que i aparece en la lista
  • list.sort(key=none reverse=false) Sirve para ordenar una lista, los argumentos se pueden utilizar para definir un orden especifico
  • list.reverse() Invierte los elementos de la lista
  • list.copy() Devuelve la mayoría de lo elementos de una lista.
 En el siguiente ejemplo se observa el funcionamiento de muchas de estas funciones:
a = [2, 56.78, 33.44, 1, 2]
print(a.count(2), a.count(1))

a.insert(2, 3)
print(a)
a.append(102)
print(a)
print(a.index(1))
a.remove(2)
print(a)
a.reverse()
print(a)
a.sort()
print(a)
a.pop()
print(a)

El cual nos da como resultado:
2 1
[2, 56.78, 3, 33.44, 1, 2]
[2, 56.78, 3, 33.44, 1, 2, 102]
4
[56.78, 3, 33.44, 1, 2, 102]
[102, 2, 1, 33.44, 3, 56.78]
[1, 2, 3, 33.44, 56.78, 102]
[1, 2, 3, 33.44, 56.78]


Pilas

El concepto de pila es muy sencillo, imagina una pila de libros, donde para poner uno libro siempre tienes que ponerlo encima y para quitarlo siempre retiras el de lo alto. Es decir el último que llega antes se va.
Para utilizar esta estructura es tan sencillo como utilizar los métodos:
  • list.append() que coloca al final
  • list.pop() que quita el último elemento de la lista
Esta estructura se suele utilizar en algunos casos de programación

Colas

Si el concepto de pila es sencillo, el de cola lo es más todavía, tan solo tenemos que imaginar una cola para entrar al cine, concierto, del paro... donde los nuevos elementos que llegan se colocan al final de la cola, pero los que salen son los que están al principio.

PHP (07) POO (06) Herencias (02) Acceso protegido

Al utilizar la palabra reservada protected, estamos haciendo que la propiedad o método sea solo accesible desde la propia clase y de sus herederas, de modo que no se puede acceder desde el resto del código.
En el siguiente ejemplo vemos como funciona esto:
class Person
 {
  var $nombre;
  var $edad;

  //Aquí comienzan los geters y seters de las propiedades.
  protected function set_nombre($dato)
  {
   $this->nombre = $dato;
  }
  
  function get_nombre()
  {
   return $this->nombre;
  }

  function set_edad($dato)
  {
   $this->edad = $dato;
  }
  
  function get_edad()
  {
   return $this->edad;
  }
 }

Esto hace imposible acceder al método set_nombre si no es desde la propia clase Person o de sus herederas, por lo que no podemos acceder a ella de la forma habitual:
$persona1->set_nombre('Antonio');

Para poder acceder a ella se debe de hacer desde su heredera, creando un método que permita llamar al protegido y pasarle el valor como vemos en el siguiente ejemplo completo:
<?php
 class Person
 {
  var $nombre;
  var $edad;

  //Aquí comienzan los geters y seters de las propiedades.
  protected function set_nombre($dato)
  {
   $this->nombre = $dato;
  }
  
  function get_nombre()
  {
   return $this->nombre;
  }

  function set_edad($dato)
  {
   $this->edad = $dato;
  }
  
  function get_edad()
  {
   return $this->edad;
  }
 }

 class Ciudad extends Person
 {
  var $ciudad;

  function set_ciudad($dato)
  {
   $this->ciudad = $dato;
  }
  
  function get_ciudad()
  {
   return $this->ciudad;
  }

  function set_nombre_publico($dato)
  {
   $this->set_nombre($dato);
  }
 }

 $persona1 = new Ciudad;
 $persona1->set_nombre_publico('Antonio');
 $persona1->set_edad('23');
 $persona1->set_ciudad('Zaragoza');

 echo '<p>Mostrando nombre con $persona1->get_nombre: ' . $persona1->get_nombre() . '</p>';
 echo '<p>Mostrando edad con $persona1->get_edad: ' . $persona1->get_edad() . '</p>';
 echo '<p>Mostrando ciudad con $persona1->get_ciudad: ' . $persona1->get_ciudad() . '</p>';
?>

Aquí vemos como en la clase Ciudad se llama traves de la función set_nombre_publico a la función set_nombre que está protegida, de modo que al introducir el nombre de la persona se accede por medio de set_nombre_publico.
De este modo se obtiene el resultado deseado:
Mostrando nombre con $persona1->get_nombre: Antonio
Mostrando edad con $persona1->get_edad: 23
Mostrando ciudad con $persona1->get_ciudad: Zaragoza


PHP (07) POO (06) Herencias (01) Cómo hacer una clase que herede

Hasta ahora hemos visto objetos que dependen de una sola clase, pero puede darse el caso de que necesitemos que objetos del mismo tipo dependan de diferentes clases, donde lo objetos tengan propiedades iguales y diferentes.
Siguiendo con nuestro ejemplo, supongamos que cada persona que creemos vive en una ciudad, aunque es cierto que la ciudad podría ser una propiedad de nuestro objeto persona, vamos a suponer que queremos que herede de este, es decir, que utilice los métodos de Person y los suyos propios. Para ello tan solo hace falta escribir una nueva clase de la misma forma pero a continuación debemos de poner la palabra reservada extends y la clase de la que hereda:
class Ciudad extends Person
 {
  ...
 }


Una vez que tenemos la nueva clase, tan solo hay que introducir las propiedades y los métodos set y get:
class Ciudad extends Person
 {
  var $ciudad;

  function set_ciudad($dato)
  {
   $this->ciudad = $dato;
  }
  
  function get_ciudad()
  {
   return $this->ciudad;
  }

 }

Una vez que tenemos esto ya podemos crear nuestro objeto, desde Ciudad que nos permite usar todos los métodos, tal y como vemos aquí:
<?php
 class Person
 {
  var $nombre;
  var $edad;

  //Aquí comienzan los geters y seters de las propiedades.
  function set_nombre($dato)
  {
   $this->nombre = $dato;
  }
  
  function get_nombre()
  {
   return $this->nombre;
  }

  function set_edad($dato)
  {
   $this->edad = $dato;
  }
  
  function get_edad()
  {
   return $this->edad;
  }
 }

 class Ciudad extends Person
 {
  var $ciudad;

  function set_ciudad($dato)
  {
   $this->ciudad = $dato;
  }
  
  function get_ciudad()
  {
   return $this->ciudad;
  }

 }

 $persona1 = new Ciudad;
 $persona1->set_nombre('Antonio');
 $persona1->set_edad('23');
 $persona1->set_ciudad('Zaragoza');

 echo '<p>Mostrando nombre con $persona1->get_nombre: ' . $persona1->get_nombre() . '</p>';
 echo '<p>Mostrando edad con $persona1->get_edad: ' . $persona1->get_edad() . '</p>';
 echo '<p>Mostrando ciudad con $persona1->get_ciudad: ' . $persona1->get_ciudad() . '</p>';
?>

Y que nos da como resultado:
Mostrando nombre con $persona1->get_nombre: Antonio
Mostrando edad con $persona1->get_edad: 23
Mostrando ciudad con $persona1->get_ciudad: Zaragoza

De este modo es como funciona la herencia, la clase que hereda puede utilizar todos los métodos de la clase "padre", siempre que estos sean publicos, ya que los privados no se heredarán.
Como sabemos los accesos publicos están disponibles a todo el código, pero...¿cómo podemos poner un método o propiedad de forma que se herede y que no permita el acceso de todo el código?...
Utilizando el acceso protegido...
 

martes, 21 de octubre de 2014

PHP (07) POO (05) Destructores

Al igual que existen los constructores en PHP también existen los destructores, que son métodos que destruyen el objeto, esto sirve para hacer limpieza después de utilizar el objeto, si ya no se va a utilizar más o en el caso con las conexiones a bases de datos.

Los destructores se llaman __destruct() y no necesitan argumentos ya que destruyen el objeto completamente.
function __destruct()
{
 
}

De hecho esta función se ejecuta automaticamente cuando termina el script para liberar memoria, tal y como vemos en el siguiente ejemplo completo.
<?php
 class Person
 {
  var $nombre;
  var $edad;

  function __construct($nombre, $edad)
  {
   $this->nombre=$nombre;
   $this->edad=$edad;
  }

  function __destruct()
  {
   echo '<p>Destruyendo el objeto ' . $this->nombre . '...</p>';
  }

  //Aquí comienzan los geters y seters de las propiedades.
  function set_nombre($dato)
  {
   $this->nombre = $dato;
  }
  
  function get_nombre()
  {
   return $this->nombre;
  }

  function set_edad($dato)
  {
   $this->edad = $dato;
  }
  
  function get_edad()
  {
   return $this->edad;
  }
 }
 $persona1 = new Person('Antonio', '23');

 echo '<p>Mostrando con $persona1->get_nombre: ' . $persona1->get_nombre() . '</p>';
 echo '<p>Mostrando con $persona1->get_edad: ' . $persona1->get_edad() . '</p>';
?>

Que nos da como resultado:
Mostrando con $persona1->get_nombre: Antonio
Mostrando con $persona1->get_edad: 23
Destruyendo el objeto Antonio...

lunes, 20 de octubre de 2014

PHP (07) POO (04) Constructores

Hasta ahora para introducir los datos de un objeto hemos tenido que hacerlo mediante la función set, pero esto aunque funciona no es lo más practico, existe un tipo de función en PHP llamada constructor, y que se define como __constructor(argumentos), con la cual se pueden introducir los datos del objeto a la hora de su declaración, tal y como vemos a continuación:
<?php
 class Person
 {
  var $nombre;
  var $edad;

  function __construct($nombre, $edad)
  {
   $this->nombre=$nombre;
   $this->edad=$edad;
  }

  //Aquí comienzan los geters y seters de las propiedades
  function set_nombre($dato)
  {
   $this->nombre = $dato;
  }
  
  function get_nombre()
  {
   return $this->nombre;
  }

  function set_edad($dato)
  {
   $this->edad = $dato;
  }
  
  function get_edad()
  {
   return $this->edad;
  }
 }
 $persona1 = new Person('Antonio', '23');

 echo '<p>Mostrando con $persona1->get_nombre: ' . $persona1->get_nombre() . '</p>';
 echo '<p>Mostrando con $persona1->get_edad: ' . $persona1->get_edad() . '</p>';
?>

En este script hemos introducido una nueva propiedad llamada $edad, y hemos introducido sus métodos get y set, además hemos puesto la función __construct que recibe como parámetros el nombre y la edad, y que introduce dentro del objeto estos parámetros a través de $this-> de este modo cuando hemos declarado el objeto con new, hemos puesto los datos. Al crearse el objeto, la clase activa el constructor e introduce los datos dándonos el objeto ya listo para trabajar, tal y como hacemos luego con los echos, obteniendo como resultado:
Mostrando con $persona1->get_nombre: Antonio
Mostrando con $persona1->get_edad: 23

De este modo se puede observar como el constructor nos ahorra código, y nos sirve para crear de forma automática los objetos. Aunque este debe de tener los atributos necesarios.

Otra forma de llamar al constructor es usando el mismo nombre de la clase, de este modo la clase lo identifica como el constructor, pero ambas formas obtienen idénticos resultados.
function Person($nombre, $edad)
  {
   $this->nombre=$nombre;
   $this->edad=$edad;
  }

domingo, 19 de octubre de 2014

PHP (07) POO (03) Accesos

Hasta ahora nuestras propiedades y métodos han sido accesibles desde cualquier parte del código, por lo que no hemos tenido ningún problema a la hora de trabajar con ellos, pero en la programación orientada a objetos.
Hay varias formas de poner restricciones, para ello vamos a utilizar varias palabras reservadas:
  • Public: la opción por defecto, es visible a todo
  • Private: significa accesible solo desde la misma clase
  • Protected: accesible solo desde la misma clase y desde las clases derivadas.

Private

Se puede hacer privada una propiedad o un método, pero si se hace esto, ya solo podrán ser accesibles desde dentro de la clase o el objeto y no desde otro lado.
En el siguiente ejemplo probamos a ha hacer privada la propiedad $nombre y a acceder a ella desde fuera desde la clase, para ello cambiamos var por private.
<?php
 class Person
 {
  private $nombre;

  function set_nombre($dato)
  {
   $this->nombre = $dato;
  }
  
  function get_nombre()
  {
   return $this->nombre;
  }
 }
 $persona1 = new Person;
 $persona1->set_nombre('Miguel');

 echo '<p>Mostrando con $persona1->get_nombre: ' . $persona1->get_nombre() . '</p>';
 echo '<p>Mostrando con $persona1->nombre: ' . $persona1->nombre . '</p>';
?>

Lo cual nos da como resultado:
Mostrando con $persona1->get_nombre: Miguel

Fatal error: Cannot access private property Person::$nombre in C:\xampp\htdocs\miphp\POO\persona.php on line 20
La razón es que en el primer echo hemos accedido al valor de la propiedad invocando al método de la clase, que es pública, mientras que en el segundo echo, que es el que nos muestra el error, hemos intentado acceder a la propiedad directamente pero al encontrarnos fuera de la clase nos es inaccesible debido a su privacidad.

También podemos hacer privadas los métodos de una clase, simplemente colocando la palabra reservada private delante de su declaración.
En este caso vamos a convertir en private la función get_nombre:
<?php
 class Person
 {
  var $nombre;

  function set_nombre($dato)
  {
   $this->nombre = $dato;
  }
  
  private function get_nombre()
  {
   return $this->nombre;
  }
 }
 $persona1 = new Person;
 $persona1->set_nombre('Miguel');

 echo '<p>Mostrando con $persona1->get_nombre: ' . $persona1->get_nombre() . '</p>';
 echo '<p>Mostrando con $persona1->nombre: ' . $persona1->nombre . '</p>';
?>

Este código no puede acceder al primer echo, ya que la función get_nombre es privada, mostrándonos el siguiente error:
Fatal error: Call to private method Person::get_nombre() from context '' in C:\xampp\htdocs\miphp\POO\persona.php on line 19

Pero si comentamos el primer echo y lo ejecutamos, observamos que si accede al valor de la propiedad mostrando su valor.
Mostrando con $persona1->nombre: Miguel



PHP (07) POO (02) Objetos

Para crear un objeto en PHP es necesaria la palabra reservada new, una vez que esta definida la clase de la que va a depender el objeto.
Además los objetos se almacenan como variables, de modo que teniendo en cuenta el código donde hemos definido una clase nos quedaría de este modo:
<?php
 class Person
 {
  var $nombre;

  function set_nombre($dato)
  {
   $this->nombre = $dato;
  }
  
  function get_nombre()
  {
   return $this->nombre;
  }
 }
 $persona1 = new Person;
?>

De esta forma hemos creado nuestro primer objeto persona1, pero aun no tiene definido su nombre, aunque esto va a ser sencillo, ya que todas las propiedades y métodos, de la clase a la que pertenece el objeto están integrados en él, de este modo, para asignarle un nombre es tan fácil como añadir la línea que hemos introducido después de la creación del objeto:
 $persona1 = new Person;
 $persona1->set_nombre('Miguel');

De esta forma se pueden llamar a los métodos de la clase, tan solo poniendo el nombre del objeto seguido del operador -> y luego el método que queremos llamar.
De este modo hemos hecho que $persona1 tenga como propiedad nombre Miguel.

Hay dos formas de mostrar la información de la propiedad del objeto como puede verse a continuación:
 echo '<p>Mostrando con $persona1->get_nombre: ' . $persona1->get_nombre() . '</p>';
 echo '<p>Mostrando con $persona1->nombre: ' . $persona1->nombre . '</p>';


Los métodos que devuelven valores de propiedades se denominan métodos accessor (o de acceso) en la programación orientada a objetos y son populares porque dan control sobre la forma en que se establecen datos internos contenidos en un objeto.

Con esto podemos empezar a comprender como funciona la programación orientada a objetos y nos da las bases para ir entendiendo todo lo que vamos a ver en el tema de POO.

PHP (07) POO (01) Clases

La programación orientada a objetos comienza por las clases, las clases definen el tipo de objeto, y el objeto es una instancia de la clase...
Una vez que tenemos creada la clase es posible crear objetos de esa clase.
Así es como lo definen muchos manuales, y la verdad es que es un infierno, pero... ¿cómo podemos definir todo esto de forma que se pueda entender claramente?
Bueno como reza el credo de este blog, "Me lo contaron y lo olvide, lo ví y lo entendí, lo hice y lo aprendí". De modo que vayamos destripando todo esto.
Lo que tenemos que tener claro es que las clases son lo principal en la programación orientada a objetos de modo que debemos de definirlas de la siguiente manera:
  • Se utiliza la palabra reservada class.
  • Se nombran con la primera letra en mayúscula.
  • Las clases pueden tener propiedades, que son características que van a definir al objeto.
En el siguiente ejemplo vamos a crear una clase llamada persona (Todo un clásico de la programación), y que va a tener una propiedad denominada nombre.
<?php
 class Person
 {
  var $nombre;
 }
?>

Como podemos ver la propiedad se declara como una variable con la palabra reservada var delante.

Dentro de una clase se pueden declarar métodos (funciones), tal y como lo hemos hecho hasta ahora.
En el ejemplo vamos a introducir una función que sirva para captar el nombre pasándoselo como un argumento y haciendo que acceda de forma global a la propiedad, aunque en POO no se utiliza la palabra global, si no $this, que apunta al objeto actual:
<?php
 class Person
 {
  var $nombre;
  
  function set_nombre($dato)
  {
   $this->nombre = $dato;
  }
  ....
 }
?>

De esta forma se hace que el objeto actual almacene como valor el dato que se le envía como argumento a la función set_nombre.

Pero también hará falta alguna forma de de leer el nombre de la persona y de devolverlo, de modo que se puede crear otro método que sea get_nombre de la siguiente forma:
<?php
 class Person
 {
  var $nombre;

  function set_nombre($dato)
  {
   $this->nombre = $dato;
  }
  
  function get_nombre()
  {
   return $this->nombre;
  }
 }
?>

De esta forma tenemos terminada nuestra clase, pero aun no hace nada, debemos de crear objetos.

Hay que tener en consideración que cada propiedad debe de tener sus dos métodos set y get, para poder trabajar más adelante con ellas.

No te preocupes, lee la entrada de objetos y seguirás comprendiendo todo esto.


viernes, 17 de octubre de 2014

Python (05) Estilo de codificación

Una vez que ya hemos visto lo más básico de Python, es hora de ver las reglas de estilo de codificación de este lenguaje, para ello puedes acceder a la web de PEP 8, donde se encuentran descritas, ya que en esta entrada solo veremos las más importantes:
  •  Recorta la líneas a 79 caracteres, ayudando a los usuarios con pantallas pequeñas a tener una buena visualización, y a que los que tienen pantallas grandes les da la posibilidad de tener varios archivos abiertos a la vez.
  • Usa sangrías de 4 espacios, no tabuladores: los 4 espacios son una buena opción entre las más pequeñas que no permiten ver bien el código y las mas grades que lo ensanchan demasiado comiéndose los 79 espacios.
  • Utiliza líneas en blanco cunado vayas a separar funciones y bloques de código
  • Intenta poner los comentarios en una sola línea
  • Utiliza docstrings en las funciones
  • Utiliza espacios alrededor de operadores y detrás de las comas, pero no dentro de los paréntesis.
f = g(1, 2) + h(3, 4) 

  • Hay que nombrar las clases con un nombre descriptivo corto con camelCase y las funciones y métodos con_guiones_bajos.
  • No utilizar codificaciones extrañas, python utiliza UTF-8 por defecto
Con estos consejos los códigos deben de quedar relativamente limpios y claros para el resto de la comunidad.

Validaciones en HTML5

Hoy vamos a ver como se validan formularios solamente empleando html5, ya que entre sus bondades se encuentran esta opción con muchas facilidades para que nuestros formularios estén controlados desde el cliente.
Aun así no esta mal que haya otro control desde el servidor, como he explicado a lo largo del tema 6 de mi tutorial de PHP, donde se pueden tratar de muchas otras formas.
Pero vamos a lo importante en este articulo las validaciones en HTML5, supondremos que todos lo que nos encontramos leyendo estas líneas sabemos o tenemos nociones de html5.
Hasta la aparición de html5, la validación en cliente debía de hacer por código javascript, que da buenos resultados, pero ahora se puede hacer de forma mucho más sencilla directamente en el código html, con tan solo utilizar algunos atributos

type

Con este atributo podemos seleccionar que tipo de entrada queremos que realice el usuario e imponer un pequeño control inicial a nuestro formulario. Para ver una lista completa de los tipos que se pueden utilizar visita mi tabla periódica de los elementos html5 .

required

Este atributo puesto en los inputs es muy útil y de muy fácil uso. Con él se provoca que cuando se le da a enviar el formulario aparezca una nube diciendo el error que se ha cometido y además en Chrome aparece lo que hayamos colocado dentro de una etiqueta title, como información adicional.

En este ejemplo vemos su funcionamiento:
<form>
 <p> Introduzca su nombre
 <input title="introduzca su nombre" type="text"  required></p>
 <p>
 <input type="submit" value="enviar">
</form>

Que se ve así en los diferentes navegadores:

pattern

Con este atributo es donde ya podemos especificarle a html5 como tiene que ser la entrada, ya que en su valor ponemos la expresión regular que deseemos y de ese modo podemos forzar a que la entrada del tipo que deseamos.
Por ejemplo si queremos colocar un email que tenga su propia expresión regular (con solo poner una arroba se detecta como mail por defecto) debemos de hacer lo siguiente:
<form>
 <p> Introduzca su nombre
 <input title="introduzca su nombre" type="text"  required></p>
 <p>Introduzca su email
 <input title="nombre@servidor.dominio" type="email" pattern="/\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([.]\w+)*/" required></p>
 <input type="submit" value="enviar">
</form>

Hay que tener en cuenta que cuando hay un patern, el title sí es tomado en los tres navegadores, pudiendo mostrar de este modo el patron de ejemplo del input:

Es más, incluso si se pasa el ratón por encima del input, aparece un pequeño dialogo en los tres navegadores con el title.


¿Donde conseguir expresiones regulares?

En un principio pensé en poner aquí una lista de expresiones regulares, pero cuando hacía la documentación para el articulo encontré esta gran web especializada en ellas, todas descritas para html5 y aumentando en número, por lo que os recomiendo que la utilicéis.


Nota: el código del ejemplo solo muestra el formulario, pero esta dentro de un archivo html completo, enlazado a un archivo css.

Python (04) Funciones

Llegamos ya a una de las características básicas en todo lenguaje que se precie, las funciones, las cuales básicamente son partes del código que se utilizan varias veces y que pueden ser llamadas en varias ocasiones. De esta forma se ahorra el utilizar código de forma reiterativa para hacer lo mismo una y otra vez, aclarando el código y haciendo mucho más efectivo.
Para empezar a definir funciones debemos de empezar por el principio...

¿Cómo se declara una función?

Para declarar una función se utiliza la palabra reservada def,  seguida de un nombre, una lista de parámetros entre paréntesis y terminando por dos puntos.
El cuerpo de la función debe de estar indexado correctamente o de lo contrario Python nos dará un error.


Documentación

De forma opcional la siguiente parte una función es la documentación, aunque es una buena práctica hacerlo, la documentación tiene algunas convecciones sobre el contenido y el formato:
  • Siempre tiene que ir entre tres grupos de comillas dobles """ .... """
  • En la primera línea se debe de incluir un resumen corto y preciso del propósito de la función. Esta línea debe de empezar con letra mayúscula y terminar un punto.
  • La segunda debe de ir en blanco separando el resumen del resto de la descripción.
  • Las siguientes líneas deben de ser uno o más párrafos describiendo las variables, los valores de retorno, efectos secundarios...
Nota: Aunque esto es lo correcto, tan solo colocaremos esta documentación en algunas de las funciones que vamos a utilizar en este documento para ocupar menos espacio ya que se explican los ejemplos en el texto.

A continuación vemos un ejemplo de función en python:
def fib(n):
    """Esto es una prueba de Fibonacci."""
    a, b = 0, 1
    while a<n:
        print (a, end=' ')
        a, b = b, a+b
    print()

fib(100)

return

La sentencia return devuelve un valor de la función de hecho si no hay ninguna expresión return, o se alcanza el final de la función sin pasar por un return, la función devuelve none.
En el siguiente ejemplo vamos a ver como funcionan  los return dentro de una función.
def fib(n):
    result = []
    a, b = 0,1
    while a<n:
        result.append(a)
        a, b = b, a+b
    return result

f100 = fib(100)
print(f100)

Aquí vemos como en la función se declara una lista, result, a la cual se le va añadiendo el valor resultante en cada ciclo del while y finalmente se devuelve la lista con un return que es lo que muestra el print ya fuera de la función.
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]


Argumentos con valores por omisión

Podemos generar funciones que tengan un determinado número de argumentos, pero que para llamarla no haga falta enviarle todos, ya que se les puede poner algunos de ellos por omisión, es decir que vienen definidos dentro de la propia definición de la función por si no se le introducen en la llamada.
Un ejemplo de esto podría ser la siguiente función:
def pedir_confirmacion(prompt, reintentos=4, queja='Si o no, por favor!'):
    while True:
        ok = input(prompt)
        if ok in ('s', 'S', 'si', 'Si', 'SI'):
            return True
        if ok in ('n', 'no', 'No', 'NO'):
            return False
        reintentos = reintentos - 1
        if reintentos < 1:
            print('Pues le echo yo, por pelmazo')
            return True
        print(queja)

pedir_confirmacion('quiere usted salir?')

Aquí vemos como la función tiene tres argumentos, el primero es un prompt, el segundo el numero de reintentos, que si no se le envía, toma 4 como valor por defecto y una queja que introduce un mensaje de aviso.


Argumentos y palabras clave

En el siguiente ejemplo vemos como una llamada puede llevar un argumento especifico, argumentos sin clasificar y una serie de palabras clave definidas con una función, de este modo:
def pruebas(tipo, *argumentos, **palabrasclaves):
    print("-- ¿a que velocidad viaja una golondrina", tipo, "?")
    print("-- ¿La golondrina ", tipo, "lleva un coco?")
    print('ARGUMNETOS')
    for arg in argumentos:
        print(arg)
    print("-" * 40)
    print('PALABARAS CLAVE')
    claves = sorted(palabrasclaves.keys())
    for c in claves:
        print(c, ":", palabrasclaves[c])

pruebas("africana", "Err no lo se.",
             "Claro, una europea no puede hacerlo.",
             Rey="Arturo rey de lo bretones",
             Guardian="Mago del puente",
             Caballero="Sir Beldebere")

Aunque parece difícil de entender en realidad es bastante sencillo, viendo la definición de la función, se observa que hay un argumento tipo, luego *argumentos y finalmente **palabras clave, en la llamada a la función vemos las siguientes correspondencias:
  • tipo = africana (el primer argumento que se le envía)
  • * argumentos = "Err no lo se." y "Claro, una europea no puede hacerlo.", (los argumentos que no entran en las demás opciones)
  • **palabraclaves = Rey="Arturo rey de lo bretones", Guardian="Mago del puente", Caballero="Sir Beldebere") (Son las palabras clave que ya vienen definidas como si fueran variables.)
El resultado de este script es el siguiente:
-- ¿a que velocidad viaja una golondrina africana ?
-- ¿La golondrina  africana lleva un coco?
ARGUMNETOS
Err no lo se.
Claro, una europea no puede hacerlo.
----------------------------------------
PALABARAS CLAVE
Caballero : Sir Beldebere
Guardian : Mago del puente
Rey : Arturo rey de lo bretones


De este modo podemos introducir todos los argumentos arbitrarios que deseemos, y hacer que nuestras funciones trabajen sin limitaciones:
def concatenar (*args, sep='-'):
    return sep.join(args)

print(concatenar('lunes', 'martes', 'miercoles', 'jueves',
                 'viernes', 'sabado', 'domingo'))

En este ejemplo, la función tiene un numero indeterminado de argumentos y un argumento por omisión, y devuelve una cadena concatenando los argumentos con el valor de omisión sep de la siguiente forma:
lunes-martes-miercoles-jueves-viernes-sabado-domingo

Con esto ya sabemos lo suficiente de funciones como para comenzar a trabajar y hacer algunos scripts complejos, aunque aun nos falta mucho camino.

PHP (06) Validaciones (04) Evitando entrandas de código en formularios

Un problema de seguridad que nos podemos encontrar es que un usuario, como decía un profesor mio, "con mala leche", quiera introducir código html dentro de un formulario, esto puede provocar fallos en la web, y por supuesto en el tratamiento de los datos.
Por ejemplo si tomamos el script del articulo comprobando datos, podemos comprobar que si introducimos nuestro nombre de este modo: <b>nombre</b>, nuestro nombre aparecerá en negrita en la respuesta, cosa que no deseamos.
Afortunadamente PHP tiene una solución muy sencilla para esto, de hecho vamos a tomar ese mismo código y vamos a introducirle tan solo dos cambios quedando del siguiente modo:
<html>
 <head>
  <title>
  Comprobación de datos requeridos
  </title>
 </head>
 <body>
  <h1>Comprobación de datos requeridos</h1>
  <?php
  /*
  Comenzamos buscando si visto esta activo, y vamos llamando a las
  funciones correspondientes para controlar el formulario
  */
   $errors_array = array();
   if(isset($_REQUEST["visto" ])){
    comprobarDatos();
    if(count($errors_array) != 0){
     mostrarErrores();
     mostrarInicio();
    }
    else {
     respuesta();
    }
   }
   else {
    mostrarInicio();
   }
   /*
   Muestra el formulario
   */
   function mostrarInicio()
   {
    echo "<form method='post'>" ;
    echo "<p>¿Cuál es su nombre?</p>" ;
    echo "<input name='flavor' type='text'>" ;
    echo "<input type='submit' value='Enviar'>" ;
    echo "<input type='hidden' name='visto' value='already_seen'>" ;
    echo "</form>" ;
   }
   /*
   Comprueba que el campo de texto no este en blanco, de ser así introduce un mensaje
   en el array global
   */
   function comprobarDatos()
   {
    global $errors_array;
    if($_REQUEST["flavor" ] == "" ) {
     $errors_array[] = "<font color='red'>Indique su nombre</font>" ;
    }
   }
   /*
   recoge los errores del array global, lo recorre y muestra su contenido
   */
   function mostrarErrores()
   {
    global $errors_array;
    foreach ($errors_array as $err){
     echo '<p>' . $err . '</p>';
    }
   }
   /*
   Muestra la respuesta del servidor cuando todo esta correcto
   */
   function respuesta()
   {
    echo "Bienvenido a PHP: ";
    $respuesta = strip_tags($_REQUEST["flavor"]);
    echo $respuesta;

   }
   ?>
 </body>
</html>

Si observamos con atención vemos que tan solo hemos introducido en la función respuesta lo siguiente:
$respuesta = strip_tags($_REQUEST["flavor"]);
echo $respuesta;

Que lo que hace es guardar en una variable el resultado de pasar la respuesta por la función strip_tags(), la cual elimina las etiquetas que pueda tener el argumento introducido, en este caso nuestra respuesta de usuario.
Finalmente se imprime la variable y de ese modo no tenemos que preocuparnos por ese tipo de personas malintencionadas.


jueves, 16 de octubre de 2014

PHP (06) Validaciones (03) Datos persistentes

Imaginemos que tenemos un formulario con diferentes campos, y que el usuario envía solo uno, o que uno es correcto y el otro no, para ello podemos mostrar de nuevo los datos que ha enviado el usuario y que son correctos.
Para ello, basandonos en nuestro script de base podemos crear el siguiente:
<html>
 <head>
  <title>
  Comprobación de datos requeridos
  </title>
 </head>
 <body>
  <h1>Comprobación de datos requeridos</h1>
  <?php
  /*
  Comenzamos buscando si visto esta activo, y vamos llamando a las
  funciones correspondientes para controlar el formulario
  */
   $errors_array = array();
   if(isset($_REQUEST["visto" ])){
    comprobarDatos();
    if(count($errors_array) != 0){
     mostrarErrores();
     mostrarInicio();
    }
    else {
     respuesta();
    }
   }
   else {
    mostrarInicio();
   }
   /*
   Muestra el formulario
   */
   function mostrarInicio()
   {
    $nombre = isset($_REQUEST["first"]) ? $_REQUEST["first"] : "";
    $apellido = isset($_REQUEST["last"]) ? $_REQUEST["last"] : "";
    echo "<form method='post'>" ;
    echo "<p>¿Cuál es su nombre?</p>" ;
    echo "<input name='first' type='text' value='". $nombre . "'>" ;
    echo "<p>¿Cuál es su apellido?</p>" ;
    echo "<input name='last' type='text' value='". $apellido . "'>" ;
    echo "<input type='submit' value='Enviar'>" ;
    echo "<input type='hidden' name='visto' value='already_seen'>" ;
    echo "</form>" ;
   }
   /*
   Comprueba que el campo de texto no este en blanco, de ser así introduce un mensaje
   en el array global
   */
   function comprobarDatos()
   {
    global $errors_array;
    if($_REQUEST["first" ] == "" ) {
     $errors_array[] = "<font color='red'>Indique su nombre</font>" ;
    }
    if($_REQUEST["last" ] == "" ) {
     $errors_array[] = "<font color='red'>Indique su apellido</font>" ;
    }
   }
   /*
   recoge los errores del array global, lo recorre y muestra su contenido
   */
   function mostrarErrores()
   {
    global $errors_array;
    foreach ($errors_array as $err){
     echo '<p>' . $err . '</p>';
    }
   }
   /*
   Muestra la respuesta del servidor cuando todo esta correcto
   */
   function respuesta()
   {
    echo "Su nombre es: ";
    echo $_REQUEST["first"];
    echo '<p></p>Y su apellido: ';
    echo $_REQUEST["last"];
   }
   ?>
 </body>
</html>

Este script que ya no es conocido, tiene algunas modificaciones interesantes pero sencillas, por ejemplo:
  • En la función mostrarInicio() vemos que aparecen dos líneas de código nuevas, las cuales se encargan de  recoger en dos variables si ya ha sido enviado el formulario y de poner en lugar del campo como value del input el valor recogido, o en caso de que no haya nada poner el valor de cadena vacía.
$nombre = isset($_REQUEST["first"]) ? $_REQUEST["first"] : "";
$apellido = isset($_REQUEST["last"]) ? $_REQUEST["last"] : "";
  • En la función comprobarDatos() aparecen dos if, uno por cada campo del formulario y añadiendo al array de errores cada uno el error que puede incluir
  • Finalmente en respuesta se muestran los datos con el formato que deseemos de la forma habitual.

miércoles, 15 de octubre de 2014

PHP (06) Validaciones (02) Requiriendo números

Continuamos con las validaciones y vamos a considerar de base el código anterior sobre la combrobación de datos.
Ahora vamos a requerir que el valor introducido sea un número.
En el siguiente código veremos que es muy sencillo una vez que tenemos nuestro script:
<html>
 <head>
  <title>
  Comprobación de datos requeridos
  </title>
 </head>
 <body>
  <h1>Comprobación de datos requeridos</h1>
  <?php
  /*
  Comenzamos buscando si visto esta activo, y vamos llamando a las
  funciones correspondientes para controlar el formulario
  */
   $errors_array = array();
   if(isset($_REQUEST["visto" ])){
    comprobarDatos();
    if(count($errors_array) != 0){
     mostrarErrores();
     mostrarInicio();
    }
    else {
     respuesta();
    }
   }
   else {
    mostrarInicio();
   }
   /*
   Muestra el formulario
   */
   function mostrarInicio()
   {
    echo "<form method='post'>" ;
    echo "<p>¿Que edad tiene?</p>" ;
    echo "<input name='number' type='text'>" ;
    echo "<input type='submit' value='Enviar'>" ;
    echo "<input type='hidden' name='visto' value='already_seen'>" ;
    echo "</form>" ;
   }
   /*
   Comprueba que el campo de texto no este en blanco, de ser así introduce un mensaje
   en el array global
   */
   function comprobarDatos()
   {
    global $errors_array;
    if(strcmp($_REQUEST["number"], strval(intval($_REQUEST["number"])))) {
     $errors_array[] = "<font color='red'>Escriba su edad con números</font>" ;
    }
   }
   /*
   recoge los errores del array global, lo recorre y muestra su contenido
   */
   function mostrarErrores()
   {
    global $errors_array;
    foreach ($errors_array as $err){
     echo '<p>' . $err . '</p>';
    }
   }
   /*
   Muestra la respuesta del servidor cuando todo esta correcto
   */
   function respuesta()
   {
    echo "Su edad es de: ";
    echo $_REQUEST["number"];
   }
   ?>
 </body>
</html>

Si comparamos el código con el que ya conocíamos vemos que lo único que ha cambiado es el nombre de la variable que se recoge a la cual hemos llamado number, y tan solo en la función comprobar datos hemos cambiado la condición del if por:
if(strcmp($_REQUEST["number"], strval(intval($_REQUEST["number"]))))

Lo que hace esta condición es convertir el valor, recogido como una cadena, en un entero con la función intval para reconvertirla en una cadena de nuevo con strval, por otro lado con strcmp se compara la cadena recibida con la obtenida en los cambios y de este modo devuelve, 0 si son iguales, o 1 si no son iguales, en cuyo caso se ejecuta el código introduciendo el error en la matriz de errores.

Como se puede observar es tan solo una adaptación de nuestro anterior script sin mayor complicación.