viernes, 10 de octubre de 2014

Recuperando permisos de / en linux

Hola,
hoy en la nueva sección "la cagué" (xDDD)..... na enserio, supongamos que por algún motivo se nos fue el chmod 777 -R / y peor aun como root D: creo que quienes lo hemos hecho sabemos los problemas que nos dará el sistema si no inmediatamente, si cuando reiniciemos.
Pues bien en este articulo espero dar al menos una pequeña opción de como podríamos recuperar dichos permisos si no del todo correctos al menos que nos deje funcionales para correr los servicios fundamentales temporalmente mientras vamos echando mano a lo que aun queda con secuelas (jejej).
Dejo una imagen de la cual me referiré el resto del articulo:
Ejemplo de uso con carpetas de prueba
Ejemplo de uso con carpetas de prueba (en rojo los pasos enumerados)
root1: Máquina "sana" o sea con los permisos por default o como vienen del sistema.
root2: Máquina que afectamos con el chmod

domingo, 28 de septiembre de 2014

[Parte 10] PHP

PHP es un tanto inusual como lenguaje este puede ser utilizado tanto como procedimiento como lo hemos venido viendo hasta ahora, y como programacion orientada a objetos (POO). Hay meritos a cuanto enfoques, y uno debe estar familiarizado con ambos, eventualmente con el tiempo.

El PHP orientado a objetos requiere mucho tiempo e informacion por lo cual veremos algo breve con lo cual podremos trabajar un poco con el. 

Sintaxis y fundamentos

Si nunca antes ha hecho alguna aplicacion realizada en enfoque de programacion orientada a objetos, tanto el concepto y la sintaxis le van a parecer bastante extraños. Simplemente poner todas las aplicaciones o scripts, significa tomar acciones con la informacion: validacion de ella, manipularla, almacenarla en una base de datos, y asi sucesivamente. Filosoficamente, la programacion de procedimiento esta escrito en enfoque a las acciones: hacen esto, entonces esto, entonces esto, la programacion orientada a objetos es centrada a datos, centrandose mas en los tipos de informacion que utiliza.

Fundamentos de POO

Programacion orientada a objetos comienza con la definicion de una clase, que es una plantilla para un tipo particular de datos: un empleado, un usuario, una pagina de contenido, y asi sucesivamente. Una definicion de clase contiene ambas variables y funciones. Sintacticamente una variable en una definicion de clase se llama atributo o propiedad, y una funcion en una definicion de una clase se llama un metodo. Combinados los atributos y metodos son los miembros de la clase. Como ejemplo teorico, es posible que tenga una clase llamada Coches. Tenga en cuenta que los nombres de las clases convencionalmente deben comenzar con una letra mayuscula. Las propiedades de una clase serian incluir marca, modelo, año, odometro, etcetera: toda la informacion que pueda ser conocida sobre un coche. Las propiedades de un coche pueden ser establecidas, cambiando y recuperando y los valores de las propiedades que pueden distinguir un coche de otro coche. Los metodos de un coche son las cosas que el coche puede hacer: Arrancar(), Estacionarse(), Apagar(), Manejarse(). Estas acciones son comunes en todos los coches. 

La reutilizacion de codigo particularmente codigos creados por otros, es uno de los beneficios clave de la programacion orientada a objetos. Que en realidad requiere mucho esfuerzo, por lo menos hacerlo bien, es dominar el proceso de diseño: entender los miembros para definir y mas importante la forma de aplicar conceptos POO sofisticadas tales como:

* Herencia
* Control de Acceso
* Resolucion de alcance
* Abstraccion
* Y asi sucesivamente

Sintaxis en POO

Digamos que alguien ya ha pasado por el proceso de diseño y definicion de una clase. La mayoria de las clases no se utilizan directamente, mas bien se crea una instancia de esa clase, un tipo de variable especifica de la clase. Esa instancia es llamada Objeto, en PHP se crea una instancia utilizando la palabra clave new:

$obj = new NombreClase();
$mio = new Coche();

Mientras que el codigo $nombre = 'Larry'; crea una variable de tipo string, el codigo anterior crea una variable de tipo Coche.
Todo eso es parte de la definicion de la clase Coches. Cada propiedad (es decir, variables) y metodo (es decir, funcion) es incrustado en la variable $mio. Detras de las escenas (es decir, la definicion de la clase), un metodo especial llamado constructor se invoca automaticamente cuando un nuevo objeto de este tipo es generado. El constructor normalmente ofrece la configuracion inicial que seria requerido por la siguiente el uso de este objeto. Por ejemplo, en una clase MySQLi establecer un constructor una coneccion para la base de datos y el constructor de la clase DateTime creando referencia a la hora y fecha exacta.

Si el constructor toma argumentos como cualquier funcion, los puede proporcionar, cuando el objeto se crea:


$mio = new Coche('Honda','Fit',2008);
Una vez que tenga un objeto usted puede referirse a sus propiedades (variables) y llamar a sus metodos (funciones), utilizando la sintaxis:

$objeto_nombre->miembro_nombre;
$mio->color = 'Lila';
$mio->Arrancar();
La primera linea teoricamente asigna el valor Lila a la propiedad color del objeto. La segunda linea invoca el metodo Arrancar(), como a cualquier funcion que llamamos se requieren los parentesis. Si el metodo toma argumentos se los podemos asignar tambien:

$mio->Manejarse('adelante');
A veces vamos a usar un objeto y podemos manejar sus propiedades como lo hariamos con cualquier otra variable:

$mio->odometro += 20;
echo "Mi carro actualmente contiene $mio->odometro de millas en el odometro";

 

Programacion orientada a objetos VS programacion de procedimiento

Las discusiones en cuanto a los meritos de la programacion orientada a objetos frente a la programacion de procedimiento puede escalar verbalmente a guerras, con cada lado ferozmente a la defensa de su enfoque. PHP es el unico que tiene una opcion (por comparacion el lenguaje C es estrictamente lenguaje procedural, y Java orientado a objetos) en mi opinion cada estilo tiene sus fortalezas y debilidades pero tampoco es "mejor" que la otra. Programacion de procedimiento es posiblemente mas facil de aprender y utilizar especialmente para proyectos mas pequeños, pero el codigo de procedimiento puede ser mas dificil de mantener y ampliar, sobre todo en sitios mas complicados y tiene el potencial de ser buggier.
El codigo escrito usando programacion orientada a objetos, por otro lado, puede ser mas facil de mantener, especificamente en proyectos mas grandes, y puede ser mas apropiado en entornos de grupo. Pero programacion orientada a objetos puede ser mas dificil de dominar, y cuando no se hace bien, es mucho mas dificil de remediar. Con el tiempo ya llegaran sus propias opiniones y preferencias. La verdadera leccion para mi es aprovechar que PHP permite ambas sintaxis y no limitarse a un solo estilo sin importar la situacion.
 

Para ver como se pone en practica el uso de PHP POO puedes ver el tutorial: http://arthusu.blogspot.mx/2013/08/tutorial-pdo-mysql.html de manera que estamos utilizando PHP POO en el uso de PDO. 
 

Cosas utiles a saber:

El operador de resolucion de ambito (tambien denominado Paamayim Nekudotayim) o en terminos simples, el doble dos puntos, es un token que permite acceder a elementos estaticos, constantes, y sobrescribir propiedades o metodos de una clase:

$nombredeclase::VALOR_CONSTANTE;

Aqui termina la parte 10 de PHP y como dijimos al inicio, esto no es mas que lo mas breve posible ya que PHP orientado a objetos es mucho mas extenso de lo que llevaria varias partes para poder explicarlo completamente. Espero que les haya sido util esta parte.
 
 
 

sábado, 27 de septiembre de 2014

[Parte 9] PHP

Introduccion a Jquery

Para poder entender Jquery deberias ya de tener antes algun conocimiento solido de Javascript, Javascript es el primero en agregar contenido dinamico a una pagina web, con la diferencia de que PHP es del lado del servidor y Javascript del lado del cliente (Javascript ha comenzado a ser usado del lado del servidor pero todavia le falta mas). PHP precisamente por que es del lado del servidor no conoce del navegador y es posible que por ello algunos script arrojen diferentes resultados en diferentes navegadores. Por el contrario el codigo javascript puede ser personalizado para la variacion de navegadores. Superar este obstaculo es una de las varias fuerzas de jquery (www.jquery.com).

Jquery es un framework de javascript, este framework solo es una libreria de codigo que simplifica y hace mas rapido el trabajo en javascript. El nucle de jquery es capaz de manejar todas las funcionalidades claves de javascript. El framework puede extenderse via plugins agregando otras caracteristicas tal como crear una tabla dinamica y ordenarla. Jquery tambien contiene una interface que te puede ser de mucha ayuda (www.jqueryui.com).

Hay muchos frameworks javascript fuera de este, esto no quiere decir que jquery sea el mejor. Sin embargo es facil de aprender y ademas puedes manejar el DOM (Document Object Model) a tu antojo. El dom es para referirse a los elementos de la pagina, ya sea guardar valores de algun formulario, agregar o quitar cualquier elemento HTML, cambiar las propiedades de tales, y demas.

Antes de comenzar a utilizar Jquery debes comprender que Jquery es un framework de javascript, significa que lo siguiente que veremos sera un poco de Javascript, javascript es un poco similar a php de alguna forma y de otra forma no tal como las variables son creadas, la concatenacion y demas. 

Un ejemplo de Javascript del lado del servidor es NodeJs (www.nodejs.com).

Una manera de saber si tenemos errores en Jquery es ver con el inspeccionador de elementos y en consola puedes ver que errores puede tener, chrome y firefox traen inspeccionador de elementos por defecto...



Incorporando Jquery

Jquery es un framework de codigo, atraves, en orden para usarlo, a una pagina web se le debe incorporar la libreria jquery.

Para incluir cualquier archivo externo en javascript en la pagina web implica la etiqueta script de HTML,proporcionando el nombre al archivo externo como valor del atributo src




<script src="archivo.js" type="text/javascript" charset="utf-8"></script>

El archivo jquery deberia ser nombrado de esta forma: jquery.x-y-x.js donde xyz es el numero de version. La parte min del nombre del archivo indica que el archivo javascript ha sido minificado. La minificacion es remover espacios, nuevas lineas, y comentarios desde el codigo, el resultado es apenas legible, pero es completamente funcional. El beneficio de minificar el codigo es que el archivo carga mas rapido en el navegador por que tiene menos peso.

Los pasos a seguir para incorporar jquery al navegador son los siguientes:

1.- nos dirigimos a www.jquery.com
2.- damos clic en download jquery y elegimos la ultima version en produccion
3.- guardamos el archivo en nuestra computadora
4.- movemos el archivo jquery a el directorio web y lo colocamos dentro de una carpeta donde se encuentren todos nuestros archivos javascript, normalmente yo creo una llamada js
5.- creamos una estructura HTML y en el head incluimos nuestro archivo jquery (prueba.html):



<!DOCTYPE html>
<html>
<head>
 <title>Jquery</title>
 <script src="js/jquery-2.1.1.min.js" type="text/javascript"></script>
</head>
<body>

</body>
</html>


Muchas veces utilizamos jQuery de manera continua en nuestra pagina web, si estamos utilizando un hosting gratis esto generara muchas peticiones a ese mismo archivo, lo mejor es que lo hagas desde un archivo externo, algunas paginas como son Google o Microsoft tienen sus CDN (red de entrega de contenidos) de manera que podemos usar sus enlaces gastando menos ancho de banda en nuestro servidor, un ejemplo utilizando google CDN, seria de la siguiente manera:

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Usando Jquery

Una vez que ya has incorporado correctamente jquery en tu pagina web, tu puedes comenzar a usarlo. Jquery, o cualquier codigo javascript, puede ser escrito en medio de las etiquetas abrir y cerrar de script.

<script type="text/javascript">//el codigo va aqui</script>

(Nota que en javascript la doble barra crea un comentario al igual que en PHP). 

Alternativamente tu puedes incluir un archivo externo utilizando codigo jquery y la liberia jquery arriba de el llamado, puedes incluir multiples archivos externos y el navegador los leera siempre que esten en la etiqueta script. 

Un problema que no encontramos es que si llamamos al DOM desde el archivo que contenga jquery analizara primero el archivo jquery que esta dentro de la etiqueta script que antes de haber cargado el DOM, para ello debemos estar seguros de que la pagina ha sido cargada y podemos utilizar el siguiente codigo javascript:

window.Onload o simplemente utilizando jquery:
$(document).ready(alguna_funcion);

La sintaxis de jquery puede parecer extraña para los iniciados es por eso que vamos a explicar el codigo:

$(document), con $ hacemos referencia a una parte del documento en este caso document que hace referencia a todo el documento de la pagina web.
Con ready(), vemos si el documento esta listo y si es asi ejecutamos alguna_funcion().

Una alternativa para esta sintaxis es utilizar una funcion anonima sin definir el nombre de tal (en PHP tambien es posible pero no es muy comun utilizarla), para utilizar una funcion anonima es de la siguiente manera:

$(document).ready(function(){ // codigo a ejecutar });

Ya que se necesita mucho este tipo de funcion en jquery, para verificar si el dom esta cargado, sea ha creado una sintaxis mas corta de manera de no alargar tanto el codigo fuente:

$(function(){});

Para probar jquery vamos a crear una simple alerta cuando el documento haya sido cargado mostraremos la alerta.

1.- creamos un archivo llamado prueba.js
2.- creamos la alerta, con el siguiente codigo: 
$(function(){
    alert('Listo!')
});

la funcion alert() muestra una caja con nuestro mensaje como argumento.
3.- guardamos el archivo .js en nuestra carpeta js en el directorio web
4.- abrimos el archivo con el codigo prueba.html haciendo referencia a el:



Notas:

El codigo $() es una abreviatura para llamar a la funcion jQuery() 

Seleccionando elementos de la pagina

Una vez que sabe la funcionalidad basica de jQuery, el siguiente paso a aprender es como seleccionar los elementos de la pagina. Al ser capaz de hacerlo le permitira ocultar y mostrar imagenes o bloques de texto, manipular formularios y mas. Ya has visto como seleccionar el documento web de la pagina: $(document). Para seleccionar otros elementos de la pagina, podemos usar selectores CSS en lugar de document.

* #algo selecciona el elemento con un id de valor de algo
* .algo selecciona cada elemento con una valor de clase de algo
* algo selecciona todos los elementos de algo escrito (por ejemplo: p selecciona todos los parrafos)

Estas tres reglas son mas que suficientes para comenzar pero a diferencia de el document estas deben ir colocadas entre comillas. 
Por ejemplo, el codigo $('a') selecciona cada enlace de la pagina, y $('#caption') selecciona cada elemento con el id caption, para hacer referencia a elementos individuales en la pagina #algo es la solucion mas facil.

Estas reglas pueden ser combiandas tambien:

* $('img.paisaje') selecciona cada imagen con la clase paisaje
* $(#registrar input) selecciona cada elemento input que encuentre con el id registrar 


Manejo de eventos

Javascript al igual que PHP se utiliza a menudo para responder a eventos, en terminos de javascript los eventos son las acciones del usuario dentro del navegador web, como por ejemplo:

* al mover el cursor sobre una imagen o parte del texto
* hacer clic en un enlace
* cambiar el valor de un elemento del formulario
* el envio de un formulario

Para controlar los eventos en javascript, debemos aplicar un detector de eventos (event listener) tambien llamado manejador de eventos a un elemento, es decir, cuando sucede un evento en el elemento B llamar a la funcion C. En jQuery los detectores de eventos son asignados utilizando la siguiente sintaxis:

seleccion.Tipodeevento(function)

La parte seleccion seria como $('.algo') o $('a') o lo que sea, elemento o elementos a los que el controlador de eventos debe aplicarse. El valor Tipodeevento sera diferente a la base seleccion. Los valores comunes son change, mouseover, click, submit, y seleccionar diferentes eventos que pueden ser activados por diferentes elementos del HTML. Comunmente la funcion es llamada en una sola linea anonimamente. Por ejemplo para manejar el evento de una imagen donde pasan el cursor sobre ella:

$('img').mouseover(function(){ // hacer algo })

Con el fin de hacer una calculadora de IVA necesitamos saber una cosa mas, en busca de los valores introducidos en los inputs requerimos la funcion val(). Que devuelve el valor de la seleccion.

calc.html

<!DOCTYPE html>
<html>
<head>
 <title>Calculador IVA</title>
 <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
 <script type="text/javascript" src="js/calculador.js"></script>
</head>
<body>
 <form action="" method="post" id="calculator">
  <p>Precio: <input type="text" name="precio" id="precio"></p>
  <p><input type="submit"></p>
 </form>
</body>
</html>


calculador.js


// si el documento esta listo
$(function(){
 // si se envio el formulario
 $('#calculator').submit(function(){
   precio = $('#precio').val();
   resultado = precio * 0.16;
   alert(resultado);
   return false;
 }) // fin del envio del formulario
}) // fin de la lectura del documento web

Lo unico que hacemos es enviar un precio y nos saca el iva que es el 16% del precio real, en este caso enviamos el precio y no los muestra en una ventana de alerta, al final retornamos falso para que el formulario no sea enviado.


Manipulacion del DOM

Uno de los usos mas criticos de javascript, y en jQuery en particular es la manipulacion del DOM, cambiar de cualquier manera el contenido del navegador web. Normalmente la manipulacion del DOM se manifiesta por alterar lo que el usuario ve, la facilidad con la que jQuery puede hacer esto es una de sus fortalezas.

Una vez que haya seleccionado el elemento o elementos para ser manipulados, para comenzar la funcion hide() y show(), ocultar y mostrar, nos sirven por ejemplo si tenemos un formulario el cual queremos ocultar cuando la informacion haya sido enviada, se podria hacer de la siguiente manera:

$('#FormularioÁctual').hide();

La funcion toggle(), cuando es llamada alterna entre mostrar y ocultar, si el elemento esta visible lo oculta y si esta oculto lo hace visible.

Similar a show() y hide() estan las funciones fadeIn() fadeOut(). Estas funciones tambien muestran y ocultan la seleccion solo que con un poco de efecto dentro.

Otra forma de impactar el DOM es cambiar las clases CSS que se aplican a una seleccion. La funcion addClass() aplica una clase CSS y removeClass() quita una clase. El codigo siguiente agrega una clase de enfasis a un bloque individual y la elimina de todos los parrafos:

$('#bloqueID').addClass('enfasis');
$('p').removeClass('enfasis');

La funcion toggleClass() alterna la aplicacion de CSS para una clase en la seleccion.

Las funciones mencionadas anteriormente cambian las propiedades de los elementos de la pagina, pero tambien se puede cambiar el contenido de los elementos. Anteriormente utilizamos val() que devuelve el valor de un elemento de formulario, pero cuando se le proporciona un argumento val() asigna un nuevo valor al elemento del formulario:

$('#algo').val('gato');

Del mismo modo la funcion html() devuelve el contenido html de un elemento y text() devuelve el contenido textual ambas funciones pueden tomar argumentos para asignar nuevo html o texto, en consecuencia.

Veamos un ejemplo del calculador del IVA agregando algunas clases y estilos:

calc.html

<!DOCTYPE html>
<html>
<head>
 <title>Calculador IVA</title>
 <style type="text/css">
  .error{
   text-align: center;
   width: 250px;
   height: 50px;
   background-color: yellow;
   border-style: solid;
   border-color:black;
   font-family: arial;
   font-weight: bold;
   font-size: 17px;
   color: red;
  }
  .correcto{
   text-align: center;
   width: 250px;
   height: 50px;
   background-color: yellow;
   border-style: solid;
   border-color:black;
   font-family: arial;
   font-weight: bold;
   font-size: 17px;
   color: green;
  }
 </style>
 <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
 <script type="text/javascript" src="js/calculador.js"></script>
</head>
<body>
 <form action="" method="post" id="calculator">
  <p id="result"></p>
  <p>Precio: <input type="text" name="precio" id="precio"></p>
  <p><input type="submit"></p>
 </form>
</body>
</html>



calculator.js



// si el documento esta listo
$(function(){
 $('#result').hide();
 // si se envio el formulario
 $('#calculator').submit(function(){
   if ($('#precio').val() >= 100) {
    precio = $('#precio').val();
    resultado = precio * 0.16;
    $('#result').show();
    $('#result').removeClass('error');
    $('#result').addClass('correcto').text(resultado);
   }else{
    $('#result').show();
    $('#result').removeClass('correcto');
    $('#result').addClass('error').text('El precio debe ser igual o mayor a $100');
   }
   return false;
 }) // fin del envio del formulario
}) // fin de la lectura del documento web



Algunas notas importantes:

jQuery no genera un error si trata de seleccionar elementos de la pagina que no existen, tampoco si llama una funcion a un elemento que no existe.

En javascript como en otros lenguajes de programacion orientado a objetos, usted puede llamar a las funciones en "cadenas" juntos, la realizacion de multiples funciones en el mismo tiempo. Un ejemplo de esto se puede hacer modificando nuestro script de javascript anterior calculator.js:

// si el documento esta listo
$(function(){
 $('#result').hide();
 // si se envio el formulario
 $('#calculator').submit(function(){
   if ($('#precio').val() >= 100) {
    precio = $('#precio').val();
    resultado = precio * 0.16;
    $('#result').show().removeClass('error').addClass('correcto').text(resultado);
   }else{
    $('#result').show().removeClass('correcto').addClass('error').text('El precio debe ser igual o mayor a $100');
   }
   return false;
 }) // fin del envio del formulario
}) // fin de la lectura del documento web

Tambien puedes cambiar los atributos de una seleccion utilizando la funcion attr() el primer argumento y el elemento seleccionado se vera afectado, el primer argumento es el atributo y el segundo valor es el valor, un ejemplo desabilitando un boton seria:

$('#submitButton').attr('disabled','disabled');

Tu puedes añadir, mover o eliminar elementos utilizando las funciones prepend(), append(), remove() y otras funciones. Para mas informacion sobre esta y otras funciones podemos consultar la documentacion de jQuery: http://api.jquery.com/.

Usando Ajax

Junto con la manipulacion del DOM, otro uso clave de Javascript y jQuery es Ajax. 

Ajax es simplemente el uso de javascript para realizar una peticion al servidor sin conocimiento del usuario. Estas aplicaciones se ejecutan en el cliente, es decir, en el navegador de los usuarios mientras se mantiene la comunicacion asincrona con el servidor en segundo plano. De esta forma es posible realizar cambios sobre las paginas sin necesidad de recargarlas, mejorando la interactividad, velocidad, y usabilidad en las aplicaciones. 

Vamos a crear un archivo el cual valide nuestro inicio de sesion utilizando ajax, en este caso no utilizaremos base de datos ni tampoco sesiones ya que solo es una simple prueba.

Primero que nada crearemos un archivo login.php el cual contendra el formulario para iniciar sesion, algunos mensajes de error, y un parrafo donde mostrara el resultado para cada cosa...

login.php


<!DOCTYPE html>
<html>
<head>
 <title>Iniciar sesion</title>
 <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
 <script type="text/javascript" src="login.js"></script>
</head>
<body>
 <h1>Iniciar sesion</h1>
 <p id="results"></p>
 <form action="login.php" method="post" id="login">
  <p id="emailP">Correo electronico: <input type="text" name="email" id="email" /></p><span class="errorMessage" id="emailError">Por favor coloque su correo electronico</span>
  <p id="passwordP">Clave: <input type="password" name="password" id="password" /></p><span class="errorMessage" id="passwordError">Por favor coloque su clave</span>
  <p><input type="submit" id="submit" name="submit" value="Iniciar Sesion!" /></p>
 </form>
</body>
</html>

Explicando un poco el codigo:

1.- Agregamos jquery CDN de google y tambien llamamos a un archivo externo llamado login.js 
2.- creamos un parrafo con el id results el cual contendra los resultados
3.- creamos un formulario, el cual contiene algunos mensajes de errores que estaran ocultos.

El segundo archivo es de validacion:

login_ajax.php

<?php
 if (isset($_GET['email']) && isset($_GET['password'])) {
  if (filter_var($_GET['email'],FILTER_VALIDATE_EMAIL)) {
   if (($_GET['email'] == 'email@example.com') && ($_GET['password'] == 'testpass')) {
    echo "Correcto";
   }else{
    echo "Incorrecto";
   }
  }else{
   echo "Email invalido";
  }
 }else{
  echo "Incompleto";
 }
?>


1.- validamos si el correo y la clave existen y sino es asi mostramos un mensaje diciendo que esta incompleto
2.- validamos el email, si es correcto podremos proceder, sino decimos que el Email invalido
3.- Si todo esta bien mostrara un mensaje donde dira que es correcto pero si no es asi mostrara un mensaje diciendo que es incorrecto

En este caso nuestras credenciales se encuentran en el mismo php y son para email: email@example.com y para password: testpass

Por ultimo vamos a crear nuestro script de javascript login.js el cual contendra el codigo para enviar nuestro formulario por medio de ajax, en este caso vamos a crear unos objetos antes de eso veremos un poco sobre esto.

En este caso crearemos dos objetos, uno va a representar los datos que vamos a enviar, y el segundo va a representar las opciones para la peticion. Para crear un objeto utilizamos la siguiente sintaxis:

var nombredeobjeto = new Object();
Una vez creado el objeto podemos crear valores para el mismo, utilizando la siguiente sintaxis:

nombredeobjeto.propiedad = valor;
Si eres nuevo en Programacion orientada a objetos en javascript puedes pensar que el objeto generico es como un array con sus indices, con nombre y valor correspondientes. La segunda nueva pieza de informacion es el uso de la funcion de jQuery ajax() esta funcion realiza una peticion ajax, toma como unico argumento la configuracion de la solicitud, siendo parte de la libreria jQuery se invoca asi:

$.ajax(configuracion);
Ya hecho esto vamos a ver el codigo y explicar un poco de el:


$(function(){

 // ocultamos todos los mensajes de error
 $('.errorMessage').hide();

 $('#login').submit(function(){

  var email, password;

  if ($('#email').val().length >= 6) {
   email = $('#email').val();
   $('#emailP').removeClass('error');
   $('#emailError').hide();
  }else{
   $('#emailP').addClass('error');
   $('#emailError').show();
  }

  if ($('#password').val().length > 0) {
   password = $('#password').val();
   $('#passwordP').removeClass('error');
   $('#passwordError').hide();
  }else{
   $('#passwordP').addClass('error');
   $('#passwordError').show();
  }

  if (email && password) {
   var data = new Object();
   data.email = email;
   data.password = password;

   var options = new Object();
   options.data = data;
   options.dataType = 'text';
   options.type = 'get';
   options.success = function(response){
    if (response == 'Correcto') {
     $('#login').hide();
     $('#results').removeClass('error');
     $('#results').text('Ahora has iniciado sesion');
    }else if(response == 'Incorrecto'){
     $('#results').text('No coinciden las credenciales enviadas');
     $('#results').addClass('error');
    }else if(response == 'Incompleto'){
     $('#results').text('Por favor llene los campos');
     $('#results').addClass('error');
    }else if(response == 'Email invalido'){
     $('#results').text('Por favor ponga un correo valido');
     $('#results').addClass('error');
    }
   } // fin de success
   options.url = 'login_ajax.php';
   $.ajax(options);
  } // fin de email y password if
  //para prevenir que se envie el formulario
  return false;
 });

});

Explicando el codigo:

1.- Verificamos que el documento este complementamente cargado utilizando $(function(){})
2.- ocultamos todos los mensajes de error 
3.- creamos un evento de escucha para cuando el formulario sea enviado
4.- inicializamos las variables email y password
5.- validamos el email tiene que contener un tamaño de 6 caracteres como minimo, si es asi quitamos los errores y lo guardamos en la variable email y sino mostramos los errores
6.- validamos la password que tiene que contener mas de 0 caracteres como minimo, si es asi quitamos los errores y lo guardamos en la variable password y sino mostramos los errores 
7.- si recibimos ambos valores, creamos un nuevo objeto data donde guardaremos los datos que fueron enviados desde el formulario. Para que se entienda en terminos equivalentes a PHP esto seria algo como:

$data = array();
$data['email'] = $email;
$data['password'] = $password;

8.- Creamos otro nuevo objeto de opciones en el cual hay una opcion data a la cual le asignamos el objeto que habiamos creado anteriormente. Luego creamos algunas otras propiedades como el tipo de dato que sera arrojado el cual sera de tipo texto y la forma en que sera enviado que es por el metodo get.

9.- Dependiendo de la respuesta que nos de que sera de tipo texto, vamos a crear diferentes cosas, como mostrar errores, de si el correo es incorrecto, que faltan datos por llenar, o que se ha iniciado sesion correctamente.


Algunos tips:


Correr el script PHP directamente para hacer un debug en caso de que suceda un error.

Desde el complemento firebug de firefox se puede ver la peticion enviada por metodo get:


Si desabilitan el javascript del navegador todo esto no tendra efecto alguno.

Hasta aqui terminamos la novena parte de PHP, en este caso no se vio mucho de PHP se vio mas de jQuery esto lo hicimos para llegar a Ajax y como podemos implementar la tecnologia Javascript y PHP juntos de manera que realicen un trabajo mas interactivo en la pagina web.

viernes, 19 de septiembre de 2014

[Parte 8] PHP

En este apartado vamos a hablar un poco sobre metodos de seguridad para nuestros scripts php, aunque no hablaremos mucho sobre el tema por que en este mismo blog puedes encontrar una recopilacion donde nos adentramos mas profundamente en el:

Seguridad en PHP:

http://arthusu.blogspot.mx/2014/02/parte-1-seguridad-en-php.html
http://arthusu.blogspot.mx/2014/03/parte-2-seguridad-en-php.html
http://arthusu.blogspot.mx/2014/03/parte-3-seguridad-en-php.html
http://arthusu.blogspot.mx/2014/03/parte-4-seguridad-en-php.html
http://arthusu.blogspot.mx/2014/04/parte-5-seguridad-en-php.html
http://arthusu.blogspot.mx/2014/04/parte-6-seguridad-en-php.html
http://arthusu.blogspot.mx/2014/04/parte-7-seguridad-en-php.html
http://arthusu.blogspot.mx/2014/04/parte-8-seguridad-en-php.html
http://arthusu.blogspot.mx/2014/04/parte-9-seguridad-en-php.html
http://arthusu.blogspot.mx/2014/04/parte-10-seguridad-en-php.html
http://arthusu.blogspot.mx/2014/04/parte-11-seguridad-en-php.html


Validando los datos por tipo

Para la mayor parte, toda la validacion de los scripts php que hemos hecho hasta ahora debe estar al minimo, incluso nisiquiera verificamos si la variable tiene algun valor o esta vacia, en varias situaciones esto es lo mejor que puedes hacer. Por ejemplo, no hay una regla perfecta para validar la direccion o un comentario de un usuario, se puede lograr algo un poco mas sofisticando utilizando expresiones regulares (http://arthusu.blogspot.mx/2013/07/phpexpresiones-regulares-pcre.html), en este caso seria mejor validar el dato por tipo. 

PHP soporta varios tipos de datos: cadenas, numeros (enteros o decimales), arrays y mas. Para cada uno de estos existe una funcion especifica para ver si una variable es de ese tipo de dato. 

is_array() - checa si es un array
is_bool() - checa si es booleano (TRUE o FALSE)
is_float() - checa si es decimal
is_int() - checa si es entero
is_null() - checa si es valor nulo (NULL)
is_numeric() - checa si es numerico
is_resource() - checa si es un recurso (por ejemplo: la coneccion a la base de datos)
is_string() - checa si es una cadena

Hay una gran parte basada en la validacion: ya sea validar por URL, cookies, formularios, datos que van fuera del servidor, a la base de datos, hay dos tipos de validaciones: lista blanca y lista negra, un ejemplo podria ser para prevenir el spam o para prevenir groserias, podriamos usar una lista negra y reemplazar esa palabra por otro o simplemente taparla (****).

Un ejemplo, podriamos hacer una calculadora que solo sume:


<form method="post">
 numero 1: <input type="text" name="n1" /><br>
 numero 2 <input type="text" name="n2" /><br>
 <input type="submit" name="enviar" />
</form>

<?php
 if (isset($_POST['enviar']) && is_numeric($_POST['n1']) && is_numeric($_POST['n2'])) {
  $n1 = $_POST['n1'];
  $n2 = $_POST['n2'];

  $result = $n1 + $n2;

  echo $result;
 }
?>


Usando la extension Filter

Introducido en PHP 5.2 Filter Extension es una importante herramienta, esta puede ser utilizada para dos propositos: validar o desinfectar. Un proceso de validacion confirma que los datos coincidan con lo esperado. Y la desinfeccion en comparacion altera los datos eliminando los caracteres inapropiados.

La funcion mas importante en la exntesion filter es  filter_var():

filter_var(variable,filter,[options]);
El primer argumento es la variable a ser filtrada, el segundo es el filtro a aplicar, el tercero es para agregar criterios adicionales.

Filtros de validacion

Constante:
FILTER_VALIDATE_BOOLEAN
FILTER_VALIDATE_EMAIL
FILTER_VALIDATE_FLOAT
FILTER_VALIDATE_INT
FILTER_VALIDATE_IP
FILTER_VALIDATE_REGEXP
FILTER_VALIDATE_URL


Filtros de desinfeccion

Constante:
FILTER_SANITIZE_EMAIL
FILTER_SANITIZE_ENCODED
FILTER_SANITIZE_MAGIC_QUOTES
FILTER_SANITIZE_NUMBER_FLOAT
FILTER_SANITIZE_NUMBER_INT
FILTER_SANITIZE_SPECIAL_CHARS
FILTER_SANITIZE_STRING
FILTER_SANITIZE_STRIPPED
FILTER_SANITIZE_URL
FILTER_UNSAFE_RAW

Por ejemplo, para confirmar que la variable sea un valor decimal:

if(filter_var($var,FILTER_VALIDATE_FLOAT)){
Un ejemplo que contenga valores opcionales podria ser el uso de FILTER_VALIDATE_INT la cual contiene min_range y max_range para controlar el minimo y maximo de valores permitidos. Viendolo en un ejemplo podria ser el siguiente:

if(filter_var($var,FILTER_VALIDATE_INT,array('min_range'=>1,'max_range'=>120))){

Hay varios filtros duplicados a funciones php. Por ejemplo: 
 

FILTER_SANITIZE_MAGIC_QUOTES es lo mismo que addslashes()
FILTER_SANITIZE_SPECIAL_CHARS es lo mismo que htmlspecialchars()
FILTER_SANITIZE_STRING es lo mismo que strip_tags()


Bueno otro tema que voy a tocar asi rapido de pasadita por que en las partes de seguridad en php se hablo mucho de ello es la proteccion contra sql injection tambien hay un tutorial de la libreria pdo en este mismo sitio.

Prevenir ataques de inyeccion SQL


En este caso utilizaremos declaraciones preparadas o preparated statements... esto lo que tiene de bueno es que son mas rapidas y mas seguras.

Las declaraciones preparadas pueden ser creadas en cualquier peticion SELECT, INSERT, UPDATE, DELETE. Comenzamos definiendo nuestra consulta marcando los placeholders:

$q = "SELECT first_name,last_name,email FROM users WHERE id=?";

Asignamos los resultados en una variable de PHP:

$stmt = mysqli_prepare($dbc,$q);
En este punto mysqli parsea la consulta pero no la ejecuta. El siguiente punto es enlazar las variables de la consulta con los placeholders:

mysqli_stmt_bind_param($stmt, 'i', $id);

La parte de i indica el valor a ser esperado.
 
Tipos de valores:

d - decimal
i - entero
b - blob (datos binarios)
s - todos los otros tipos
Un ejemplo utilizando el script de las sesiones donde iniciabamos una sesion, podria ser como la siguiente consulta:

$q = "SELECT user_id,first_name FROM users WHERE email=? AND pass=SHA1(?)";

$stmt = mysqli_prepare($dbc,$q);
mysqli_stmtm_bind_param($stmt, 'ss',$e,$p);
$e = 'correo@ejemplo.com';
$p = 'miclave';
mysqli_stmt_execute($stmt);

Para cerrar la declaracion utilizamos:

mysqli_stmt_close($stmt);

Evitar ataques de fuerza bruta


Este tambien se comenta en las partes de seguridad de php, pero solo vamos a comentar que este tipo de ataques se puede detener ya que la mayoria de las personas la realizan desde la misma IP, con lo cual despues de varios intentos le hacemos un delay (esperar) tantos segundos cada peticion esto lo hacemos con el uso de la funcion sleep() en PHP.

Si te parece interesante esto de los filtros o validacion de tipo de datos pueden adentrarte a algo mas complejo como son las expresiones regulares, de manera que encuentres lo que deseas:

http://arthusu.blogspot.mx/2013/07/phpexpresiones-regulares-pcre.html


Hasta aqui llega esta parte que parece ser la mas corta pero en realidad no lo es ya que tambien se encuentran las partes de seguridad en php al inicio del post.

jueves, 18 de septiembre de 2014

[Parte 7] PHP

Cookies y Sesiones

Http es un protocolo sin estado por lo cual no puede identificar que usuario es cual, ni darle seguimiento. En PHP existen dos herramientas para este proposito las cookies y las sesiones, con las cuales podemos identificar al usuario y darle seguimiento.

Las diferencias entre las cookies y las sesiones es que las cookies se guardan en el navegador del cliente y las sesiones se guardan en el servidor. Las sesiones son generalmente mas seguras que las cookies y pueden almacenar mucha mas informacion. Ambas son tecnologias faciles de utilizar usando PHP para demostrarlo crearemos un sistema de inicio de sesion.

Crear una pagina de inicio de sesion

El proceso de inicio de sesion envuelve algunos componentes:

* Un formulario envia la informacion de inicio de sesion
* Una rutina de validacion se asegura de que los datos necesarios se han enviado
* Una consulta a la base de datos compara que la informacion enviada sea igual a la informacion almacenada en la base de datos
* Las cookies o sesiones son almacenadas reflejando un inicio de sesion correcto

Subsecuente a esto las paginas pueden tener una restriccion por la cual solo se mostraran a usuarios que hayan iniciado sesion, en las cuales pueden agregar caracteristicas especiales.

Crearemos varios archivos rompiendo la logica y haciendola mas facil para que nuestro codigo sea mas facil de escribir y leer y tenga menos redundancia. El script va contener la pagina de inicio de sesion, la cabecera, el reporte de errores, el formulario y el pie de pagina.

Creamos la pagina de inicio de sesion:

login _page.inc.php



<?php
 # Esta pagina imprime cualquier error y esta asociado con la pagina de inicio
 # Y crea la pagina de inicio de sesion entera, incluyendo el formulario.

 # incluir la cabecera
 $page_title = 'Inicio de sesion';
 include('includes/header.html');

 # Imprime cualquier mensaje de error, si existe:
 if (isset($errors) && !empty($errors)) {
   echo '<h1>Error!</h1>
   <p class="error">Los siguientes errores han ocurrido:<br />';
   foreach ($errors as $msg) {
    echo "- $msg<br />\n";
   }
   echo "</p><p>Por favor intente de nuevo.</p>";
  } 

  # Mostrar el formulario:
?>
<h1>Iniciar sesion</h1>
<form action="login.php" method="post">
 <p>Correo electronico: <input type="text" name="email" size="20" maxlength="60" /></p>
 <p>Clave: <input type="password" name="pass" size="20" maxlength="20" /></p>
 <p><input type="submit" name="submit" value="Iniciar sesion!" /></p>
</form>
<?php 
 include('includes/footer.html');
?>


1.- Incluimos el header.html y el titulo al inicio (el header.html lo veremos mas adelante)

2.- Si ocurre algun error imprimimos el error recorriendolo con foreach
3.- Mostramos el formulario
4.- Incluimos footer.html

Nota: estamos utilizando .inc.php para los archivos que iran dentro de otros archivos (seran incluidos), y tambien crearemos una carpeta llamada includes/ donde se encontraran cada uno de ellos.

En el proceso de la creacion de la pagina de inicio de sesion, hay 2 cosas que se repiten, las cuales son :

- Verificacion de correo electronico y clave en la base de datos
- Redirecciones

Es por eso que para comenzar crearemos un script php con el cual evitaremos la redundancia del codigo, nuestro script se llamara login_functions.inc.php:


<?php
 # Esta pagina define dos funciones usadas para el inicio y cierre de sesion
 /*
  Esta funcion determina la URL absoluta y redirige al usuario
  * Esta funcion toma un argumento para que sea redirigido
  * El argumento por defecto es index.php
 */
 function redirect_user ($page = 'index.php'){
  // comienza definiendo la url
  // la url es http:// agregando el nombre del host y el directorio actual
  $url = 'http://'.$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF']);

  // remueve cualquier barra invertida
  $url = rtrim($url,'/\\');

  // Agrega la pagina:
  $url .= '/' . $page;

  // Redirige al usuario:

  header("Location: $url");
  exit(); // Quita el script
 } // Fin de la funcion redirect_user()

 /*
  Esta funcion valida los datos del formulario (el correo electronico y la clave).
  * Si ambos estan presentes, la base de datos es consultada
  * La funcion requiere coneccion a la base de datos
  * La funcion devuelve un arrat de informacion, incluyendo:
   -  Una variable TRUE/FALSE que indica si fue correcto
   - Un array para los errores o resultados de la base de datos
 */
 function check_login($dbc,$email='',$pass=''){
  $errors = array(); // Inicializamos un array de errores

  // Validamos el correo electronico
  if (empty($email)) {
   $errors[] = 'Olvidastes poner el correo electronico';
  }else{
   $e = mysqli_real_escape_string($dbc,trim($email));
  }
  // Validamos la clave
  if (empty($pass)) {
   $errors[] = 'Olvidastes poner la clave';
  }else{
   $p = mysqli_real_escape_string($dbc,trim($pass));
  }

  if(empty($errors)){
   // Si todo esta bien
   // Devolvemos el id de usuario, el primer nombre de usuario con la combinacion de
   // correo electronico/clave

   $q = "SELECT user_id, first_name FROM login WHERE email='$e' AND pass=SHA1('$p')";
   $r = @mysqli_query($dbc,$q);
   // Correr la consulta
   // verificamos el resultado

   if (mysqli_num_rows($r) == 1) {
    // devolvemos los registros
    $row = mysqli_fetch_array($r,MYSQLI_ASSOC);
    // devuelve true y los registros:
    return array(true,$row);

   }else{ // No coincide
    $errors[] = 'El correo electronico y la clave no coinciden con el archivo';
   }
  } // final de si empty($errors)
  // devuelve falso y los errores:
  return array(false,$errors);
 } // final de la funcion check_login().
?>

Explicando un poco el codigo:

La primera funcion:

1.- Creamos una funcion redirect_user() con la cual podemos redirigir a los usuarios a la pagina que le demos como parametro, pero por defecto es index.php

2.- Creamos la variable $url la cual contiene, primero agregamos el http:// por si nos encontramos en localhost, despues el host seria la url actual, al final agregamos el directorio actual del archivo donde nos encontramos con PHP _SELF.

3.- Removemos las barras

4.- Agregamos la pagina que le dimos para redirigir a la variable $url

5.- Redirigimos a la $url final con header()

6.- Paramos el script con exit()

La segunda funcion:

1.- Se crea la funcion check_login() que lleva tres argumentos, la coneccion a la base de datos, el correo electronico (este es opcional) y la clave (tambien es opcional).

2.- Validamos el correo y la clave, si algun problema ocurre mostrara los errores.

3.- Verificamos que el correo y la clave sea correcta esto lo hacemos de manera que si arroja 1 resultado significa que lo es. Luego devolvemos el resultado en un array como verdadero.

4.- Si el resultado no es correcto devolvemos el array en falso y el inicio de sesion fallará.


Usando Cookies

Las cookies es una forma de que el servidor guarde informacion en la maquina del usuario. Esta es una forma de que el servidor recuerde o siga al usuario. Piensa que la cookie es como un identificador personal, en la cual tu llamas al servidor con tu nombre y el te da una identificacion (pasé o pulsera). Entonces con eso ya sabe a quien se esta refiriendo. En este apartado veremos como establecer una cookie, devolver informacion almacenada por la cookie, alterar la configuracion de la cookie, y tambien eliminar la cookie.


Establecer cookies

La cosa mas importante para aprender acerca de las cookies es que ellas son enviadas desde el servidor hasta el cliente antes que cualquier otra informacion. Ya que si envias una cookie despues esto causaria un error. Incluso si es un espacio en blanco.

Las cookies se envian con la funcion setcookie():

setcookie('nombre','valor');

setcookie('nombre','arthusu');


Como ves esto enviaria una cookie al navegador de nombre le pusimos nombre (valga la redundancia) y de valor le pusimos arthusu. De igual manera si quisieramos agregar mas cookies solamente las seguimos estableciendo con la misma funcion:

setcookie('ID',250);
setcookie('email','arthusu@gmail.com');

Es recomendable no utilizar espacios ni puntuaciones en el nombre establecido.

Veamos como establecer una cookie utilizando todo el codigo del ejemplo anterior...

login.php


<?php
 // esta pagina procesa el formulario de inicio de sesion
 // si el inicio de sesion es correcto, el usuario es redirigido
 // tenemos que incluir dos archivos necesarios
 // no enviamos nada al navegador antes de las lineas setcookie()

 // checamos si el formulario ha sido enviado:
 
 if ($_SERVER['REQUEST_METHOD'] == 'POST') {
  // para procesar el inicio de sesion
  require('includes/login_functions.inc.php');

  // necesitamos la coneccion a la base de datos:
  require('../mysqli_connect.php');

  // verificamos el inicio de sesion:
  list($check,$data) = check_login($dbc,$_POST['email'],$_POST['pass']);
  if ($check) { //OK
   setcookie('user_id',$data['user_id']);
   setcookie('first_name',$data['first_name']);

   // redirigimos
   redirect_user('loggedin.php');
  }else{ // No es correcto
   // asignamos a $data para $errors para que nos muestre los errores
   // en el archivo login_page.inc.php
   $errors = $data;
  }

  mysqli_close($dbc); // cerramos la coneccion a la base de datos
 } // aqui termina la condicional principal
 
 // creamos la pagina:
 include('includes/login_page.inc.php');

?>


Explicando el codigo anterior:

1.- Creamos la pagina login.php que requiere de los dos archivos que creamos anteriormente para poder funcionar.

2.- Verificamos que el formulario haya sido enviado y si es asi, entonces agregamos dos script el de las funciones por que lo necesitaremos y el de la coneccion a la base de datos, de forma que verificaremos el inicio de sesion y ademas enviaremos las cookies.

Antes de seguir agregare el codigo de los demas archivos que nos faltan para poder seguir trabajando con nuestros scripts:

1.- Vamos a crear la base de datos la cual llamaremos "usuarios", esto lo hacemos ingresando a phpmyadmin:
http://localhost/phpmyadmin/

2.- Donde dice crear nueva base de datos, colocamos y nombre y le damos crear.

3.- Creamos una nueva tabla dentro que se va llamar login, en la cual agregaremos 5 campos los cuales seran:

* user_id (int not null autoincrement primary key)
* first_name (varchar 70 not null)
* last_name (varchar 70 not null)
* email (varchar 20 not null)
* password (varchar 40 not null)



4.- Insertamos un nuevo registro dando clic en insertar, ahi llenamos los datos, en mi caso puse lo siguiente :

user_ id : 1first_name:  arthusulast _name:  xdemail: arthusu@gmail.compassword: utilize la funcion sha1 y puse clave 123

El archivo php para la coneccion a la base de datos la tenemos fuera del directorio publico de manera que nadie mas lo podra ver a menos que tengan permisos:

mysqli_connect.php


<?php
 
 // Este archivo contiene acceso a la informacion de la base de datos
 // Esta archivo tambien establece coneccion con MySQL
 // selecciona la base de datos, y establece una codificacion

 
 // establecemos la informacion en constantes:
 define('DB_USER', 'tusuario');
 define('DB_PASSWORD', 'tucontraseña');
 define('DB_HOST', 'localhost');
 define('DB_NAME', 'usuarios');

 // creamos una coneccion:
 $dbc = @mysqli_connect(DB_HOST,DB_USER,DB_PASSWORD,DB_NAME) OR die('No se pudo conectar a MySQL: '.mysqli_connect_error());

 // esablecemos la codificacion:
 mysqli_set_charset($dbc,'utf-8');
?>

En el codigo del archivo anterior definimos en constantes los datos para una coneccion, con mysqli_connect() establecemos una coneccion con la base de datos con mysqli_set_charset() establecemos una codificacion para la base de datos.


El archivo header y footer son los siguientes: 

header.html


<!DOCTYPE html>
<html>
<head>
 <title><?php echo $page_title; ?></title>
 <link rel="stylesheet" href="includes/styles.css" type="text/css" media="screen" />
 <meta http-equiv="content-type" content="text/html;charset=utf8" />
</head>
<body>
 <header>
  <h1>Tu sitio web</h1>
  <h2>Tu slogan...</h2>
 </header>
 <nav>
  <ul>
   <li><a href="#">Inicio</a></li>
   <li><a href="#">...</a></li>
   <li><a href="#">...</a></li>
   <li><a href="#">...</a></li>
   <li><a href="#">...</a></li>
  </ul>
 </nav>



footer.html
 <footer>
  <p><b>Copyright 2014</b></p>
 </footer>
</body>
</html>


Ya terminado nuestro codigo para continuar con la explicacion con el codigo de las cookies, por cierto el estilo no se ha agregado, esto lo veremos mas adelante...

3.- Validamos los datos enviando estableciendo la coneccion a la base de datos, y los datos que se pasan que estan en el formulario. Como en la funcion check_login() devolvemos un array entonces lo recojemos en variables utilizando la funcion list(). De esta manera sabremos si el login es correcto o no, y asi poder utilizar los datos.

4.- Si el inicio de sesion es correcto, establecemos las cookies user_id y first_name para ello utilizaremos los datos de la base de datos arrojados por la funcion check_login(). Y haremos una redireccion a un archivo que todavia no existe llamado loggedin.php

5.- Si el inicio de sesion no es correcto arrojamos los errores.

6.- Cerramos la base de datos utilizando mysqli_close(). Incluimos el archivo que contiene nuestro formulario.


De todas formas aunque el archivo loggedin.php no exista en los navegadores podemos ver como las cookies se han establecido correctamente:



Algunas notas importantes sobre las cookies es que estan limitadas a 4KB y que cada navegador recuerda un numero limitado de cookies para cada sitio. Los mayoria de los navegadores actuales soportan hasta 50 cookies por sitio. La funcion setcookie() es una de las pocas funciones en php que podria tener diferentes resultados en diferentes navegadores, desde cada navegador las cookies son tratadas de diferente manera. Para estar seguros podemos probar nuestro sitio web en diferentes navegadores y diferentes plataformas.

Accediendo a las cookies

Para devolver una valor desde la cookie, tu solo debes referirte al array superglobal $_COOKIE, usando apropiadamente el nombre de la cookie como clave, por ejemplo para devolver el valor de una cookie establecida:


setcookie('username','arthusu');

tu puedes referirte a ella como $_COOKIE['username']




<?php
 // el usuario es redirigido aqui desde login.php
 
 // si la cookie no esta presente, redirigimos al usuario
 if (!isset($_COOKIE['user_id'])) {
  // necesitamos las funciones
  require('includes/login_functions.inc.php');
  redirect_user();
 }

 // establecemos el titulo de la pagina en la cabecera html
 $page_title = 'Sesion iniciada';
 include('includes/header.html');

 // mostramos un mensaje personalizado

 echo "<h1>Sesion iniciada correctamente</h1>
 <p>Tu sesion esta iniciada como, {$_COOKIE['first_name']}!
 <a href=\"logout.php\">Salir</a></p>";

 include('includes/footer.html');
?>

1.- verificamos si existe la cookie, en caso de no existir redirigimos al inicio de la pagina. Antes para ello es necesario agregar donde se encuentran las funciones para llamar a la pagina y redirigir.

2.- Si el inicio de sesion es correcto, creamos una variable con el titulo e incluimos el header.html el cual contiene un codigo para nuestra variable. Despues de eso mostramos un mensaje de bienvenida con el nombre del usuario haciendo referencia a el con el array superglobal $_COOKIE.

3.- Creamos un enlace de Salida (logout.php) que mas adelante veremos como crear.

Estableciendo parametros a las cookies

Nosotros solo hemos pasado el nombre y el valor como parametros en la funcion setcookie(), pero hay otros argumentos disponibles que puede tomar y cada uno altera la definicion de la cookie.


setcookie(nombre,valor,expiracion,ruta,servidor,secure,httponly)

El argumento expiracion es usado para establecer el tiempo de duracion para que una cookie exista. Este tiempo se especifica en segundos. Si este valor se deja en 0 no se especifica nada y la cookie es eliminada hasta que el navegador es cerrado. Podremos agregar un tiempo de expiracion especifico utilizando la funcion time(), por ejemplo si quisieramos agregar 30 minutos en tiempo de expiracion de la cookie seria de la siguiente manera:


setcookie(nombre,valor,time()+1800);

Donde 1800 es el tiempo en segundos.
La ruta y el servidor son usados para limitar la cookie a una ruta especificada o servidor, por ejemplo: www.ejemplo.com o 192.168.0.1. Y en la ruta por ejemplo si tu quieres que esa cookie solo exista en la ruta del administrador admin/ se la especificas ahi mismo.
Si nosotros establecemos en la ruta / se podra usar la cookie en todo el sitio, y si ponemos en el servidor .ejemplo.com se puede usar la cookie en todo el sitio y subdominios.

El valor secure dice que la cookie solo puede ser enviada por conecciones seguras https. Con 1 la activamos y con 0 dejamos la coneccion estandar. En caso de que tu sitio tenga activado https puedes activar para que las cookies sean seguras estableciendo el valor 1.


setcookie(nombre,valor,expiracion,ruta,servidor,1);
En la version de php 5.2 fue agregado el argumento httponly. Este es un valor Booleano que es usado para crear una cookie accesible mediante HTTP (y HTTPS). Reforzando la restriccion de la cookie haciendola mas segura (ante intentos de hackers) pero no es soportada por todos los navegadores. 


setcookie(nombre,valor,expiracion,ruta,servidor,secure,TRUE);

Como la mayoria de las funciones en setcookie() para no establecer ninguna valor a alguno de los parametros solo es necesario utilizar NULL, 0 o una cadena vacia (No usar FALSE). La expiracion y secure ambos son valores enteros por lo cuales no deben ir entre comillas. 

Vamos a demostrar todo lo visto en el script anterior modificando la cookie haciendo que expire en 1 hora.

Abrimos el archivo login.php y le agregamos lo siguiente:


setcookie('user_id',$data['user_id'],time()+3600,'/','',0,0);setcookie('first_name',$data['first_name'],time()+3600,'/','',0,0);




<?php
 // esta pagina procesa el formulario de inicio de sesion
 // si el inicio de sesion es correcto, el usuario es redirigido
 // tenemos que incluir dos archivos necesarios
 // no enviamos nada al navegador antes de las lineas setcookie()

 // checamos si el formulario ha sido enviado:
 
 if ($_SERVER['REQUEST_METHOD'] == 'POST') {

  // para procesar el inicio de sesion
  require('includes/login_functions.inc.php');

  // necesitamos la coneccion a la base de datos:
  require('../mysqli_connect.php');

  // verificamos el inicio de sesion:

  list($check,$data) = check_login($dbc,$_POST['email'],$_POST['pass']);
  if ($check) { //OK
   setcookie('user_id',$data['user_id'],time()+3600,'/','',0,0);
   setcookie('first_name',$data['first_name'],time()+3600,'/','',0,0);

   // redirigimos
   redirect_user('loggedin.php');
  }else{ // No es correcto
   // asignamos a $data para $errors para que nos muestre los errores
   // en el archivo login_page.inc.php
   $errors = $data;
  }

  mysqli_close($dbc); // cerramos la coneccion a la base de datos
 } // aqui termina la condicional principal
 
 // creamos la pagina:
 include('includes/login_page.inc.php');

?>


Para sacar los segundos es tan facil como multiplicar 60 minutos que es una hora por 60 segundos que es 1 minuto.


Eliminar las cookies

Lo ultimo para terminar de saber como se usan las cookies es eliminar una. Ya sabemos que hay cookies que tienen un tiempo de expiracion pero incluso si tu quisieras simplemente salir de alguna pagina y que tu sesion ya no este iniciada por alguna razon podrias cerrar tu sesion eliminado la cookie.

Para eliminar la cookie solo es necesario el nombre, el valor dejarlo vacio y el tiempo de expiracion ponerlo hacia atras el tiempo que le hayas dado. Un ejemplo para eliminar la cookie first_name:


setcookie('first_name','',time()-3600);
Para que todo esto quede mas claro vamos a crear nuestra pagina de logout.php:



<?php
 // esta pagina deja al usuario cerrar sesion
 // si la cookie no esta presente, redirige al usuario:

 if (!isset($_COOKIE['user_id'])) {
  // necesitamos las funciones
  require('includes/login_functions.inc.php');
  redirect_user();
 }else{
  // Eliminamos las cookies:
  setcookie('user_id','',time()-3600,'/','',0,0);
  setcookie('first_name','',time()-3600,'/','',0,0);
 }
 // Establecemos un titulo a la pagina
 $page_title = 'Cerrar sesion';
 include('includes/header.html');

 // Imprimimos un mensaje personalizado

 echo "<h1>Cierre de sesion!</h1>
 <p>Tu cesion ha sido cerrada correctamente, {$_COOKIE['first_name']}</p>";

 include('includes/footer.html');
?>


Usando sesiones

Otro metodo para crear datos disponibles en multiples paginas de un sitio web es utilizar sesiones. La premisa de una sesion es que los datos son almacenados en el servidor, no en el navegador web, y el identificador de sesion es usado para identificar a un usuario en particular (datos de sesion). Este identificador de sesion es almacenado en el navegador comunmente cuando utilizamos cookies, pero los datos son sensibles, como el ID de usuario, el nombre y demas, por eso los datos siempre deben de mantenerse en el servidor.

La pregunta surge aqui: ¿para que usamos sesiones si podemos usar cookies y funcionan correctamente? primero que todo, las sesiones son mas seguras al almacenar los datos en el servidor,y no continua enviando atras y adelante entre servidor y cliente. En segunda tu puedes guardar mas datos en las sesiones. En tercera algunos usuarios rechazan las cookies o simplemente las mantienen apagadas. Mientras que las sesiones estan diseñadas para trabajar con cookies pueden funcionar sin ellas, tambien.

Para demostrar las sesiones y compararlas con las cookies, reescribiremos los scripts creados anteriormente...

Estableciendo sesiones

La mas importante regla respecto a las sesiones es que cada pagina que vayan a llamarlas deben usar la funcion session_start() al comienzo. Esta funcion es llamada en PHP ya sea cuando comienzas una nueva sesion o accedes a una existente. Esta funcion debe ser llamada antes que cualquier cosa sea enviada al navegador.
La primera vez que esta funcion es usada, session_start() intentara enviar una cookie con el nombre PHPSESSID (nombre por defecto de una sesion) y un valor parecido al este 7d9d0e1d7a8e37f6feb9967ac0a5b445 (32 letras hexadecimales, ID de sesion). El por que de este intento para enviar la cookie, session_start() es enviada antes que cualquier dato sea enviado al naveador web, hasta ese caso nosotros podemos usar las funciones setcookie() y header().

Incluso si la sesion ya ha comenzado, los valores pueden ser registrados para la sesion usando la sintaxis normal del array, usando el array superglobal $_SESSION.

1.- abrimos el archivo login.php y reemplazamos las lineas de setcookie() por el siguiente codigo:

session_start();
$_SESSION['user_id'] = $data['user_id'];
$_SESSION['first_name'] = $data['first_name'];
El primer paso para comenzar la sesion. Es que no debe de haber ninguna declaracion echo, inclusion de archivos HTML o espacios en blanco. Para que la funcion session_start() este segura, tambien podriamos ponerla al inicio de todo el script, nuestro array $_SESSION tiene dos pares de claves con sus valores, first_name y user_id.


<?php
 // esta pagina procesa el formulario de inicio de sesion
 // si el inicio de sesion es correcto, el usuario es redirigido
 // tenemos que incluir dos archivos necesarios
 // no enviamos nada al navegador antes de las lineas setcookie()

 // checamos si el formulario ha sido enviado:
 
 if ($_SERVER['REQUEST_METHOD'] == 'POST') {

  // para procesar el inicio de sesion
  require('includes/login_functions.inc.php');

  // necesitamos la coneccion a la base de datos:
  require('../mysqli_connect.php');

  // verificamos el inicio de sesion:

  list($check,$data) = check_login($dbc,$_POST['email'],$_POST['pass']);
  if ($check) { //OK
   session_start();
   $_SESSION['user_id'] = $data['user_id'];
   $_SESSION['first_name'] = $data['first_name'];
   // redirigimos
   redirect_user('loggedin.php');
  }else{ // No es correcto
   // asignamos a $data para $errors para que nos muestre los errores
   // en el archivo login_page.inc.php
   $errors = $data;
  }

  mysqli_close($dbc); // cerramos la coneccion a la base de datos
 } // aqui termina la condicional principal
 
 // creamos la pagina:
 include('includes/login_page.inc.php');

?>

Obviamente el script loggedin.php debe ser modificado ya que esta esperando la precencia de una cookie.

Tips:

Puedes establecer session.auto_start a 1 en el archivo php.ini de esta manera no es necesario agregar session_start() en cada pagina. Aunque esto tambien hace que el servidor este enviando sesion nueva cada vez y solo debe utilizarse cuando sea realmente necesario.



Accediendo a las sesiones

Incluso las sesiones que ya han sido creadas y las variables que ya han sido registradas, tu puedes acceder desde otros scripts a estas variables, esto lo podemos hacer con cada script iniciando la sesion con session_start().

Esta funcion nos da acceso a la sesion anteriormente almacenada (puede leer el PHPSESSID almacenado en la cookie) o crear una nueva sesion si no esta creada. Comprendiendo que si el ID de sesion no es encontrado y un nuevo ID de sesion es generado, ninguno de los datos almacenados en el ID de sesion viejo estaran disponibles. Lo mencionado aqui puede causarte problemas con sesiones, para verificar el valor de el ID de la sesion podemos verlo en una pagina con el paso a debugear.

Asumiendo que no tienes problemas con la sesion, nos referimos a la variable de la sesion, usando $_SESSION['var'], tu podrias referirte a cualquier otro array. 

1.- abrimos el archivo loggedin.php y agregamos al inicio session_start() que debe ser llamada antes que header.html.

2.- reemplazamos $_COOKIE por $_SESSION y guardamos el archivo.






<?php
 // iniciamos la sesion
 session_start();
 // el usuario es redirigido aqui desde login.php
 
 // si la cookie no esta presente, redirigimos al usuario
 if (!isset($_SESSION['user_id'])) {
  // necesitamos las funciones
  require('includes/login_functions.inc.php');
  redirect_user();
 }

 // establecemos el titulo de la pagina en la cabecera html
 $page_title = 'Sesion iniciada';
 include('includes/header.html');

 // mostramos un mensaje personalizado

 echo "<h1>Sesion iniciada correctamente</h1>
 <p>Tu sesion esta iniciada como, {$_SESSION['first_name']}!
 <a href=\"logout.php\">Salir</a></p>";

 include('includes/footer.html');
?>

Tips:

Recuerda que como ya dijimos, si en tu aplicacion no ves los datos de sesion en otra pagina, esto puede ser por que se ha creado una nueva sesion en otra pagina. Para verificar esto podemos comprobar el ID de sesion (mirando los ultimos caracteres comprobando si son iguales) tambien puedes ver el ID de sesion utilizando la funcion session_id():

echo session_id();

Eliminando sesiones

Cuando utilizamos sesiones usted debe de tener un metodo para poder eliminarlas, esto es necesario para que el usuario cierre sesion. 
Para eliminar una variable de sesion individual podemos utilizar la funcion unset() que es valida para cualquier variable:

 unset($_SESSION['var'])

Para eliminar cualquier variable de la sesion tu no deberias utilizar unset() sino reestablecer la sesion de la siguiente manera:

$_SESSION = array();

Y finalizamos borrando cualquier dato de sesion en el servidor utilizando la funcion session_destroy():

session_destroy();
Nota que la prioridad para utilizar cualquiera de estos metodos es siempre iniciar session_start(), para que los datos de sesion sean recogidos.

1.- abrimos el archivo logout.php
2.- agregamos al inicio del archivo session_start();
3.- Cambiamos la condicional en lugar de $_COOKIE usamos $_SESSION
4.- reemplazamos las lineas de setcookie() por $_SESSION = array(); session_destroy(); y eliminamos del mensaje de cerrado de sesion {$_COOKIE['first_name']}:


<?php

 // iniciamos sesion
 session_start();

 // esta pagina deja al usuario cerrar sesion
 // si la cookie no esta presente, redirige al usuario:

 if (!isset($_SESSION['user_id'])) {
  // necesitamos las funciones
  require('includes/login_functions.inc.php');
  redirect_user();
 }else{
  // Eliminamos las cookies:
  $_SESSION = array();
  session_destroy();
 }
 // Establecemos un titulo a la pagina
 $page_title = 'Cerrar sesion';
 include('includes/header.html');

 // Imprimimos un mensaje personalizado

 echo "<h1>Cierre de sesion!</h1>
 <p>Tu cesion ha sido cerrada correctamente</p>";

 include('includes/footer.html');
?>

Hasta aqui termina la septima parte de PHP, nos vemos en la proxima parte :).