miércoles, 9 de julio de 2014

Tunel SSH Reverso y trabajo con screen (terminal compartida)

Wenas,

Que se necesita:


  • Que todas las maquinas tengan SSH Server y SSH client :) (los servers iniciados claro esta).
  • Saber de Linux (bueno en este ambiente es linux, en windows ha de ser igual, adaptalo ejjeje)


hace tiempo llevo haciendo esto pero siempre se me olvida jejeje asi que lo dejo aquí mas que para mi por si a alguien le interesa.

Paso a explicar el caso, supongamos tienes un server (VPS, lo que sea [a la cual llamaremos de ahora en mas SV]) al cual te puedes conectar mediante SSH, y quisieras conectarte al computador de tu casa o al de un amigo que esta en apuros (al cual llamaremos desde ahora PC), y te encuentras con que al PC que te quieres no tiene puertos abiertos en router y la ISP te cobra bla bla bla...

Ademas el computador desde el que estas conectado (al cual llamaremos HS) ahora tampoco tiene los puertos abiertos en el router al que esta conectado :/ pinta mal la cosa xDDD... Pero no tanto recuerda que tienes el server :o, asi que wala, podremos hacer la conexion inversa y obtener la terminal del PC desde tu HS a traves de nuestro SV... mmm un poco confuso de explicar y como dicen una imagen vale mas que 1000 palabras aqui el esquema mejor explicado :)




Ahora si es mas fácil de explicar: El PC se conecta al servidor con el comodin -R de ssh indicando un puerto no ocupado (preferiblemente mayores a 2222) y ha de tenerse en cuenta dicho puerto, este se debe ejecutar de esta manera:


$ ssh -R 4444:localhost:22 usuario@SV

una vez hagas esto te pedirá la contraseña y paso a explicar:

ssh -> pues el cliente ssh jejeje

-R 4444:localhost:22 -> el -R lo que hara sera unir o bindear (jejeje) la conexion hacia un puerto que le indiques y hacia un host:puerto que asignaras también, has de tener en cuenta que si cambiaste la configuracion de tu ssh en la maquina que estas (me refiero al puerto) y no dejaste el 22 (que es defecto) debes cambiar el 22 por el puerto que hayas configurado.

usuario@SV -> usuario para conectartre al servidor luego el arroba (@) y la direccion del servidor (IP, dominio que se yo).


hasta ahi todo bien el PC conectara al SV y en el servidor se genera una conexion entre el puerto 22 del propio y el puerto 4444 que en otras palabras se conecta con PC. Ahora conectamos desde nuestro HS al servidor, y desde alli nos conectaremos a la PC por el puerto que se definió (en este caso 4444):

ssh usuario@SV

y ya conectado a SV ejecutamos:

$ ssh usuariodePC@localhost -p 4444

y boom aquí conecta jejeje, ya tendremos acceso a la maquina PC los comandos que ejecutemos desde HS se ejecutarán directamente en PC...

Y bien para que todo salga al peluche y si nuestro amigo es desconfiado pues le dices que desde PC ejecute screen (en otra terminal, no en la que esta conectado a SSH) así:

$ screen

Parecerá que no hace nada pero desde HS tu ejecutaras screen -ls asi:

$ screen -ls

y saldrá algo similar a esto:

There is a screen on:
15741.pts-9.PC (09/07/14 16:22:07) (Attached)
1 Socket in /var/run/screen/S-pc.

ves el nombre despues del punto me refiero a pts-9.PC y tu desde HS ejecutas:

$ screen -x pts-9.PC

y boom lo que escribas en HS aparecerá en PC y viceversa, ademas de que si necesitases claves (por ejemplo en un comando sudo) desde PC te escribiría la clave y todos felices :) una terminal compartida en donde podrán trabajar juntos :) y tu amigo (PC) verá todo lo que haces y así aprende jejejej...

Y bueno espero les sirva de mucho como a mi y si no pues a mi si me sirve que se me olvida a cada momento xDDD..

Saludos kid_goth

lunes, 7 de julio de 2014

[Parte 5] PHP

Manejo de errores y depuración

Hay tres tipos de fallos generales en programacion, los cuales son los siguientes:

* Errores sintacticos
* Errores en tiempo de ejecucion
* Errores logicos

En php uno de los errores mas comunes y faciles de arreglar es el punto y coma (;), que muchas veces se olvida de colocar.

Si alguna ves ejecutas el codigo y sale la pagina en blanco esto puede deberse a que no tienes habilitado (on) display_errors en php.ini.

Un error de sintaxis que ocurre mucho es cuando arroja un mensaje como "unexpected $end" este error es muy comun y pasa cuando hace falta cerrar una llave ({})  o cuando estas utilizando etiquetas en formato abreviado (<??>) y en la configuracion esta desactivada, es por eso muy recomendable utilizar <?php ?> como inicio y cierre de php, otra forma de solucionar este error es que no haya ningun espacio al final del archivo.

Otro error de sintaxis muy comun en el uso de funciones es "expects at least # parameters" donde # es el numero de parametros que se esperan en esa funcion, con esperar ese numero de parametros se refiere a eso que tienes mas o menos parametros dependiendo de como te lo indique el error, la manera mas facil de corregir este error es ir a la documentacion de php y ver como esta la sintaxis de esa funcion, documentacion php: php.net

Lo mas recomendable a la hora de estar programando es utilizar un IDE (Entorno de desarrollo integrado) de esta manera nos podemos dar cuenta de manera mas rapido de los errores que tenemos. El que yo utilizo es Sublime Text. Pero hay otros, uno de los mas usados e importantes es Dreamweaver.

Si pasa que alguna vez te sucede algun error por que pasas algun script a otro servidor puede ser que la configuracion del mismo no sea la que tenias antes por lo cual no acepte algunas de las funciones que tienes, es por eso que tenemos siempre que nos suceda eso verificar la version de PHP y MySQL y las librerias que incluye, para ello creamos un archivo php con la funcion phpinfo().

Si no sabes donde se encuentra el archivo de configuracion de PHP puedes vericarlo simplemente en el archivo creado con la funcion phpinfo() la cual muestra informacion sobre el servidor y su configuracion, pero de otra forma tambien podemos utilizar la funcion ini_set() que establece una directiva de configuracion, de manera que si utilizaramos:

 <?php ini_set('display_errors',1);?>

Nuestra directiva display_errors estaria activada.

Tambien hay una manera de eliminar los errores utilizando @ delante de una funcion no mostraria nuestro error, un ejemplo podria ser @include('archivo_que_no_existe.php'); no nos mostraria error.

Siempre que un error es mostrado, se muestra al inicio el nivel de error que es, por ejemplo: Warning: Division by zero...
en el nivel de error nos referimos a Warning, existen varios niveles veamos cuales son y que es lo que indican:



Con la funcion error_reporting() podemos seleccionar que tipo de error mostrar en tiempo de ejecucion. Unos ejemplos serian:


 <?php error_reporting(0); // Desactiva toda notificacion de error ?>


 <?php error_reporting(E_ALL ^ E_NOTICE ); // Notificar todos los errores excepto E_NOTICE ?>
 
 <?php error_reporting(E_ERROR | E_WARNING | E_PARSE); // Notificar solamente errores de ejecucion ?>



La funcion trigger_error() lo que hace es generar un error en el script PHP. El primer argumento es el mensaje de error, el segundo es opcional, y es el numero del tipo de error (el cual esta descrito en la imagen anterior). Por defecto el tipo de error utilizado es E_USER. Un ejemplo del uso de la funcion trigger_error() podria ser el siguiente:


 <?php
 if(/* alguna condicion */){
  trigger_error("Algo ha fallado!");
 }?>

Hay una mejor manera de gestionar nuestros errores utilizando la funcion set_error_handler() de manera que creamos una funcion la cual maneja los errores y los muestra personalizados, haciendolos mas entendibles para nosotros mismos. Un ejemplo simple seria el siguiente:


 <?php
 function reportar_errores(argumentos){
  //hacer algo aqui
 }
 set_error_handler('reportar_errores');?>

Al definir nuestra funcion acepta los siguientes argumentos:


 <?php
 function reportar_errores($num,$msg,$archivo,$linea,$vars){
  //hacer algo aqui
 }?>


Veamos un ejemplo completo de como podemos usar nuestra propia funcion para reportar errores:


 <?php
 // el mensaje para ver si el sitio esta subido o no
 define('ONLINE', FALSE);
 //creamos la funcion
 function reportar_errores($num,$msg,$archivo,$linea,$vars){
  // el mensaje de error
  $mensaje = "Un error a ocurrido en el script '$archivo' en la linea $linea: $msg\n";
  // le agregamos las variables que existen en el error al mensaje
  $mensaje .= print_r($vars,1);

  if(!ONLINE){ // para version en desarrollo
   echo '<pre>' . $mensaje . "\n";
   debug_print_backtrace(); // devuelve informacion sobre funciones llamadas, archivos incluidos, etc.
   echo '</pre><br />';
  }else{
   echo '<div class="error">Ha ocurrido un error en el sistema. Disculpenos por el inconveniente.</div><br />';
  }
 }

 // uso mi manejador de errores
 set_error_handler('reportar_errores');

 // creo unos errores:
 foreach($var as $v){}
 $result = 1/0;
?>


Como puedes ver en la imagen es el resultado de nuestra funcion y en la creacion de la funcion se explica todo claramente con comentarios, lo unico que tendriamos que modificar en caso de que subamos este script a un alojamiento gratuito o de paga es la constante ONLINE  en TRUE de manera que nos arrojaria un error personalizado.


Con error_log() podriamos enviar nuestro mensaje de error al registro de errores del servidor o de un fichero o simplemente a un email, de manera que si estamos ONLINE podriamos hacer que se nos enviara un error, ademas de nuestro mensaje personalizado.

La sintaxis es la siguiente:

error_log(mensaje,tipo,destino,cabeceras extras);

* mensaje es el mensaje de error que vas a enviar
* tipo es a donde va ir el mensaje: 
- 0 va para el registro del sistema, usando el mecanismo de registro del sistema operativo. Esta es la opcion predeterminada.
- 1 el mensaje es enviado por correo a la direccion que se indique en destino, es el unico tipo de mensaje donde se utiliza el cuarto parametro cabeceras extras.
- 3 es añadido al final del fichero destino. No se añade automaticamente una linea al final de la cadena mensaje.
- 4 es enviado directo al gestor de registro SAPI.
* destino su significado depende de el tipo como se indico arriba.
* cabeceras extras se usa cuando el tipo de mensaje esta establecido en 1, este tipo utiliza la misma funcion interna mail().

Errores comunes en PHP

Pagina en blanco: Posible problema en el HTML, o display_errors o error_reporting() estan desactivados.

Parse error: Se olvido colocar punto y coma (;), las llaves no estan correctamente colocadas ( inicio y cierre de llaves {}), o parentesis, o comillas, o las comillas no han sido escapadas.

Empty variable value: Se olvido colocar el caracter inicial de una variable signo de dolar ($), la variable esta mal escrita o no esta respetando que es case-sensitive, o uso inapropiado de la variable con respecto a su ambito (esto sucede mucho en funciones).

Undefined variable: Se esta haciendo referencia a la variable antes de ser creada o simplemente no tienen ningun valor y esta vacia para ello podemos checar Empty variable value

Call to undefined function: Nombre de la funcion esta mal escrito, PHP no esta configurado para utilizar esa funcion (esto se puede deber a alguna libreria que no contiene), contiene una funcion que no ha sido incluida (a esto me refiero que no ha hecho include a algun archivo donde se encuentra la funcion en si).

Cannot redeclare function: Existen dos declaraciones en la misma funcion, esto puede deberse al incluir algun archivo, entonces lo recomendable es mirar si no incluistes dos veces el mismo archivo.

Headers already send: Existe un espacio en el script antes de las etiquetas de PHP, los datos que ya se han mostrado o se ha incluido el archivo dos veces.

Al momento de querer reparar algunos errores es buena idea utilizar comentarios, comentamos alguna linea para ver que es lo que esta pasando y si es la linea que esta causando ese error o simplemente no podemos usarla por el momento por que el servidor no esta configurado correctamente para utilizar esa funcion (por ejemplo la funcion mail()).

Tambien podemos mostrar lo que contiene alguna variable o array de manera que veamos en que estamos equivocandonos,  para ello podemos usar las funciones echo o print en caso de variables o print_r o var_dump en caso de arrays.

echo $variable_contiene_algo_importante;
print_r($array_contiene_algo_importante);
A que contiene algo importante me refiero a que es algo importante para que el script siga su ejecucion, pero como en realidad las variables o arrays no lo estamos viendo entonces los mostramos para saber si algun valor se esta pasando correctamente o hay algun error.

Muchas veces una condicional o un bucle son los que pueden estar causando nuestro error en caso de querer comentarlos podemos utilizar el comentario multilinea /* acadentrolacondicionalobucle */.

Muchos utilizan la funcion die() o exit() para terminar el script en caso de que un error suceda, mostrando un mensaje del error... por ejemplo:


<?php
 $nombre_archivo = 'ruta/hacia/archivo-datos';
 @fopen($nombre_archivo,'r') or exit("No se pudo abrir el archivo ($nombre_archivo)");
?>


Como vemos en este caso utilizamos el @ para suprimir el error de fopen y con la funcion exit() mostramos el mensaje de error personalizado, podriamos haber usado die() en lugar de exit() y seria lo mismo.

Muchas veces también tenemos algunos errores en MySQL (en nuestras consultas) en estos casos lo mejor seria mostrar nuestra variable de consulta $query, de manera que podamos ver como es que se están pasando los valores y en que es lo que nos estamos equivocando... o simplemente ejecutar la consulta desde phpmyadmin o desde consola. Muchas veces suele suceder al no poner el tipo de dato correctamente tal como una cadena por ejemplo. O también hacer uso de print_r() en caso de mostrar un array para ver donde se encuentra el valor que necesitamos.

Un error muy común es cuando nos arroja un mensaje como "Access denied for user: user@localhost" esto sucede ya que algún parámetro a la coneccion puede estar mal colocado o simplemente el usuario a sido baneado por realizar demasiadas consultas (sobrecargando el servidor).

Bueno hasta aquí les dejo la parte 5 de PHP, puede que les parezca algo mal redactado y puede ser que así sea, solo que esta semana no he tenido bastante tiempo como para darle un buen formato y no los quería dejar sin seguir los tutoriales es por eso que lo hice de esta manera, espero que les guste y que puedan encontrar errores en su código de manera mas rápida, saludos.

martes, 24 de junio de 2014

[Parte 4] PHP

En esta parte de PHP intentaremos ver algo sobre base de datos y usaremos MySQL y no dare la teoria ya que pues en los minitutoriales de MySQL que se encuentran en el blog son mas que suficientes para la teoria, pero si entrare en algunos conceptos que no creo haber mencionado en los minitutorials de MySQL en la teoria.

Minitutoriales MySQL:

1.- http://arthusu.blogspot.mx/2013/03/mysql-minitutorial-parte-1.html
2.- http://arthusu.blogspot.mx/2013/03/mysql-minitutorial-parte-2.html
3.- http://arthusu.blogspot.mx/2013/03/mysql-minitutorial-parte-3.html
4.- http://arthusu.blogspot.mx/2013/03/mysql-minitutorial-parte-4.html
5.- http://arthusu.blogspot.mx/2013/05/mysql-minitutorial-parte-5.html


Normalizacion

Para poder trabajar correctamente con las bases de datos relacionales se creo un proceso llamado normalizacion el cual seguiremos para que los diseños de nuestra bases de datos sean correctos. 

Claves

Hay dos tipos de claves las claves primarias y las claves foraneas.

Una clave primaria es un identificador unico que tiene que cumplir las siguientes reglas:

* No pueden ser valores NULL
* Tener un valor que nunca cambia
* Tener un valor unico para cada registro en una tabla

Un ejemplo de clave primaria podria ser la CURP la cual su valor nunca cambia y es unico para cada persona.

La clave foranea son la representacion en la tabla B de la clave principal en la tabla A. Si tenemos una base de datos cine con una tabla peliculas y una de directores, la principal de los directores estaria vinculada con la clave foreanea en peliculas.

Nota Importante: ¨Las claves primarias es ideal que sean numeros enteros para poder obtener un mayor rendimiento.

Relaciones

Las relaciones en la base de datos se refiere a como una tabla se puede relacionar con otra tabla, de alguna manera juntandose (relacionandose). 

Las relaciones deben ser comunmente 1 a varias, ya que si son varias a varias conducen a la redundancia, por lo cual deberiamos hacer que las relaciones sean 1 a varias o 1 a 1.


Las relaciones y las claves trabajan juntos, una clave en una tabla se relacionara con una clave en otra tabla.




Podemos usar MySQL WorkBench como software para diseñar nuestras bases de datos: http://www.mysql.com/products/workbench/

Una relacion varios a varios entre dos tablas es mejor representado como dos uno-varios esas tablas tendran otra tabla como intermediario.

Las bases de datos utilizan ciertas convenciones para estar bien estructuradas. El proceso de un diseño de base de datos obtiene como resultado un ERD (entity-relationship model) o ERM (entity-relationship model). El termino "relacional" en RDBM se deriva de las tablas que son tecnicamente llamadas relacionales.

1 Forma Normal (1NF):

- Cada columna debe tener solo un valor (esto aveces se describe como ser atomica o indivisible (que un solo dato no se divida en varios))
- La tabla no puede tener grupos repetidos de datos relacionados.

Un ejemplo incorrecto para esta norma seria usar, una tabla que contiene la direccion completa de una persona, con las siguientes columnas: calle, ciudad, estado, codigo_postal, pais... ya que tiene varios valores en una columna.

Y el otro ejemplo incorrecto seria una tabla peliculas donde tenemos actor1,actor2,actor3 por que las columnas se repiten con el mismo tipo de informacion.

2 Forma Normal (2NF):

En esta forma se indica que se crearan mas y mas tablas para que no haya redundancia. Un ejemplo podria ser un director de cine, en una tabla de peliculas, en la cual el director de cine puede repetirse tantas veces como haya creado una pelicula, entonces ahi lo correcto seria crear una tabla para el director. Este tipo de llaves son foraneas de manera que se enlacen a la llave principal de la tabla principal.



Aqui puedes ver como para hacer la base de datos compatible con la segunda forma normal hemos creado varias tablas para no causar redundancia.

3 Forma Normal (3NF):

La tercera norma indica que si se cambia el valor de una tabla o se modifica tendra que cambiar el valor de otro, lo cual causaria problemas, es por eso que es mejor dejarlas como estan bien normalizadas o simplemente crear una nueva tabla para hacer referencia en ella en las otras tablas.


La normalizacion es un compromiso entre la integridad de datos, escalabilidad y simplicidad/velocidad.

Existen mas formas de normalizacion pero con llenar hasta la tercera forma normal es mas que suficiente para que tu base de datos trabaje de forma normalizada y correcta.

Les dejo un documento que puede ser leido para tomar mayor claridad sobre el asunto de la normalizacion: http://www.eet2mdp.edu.ar/alumnos/MATERIAL/MATERIAL/info/infonorma.pdf

 

martes, 3 de junio de 2014

Juego XSS de Google

Hace poco vi un post en MuySeguridad Y no dude en intentar pasar el juego que publico Google, tiene una documentacion muy buena que la pueden encontrar aqui:

https://www.google.com/about/appsecurity/learning/xss/index.html

Son nada mas 6 niveles:




En los 6 niveles te enseñan los ataques mas famosos XSS reflejado, XSS Persistente y DOM XSS.

Es muy divertido de jugarlo, se los recomiendo aqui les dejo el link:

https://xss-game.appspot.com/

lunes, 26 de mayo de 2014

[Parte 3] PHP

Incluyendo multiples archivos

En PHP frecuentemente usamos archivos de HTML tales como cabeceras, pies de paginas, contenido, conecciones a la base de datos, etc. Para simplemente No tener que crear el mismo archivo en todos los scripts de PHP que creemos, simplemente las llamaremos donde las necesitamos ahorrandonos codigo y haciendolo todo mas simple. 

Existen 4 funciones para incluir archivos externos:

include(), include_once(), require(), require_once().

Y para usarlas simplemente usuariamos la siguiente sintaxis:

include('RutaDelArchivoAgregar.Extension');

require('RutaDelArchivoAgregar.Extension');


En muchos casos se crean una carpeta includes/ donde se colocan los archivos que seran incluidos, tambien casi por regla estandarizada creamos archivos a incluir sea .php o .html de la siguiente forma:

Miarchivo.inc.html
Miarchivo.inc.php

Asi de simple nos dariamos cuenta que ese archivo se esta incluyendo dentro a algun otro...

Las diferencias entre las funciones include() y require() son que con include() la funcion no pararia el script sino que se seguira ejecutando el script en si y con require() la funcion pararia el script y mostraria un error. En este caso es mas recomendable usar un require() en caso de conexiones a bases de datos y un include() en caso de archivos HTML.

Y con las mismas funciones *_once() seria como checar si el archivo ya esta incluido, de manera que si ya esta incluido... ¿para que lo incluimos de nuevo?... Esto en caso de caso que no necesitemos incluirlo de nuevo... Lo que hace es checar si el archivo ya se incluyo.

Veamos un ejemplo donde tenemos una pagina y tenemos que agregar tal coneccion un gran numero de veces en algun script php, o simplemente una pagina donde tenemos varias partes y el menu lo queremos cambiar... tendriamos que cambiar todo el menu. Pero si usamos archivos incluidos simplemente los tendriamos que agregar una vez:



Aqui en la imagen anteror estamos haciendo dos includes el de la cabecera y el del pie de pagina y en el index solo agregamos nuestro contenido...

Esto nos ahorraria mucho trabajo a la hora de modificar un menu en todas las paginas. 


El codigo es el siguiente:

index.php



 <!DOCTYPE html>
<html>
<?php
 $title = "Mi primera pagina web";
 include("header.inc.php");
?>
<div class="box">
 <h3 style="text-align:center;">lorem ipsum</h3>
 <p><img src="neko.jpg" class="img-polaroid" width="200" style="float:left;"></p>
 <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Omnis, ex, consequuntur, dolorem magni inventore tempora harum molestias voluptatum assumenda distinctio temporibus ratione minima voluptatibus esse dolores quo voluptas provident nemo.</p>
 <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Reiciendis amet dicta voluptate totam rerum eos excepturi sint doloribus. Fugit, atque, repellendus molestiae autem sapiente porro animi dicta reprehenderit ea commodi.</p>
 <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Reiciendis amet dicta voluptate totam rerum eos excepturi sint doloribus. Fugit, atque, repellendus molestiae autem sapiente porro animi dicta reprehenderit ea commodi.</p>
 <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Reiciendis amet dicta voluptate totam rerum eos excepturi sint doloribus. Fugit, atque, repellendus molestiae autem sapiente porro animi dicta reprehenderit ea commodi.</p>
 <p style="float:right"><iframe width="300" src="http://www.youtube.com/embed/QH2-TGUlwu4" frameborder="0" allowfullscreen></iframe></p>
 <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Reiciendis amet dicta voluptate totam rerum eos excepturi sint doloribus. Fugit, atque, repellendus molestiae autem sapiente porro animi dicta reprehenderit ea commodi.</p>
 <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Reiciendis amet dicta voluptate totam rerum eos excepturi sint doloribus. Fugit, atque, repellendus molestiae autem sapiente porro animi dicta reprehenderit ea commodi.</p>
 <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Reiciendis amet dicta voluptate totam rerum eos excepturi sint doloribus. Fugit, atque, repellendus molestiae autem sapiente porro animi dicta reprehenderit ea commodi.</p>
 <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Reiciendis amet dicta voluptate totam rerum eos excepturi sint doloribus. Fugit, atque, repellendus molestiae autem sapiente porro animi dicta reprehenderit ea commodi.</p>
 </div>
<?php
 include("footer.inc.php");
?>
</html>




header.inc.php


 <head>
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="assets/css/bootstrap-responsive.css" rel="stylesheet">
 <link rel="stylesheet" type="text/css" href="bootstrap/css/bootstrap.css">
 <script src="bootstrap/js/bootstrap.js"></script> 
 <title><?php echo $title; ?></title>
 <meta charset="utf-8" /> 
 <style type="text/css">
  .menu{
   width:200px;
   float: right;
   margin:5px;
  }
  .footer {
      background-color: #F5F5F5;
      height: 60px;
      text-align: center;
      padding-top: 10px;
  }
  .box img{
   margin:5px;
   text-align: justify;
  }
 </style>
</head>
<body>
<div class="container">
 <div class="page-header">
  <h1>Mi Cabecera</h1>
 </div>
 <div class="menu">
  <ul class="nav nav-tabs nav-stacked">
   <li><a href="">Link</a></li>
   <li><a href="">Link</a></li>
   <li><a href="">Link</a></li>
   <li><a href="">Link</a></li>
   <li><a href="">Link</a></li>
  </ul>
 </div>

footer.inc.php

  <div class="footer muted">
  <div class="container">
   <p>Pie de pagina</p>
  </div>
 </div>
</div>
</body>

Nota: En este caso para los estilos estamos utilizando el framework bootstrap 2, puedes encontrar el curso completo en este mismo BLOG.

Si te das cuenta en este ejemplo solo usamos el include()... Usemos el require() para ver en que casos es importante usarlo...



Tenemos el archivo conexion.php


 <?php
 $con = mysqli_connect("localhost","root","");
 mysqli_select_db($con,"usuarios_api");
 $consulta = "SELECT * FROM usuarios";
 $resultado = mysqli_query($con,$consulta);
 $array_resultados = mysqli_fetch_array($resultado,MYSQLI_ASSOC);
?>




El cual conecta a la base de datos y pide algun registro para que se muestre en el footer (pie de pagina), en este caso no es necesario entender el codigo de arriba por que todavia no vamos en esa parte...


Y el footer.inc.php se cambio de la siguiente forma:


   <div class="footer muted">
  <div class="container">
   <p>
   2014 &copy; by
   <?php 
    require('conexion.php');
    echo $array_resultados['usuario']; 
    ?></p>
  </div>
 </div>
</div>
</body>



Lo unico que hay que entender aqui es que requiero el archivo conexion.php por que si no mi script no se ejecutara correctamente. Y esa es la diferencia de require() a include().




Ruta relativa VS Ruta Absoluta

La ruta absoluta es la cual se indica desde 0, es decir, desde donde viene el archivo, por ejemplo:

C:\Xampp\htdocs\Proyecto\Includes\ejemplo.php

Como puedes ver la ruta es un poco larga y ademas no es compatible con todos los sistemas, ya que si estuviesemos en Linux la ruta seria algo parecido a la siguiente:

/var/www/proyecto/includes/ejemplo.php

Las rutas relativas en cuando a compatibilidad son mejores, ya que si las mueves de servidor no importa seguiran funcionando. Y la otra ventaja es que son menos largas... Une ejemplo es que nuestro archivo que estamos escribiendo codigo en el momento se encuentra en proyecto/ pero queremos incluir un archivo, el de ejemplo.php que se encuentra dentro de la carpeta includes/, quedaria algo mas o menos asi:

/includes/ejemplo.php

Y simple y sencillamente funcionaria tanto en windows como en linux o macos.

Crea tus propias funciones

La sintaxis de una funcion es la siguiente:

function nombre_funcion (){ //codigo funcion }

Y en caso de que contenga parametros es la siguiente:

function nombre_function($parametro1,$parametro2,...){ // codigo funcion}

Las funciones son case-sensitive (se refiere a que diferencia entre mayuscula o minuscula), una funcion llamada: simple_funcion() no es lo mismo que Simple_Funcion() o sImpLe_FuNCiOn(),etc.

Una funcion se usa cuando:

* Una parte de codigo es repetida muchas veces
* Una parte de codigo es dificil y podemos simplemente llamarla

Pongamos de ejemplo una funcion la cual creamos para que cree anuncios con su url, y cada vez que el usuario vuelve a entrar a la pagina web, crea un anuncio diferente. Esto seria de mucha utilidad si lo creeamos en multiples partes del codigo:


 function anuncios(){
  global $imagen_url;
  $imagenes = array('1-http://localhost1','2-http://localhost2','3-http://localhost3','4-http://localhost4','5-http://localhost5','6-http://localhost6','7-http://localhost7');
  shuffle($imagenes);
  $imagen_url = $imagenes[0];
  $imagen_url = explode("-", $imagen_url);
 }

Para acceder a la funcion anuncios tan solo la llamamos desde donde queramos usando su nombre y parentesis: anuncios() y se llamaria, en este caso por que no incluye argumentos.

Explicacion de la funcion anterior:

En la funcion anterior jugamos con un array donde tenemos nuestro nombre de imagen y su divisor sera -, randomizamos el array usando la funcion shuffle(), luego tomamos la primera imagen solamente, esa imagen la "cortamos" usando el divisor y se creara un nuevo array con nuevos valores el cual contendra 1 y el otro http://localhost1 si fuese el caso, ya que cada vez sale diferente imagen por que se "randomiza" con shuffle().


Ahora veamos un ejemplo de una funcion donde apliquemos argumentos (con argumentos nos referimos cuando es necesario pasarle 1 o mas valores a una funcion, aunque muchas veces puede ser tratado como opcional), en esta funcion usaremos un formulario donde pediremos la fecha de nacimiento del usuario para sacar su edad:



El codigo del script es el siguiente:



 <?php
 function calcular_edad($fecha){
  global $cumpleanios;

  $fecha = explode("/", $fecha);
  list($mes,$dia,$anio) = $fecha;

  $fecha_actual = date("m/d/Y");
  $fecha_actual = explode("/", $fecha_actual);
  list($mes1,$dia1,$anio1) = $fecha_actual;
 

  if($mes1 == $mes && $dia1 == $dia){
   $cumpleanios = "Feliz cumpleaños :)";
  }
  elseif($mes1 < $mes ){
   $cumpleanios = $anio1 - $anio - 1;
  }
  elseif ($mes1 == $mes && $dia1 != $dia) {
   $cumpleanios = $anio1 - $anio - 1;
  }
  else{
   $cumpleanios = $anio1 - $anio;
  }
 }
 if (isset($_POST['date'])) {
  $fecha = $_POST['date'];
  $nombre = $_POST['nombre'];
  calcular_edad($fecha);
  echo "<h3>$nombre tu edad es: $cumpleanios</h3>";
 }
?>
<!DOCTYPE html>
<html>
 <head>
  <title>Descubrir edad</title>
  <meta charset="utf-8" />
   <link rel="stylesheet" href="http://code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css">
  <script src="http://code.jquery.com/jquery-1.10.2.js"></script>
  <script src="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
  <script>
   $(function() {
    $( "#datepicker" ).datepicker({
     changeMonth: true,
     changeYear: true,
     yearRange: "1900:2025"
    });
   });
  </script>
 </head>
 <body>
  <form action="" method="post">
   <h3>Proporciona tu fecha de nacimiento</h3>
   <p><b>Nombre:</b><input type="text" name="nombre" /></p>
   <p><b>Fecha de nacimiento:</b><input type="text" name="date" id="datepicker" /></p>
   <p><input type="submit" name="enviar"></p>
  </form>
 </body>
</html>




Explicacion del codigo:

Lo que cuenta aqui mas que nada es la funcion, la cual te da la edad del usuario que ingrese su fecha de nacimiento. Lo que hacemos es coger la fecha del usuario y pasarlo a unas variables $mes,$dia,$año con la funcion list() y con explode() las convertimos en un array dividiendolas desde /... Entonces cogemos la fecha del usuario y la fecha actual, hacemos comparaciones para saber si la fecha es igual a su cumpleaños: le deseamos un feliz cumpleaños, si el mes de la fecha actual es menor al que nos da el significa que todavia no cumple años, o si el mes es igual y el dia no pues todavia no cumple años, pero si no entonces si cumple años.

Nota: Estamos haciendo uso de Jquery UI, para saber mas puedes consultar la pagina oficial de Jquery UI.

En la funcion hacemos uso del parametro $fecha este no es un valor opcional, si no le das este valor en la funcion simplemente nos daria un error, por lo cual este valor debe ingresarse, no necesariamente la variable tiene que ser igual que la otra. En caso de que un parametro sea opcional tendrias que dar una fecha por defecto... De esta manera el llamado a la funcion fue:

calcular_edad($fecha);

Ambito en las variables

En este caso de las funciones si que era muy importante el ambito, ya que les estaba dando a algunas variables ambito global para poder hacer referencia a ellas al llamar la funcion.

La variable local, son las que estan dentro de un bloque y solamente cuentan alli, es como en la funcion anterior, sino le agregas como variable global solamente puede valer alli y entonces cuando las llamas causarian algun error.

La variable global es accedida desde todos los ambitos. Puedes usar la palabra global $nombre_tu_variable, para convertir esa variable con ambito global en caso de que tenga otro ambito.

Hasta aqui la parte 3 de PHP, espera la parte 4, dejame tu comentario si tienes dudas o si crees que le falto algo mas y podria incluirlo en la siguiente parte, un saludo :)

lunes, 19 de mayo de 2014

[Parte 2] PHP

Crear un formulario HTML

Para crear un formulario solo necesitamos conocimiento de HTML. Un formulario se crea de la siguiente manera:


 <!DOCTYPE html>
<html>
<head>
 <title>Formulario a procesar</title>
 <meta charset="utf-8">
</head>
<body>
 <form action="" method="post">
  <!-- Aqui dentro van los inputs, selects, checkboxes, radiobuttons, etc -->
 </form>
</body>
</html>

En el formulario tenemos dos cosas importantes:

1.- action = En este atributo se indica a donde son enviados los datos para que sean procesados, en este caso debe ser un script PHP

2.- method = Este atributo se indica como los datos seran enviados. Existen dos metodos POST y  GET.
GET - Se envia por la URL (las variables se ven reflejadas en la url)
POST - Se envian por las cabeceras de manera que no se ven en la URL, sino que se envian ocultos de cierta forma (como vimos en las partes de seguridad en PHP veiamos como capturar las cabeceras con ello los formularios)

Lo bueno que tiene el metodo GET es que es mas facil de comprender los datos que contiene la pagina, al igual que es una buena manera de que los buscadores te encuentren por algunas palabras que tengas en la URL, pero lo malo es que tiene un limite de caracteres (HTTP Error 414 Request URI Too Long, por ello es mejor enviar algunos tipos de datos por el metodo POST.



 <!DOCTYPE html>
<html>
<head>
 <title>Formulario a procesar</title>
 <meta charset="utf-8">
</head>
<body>

 <form action="" method="post">
  <h1>Deja tu opinion</h1>
  <p><input type="text" name="nombre" placeholder="nombre" /> <b>Nombre</b></p>
  <p><input type="email" name="email" placeholder="email" /> <b>Email</b></p>
  <p><input type="url" name="url" placeholder="url" /></p>
  <p><textarea rows="5" cols="35"></textarea></p>
  <p><input type="submit" name="enviar" value="Enviar Comentario" /></p>
 </form>
</body>

En la estructura anterior tenemos un formulario en el cual nos pide unos datos para comentar en una pagina web.

Tip: Si tu pagina solo utiliza HTML, entonces no es necesario que utilices la extension .php.

Procesar el formulario HTML

Para procesar un formulario tenemos de cierto modo que "atrapar" las entradas del mismo. Para ello no valemos de su atributo name el cual contiene el nombre de tal, en el ejemplo anterior teniamos algo como:



 <input type="text" name="nombre" placeholder="nombre" /> 


Atrapamos ese campo de entrada con el siguiente codigo:



 $nombre = $_REQUEST['nombre'];

En el cual tenemos una variable llamada "nombre" la cual puede tener cualquier valor, me refiero a que puede llamarse $nombreASD, $nombrefgh, o como tu quieras llamarlo, y tenemos otra variable superglobal llamada $_REQUEST la cual atrapa metodos como $_POST, $_GET y $_COOKIE. Con este codigo de arriba tendremos almacenado el valor del input en la variable llamada $nombre cuando el formulario sea procesado en el archivo que se especifique en action.


Magic Quotes


Cuando estan habilitadas escapa automaticamente las comillas simples y dobles (',") al igual que las barras (\) y caracteres NULL. 

Algo por lo que esta obsoleta esta caracteristica es que al tenerla habilitado muchas veces es necesario tener esas comillas simples, dobles o barras o caracteres NULL. Por lo que si se necesitara en realidad esta caracteristica se podria usar en ese caso la funcion stripslashes() - esta funcion quita las barras de un string con comillas escapadas o addslashes() - esta funcion escapa strings con barras invertidas  que tiene el mismo efecto.



 $barras = addslashes($_REQUEST['nombre'])


Condiciones y operadores

Los principales terminos para crear condicionales son if, else y elseif (este tambien puede ser escrito como else if), todas las condicionales comienzan con if:

if(condicion){ //¡Realizar algo!}

Y tambien pueden llevar la clausula else:

if(condicion){//¡Realizar algo!}else{//¡Realizar algo mas!}

Tambien podemos agregar mas de una condicion, con elseif:

if(condicion){//¡Realizar algo!}elseif{//¡Realizar algo mas!}else{//¡Realizar algo mas!}


-> Con if decimos que si la condicion es verdadera se ejecute lo que esta encerrado entre llaves...
-> Con else decimos que sino es verdad if se ejecute else 
-> Con else if, es como otro if, es decir es otra condicion mas ...

Operadores comparativos y logicos


Una condicion en PHP puede ser verdadera por cualquier numero de razones:

-> $variable, si $variable tiene otro valor que no sea 0, o una cadena vacia o FALSE, o NULL.
-> isset($variable), si $variable tiene otro valor que no sea NULL, 0, FALSE o una cadena vacia.
-> TRUE, true, True, etc.

Con la funcion isset() decimos que $variable sea un valor que no sea NULO y que la $variable exista o este establecida.

Veamos un ejemplo muy basico de una condicional:


 <form action="" method="post">
 <input name="acepto" type="submit"  value="Acepto entrar soy mayor de edad" />
 <input name="noacepto" type="submit" value="Soy menor de edad, me pegan mis padres si entro" />
</form>

<?php
 if (isset($_POST['acepto'])) {
  echo "Has aceptado esto es contenido privado :D";
 }elseif(isset($_POST['noacepto'])){
  echo "Nimodo que hacerle, si te PEGAN te PEGAN :(";
 }
 
?>



Switch

Cuando tienes un condicional if-elseif-else demasiado largo puedes usar Switch:



 switch ($variable) {
  case 'valor1':
   # codigo...
   break;
  case 'valor2':
   # codigo...
   break;
  case 'valor3':
   # codigo...
   break; 
  default:
   # codigo...
   break;
 }


El condicional Switch compara la $variable en diferentes casos, si el codigo es verdad y se ejecuta, ponemos un break para que este descanse, default es un valor por defecto se ejecuta si ninguno de los casos existe.

Validando los datos de un formulario

Podemos usar algunas funciones para validar algun formulario, como por ejemplo la funcion isset() que determina si una variable esta definida y no es NULL. O la funcion empty() que determina si una variable esta vacia. Veamos un ejemplo:


 <form action="" method="post">
<b>Cual es tu color preferido:</b><input type="text" name="color" /><br />
<input type="submit" name="enviar" />
</form>
<?php
 if(isset($_POST['enviar'])){
  if(!empty($_POST['color'])){
   $color = htmlentities($_POST['color']);
   switch ($color) {
    case 'rojo':
     $color = "red";
     echo '<div style="background-color:'.$color.';width:100px;height:100px"></div>';
     break;
    case 'amarillo':
     $color = "yellow";
     echo '<div style="background-color:'.$color.';width:100px;height:100px"></div>';
     break;
    case 'azul':
     $color = "blue";
     echo '<div style="background-color:'.$color.';width:100px;height:100px"></div>';
     break;
    case 'blanco':
     $color = "white";
     echo '<div style="background-color:'.$color.';width:100px;height:100px"></div>';
     break;
    case 'negro':
     $color = "black";
     echo '<div style="background-color:'.$color.';width:100px;height:100px"></div>';
     break;
    default:
     echo "Ese color no esta disponible, lo sentimos :(";
     break;
   }
  }else{
   echo "Por favor no deje el campo vacio.";
  }
 }
?>


Tip1: Podemos usar tambien alguna funcion como is_numeric() que comprueba si una variable es un numero o un string numerico.

Tip2: Tambien podriamos usar expresiones regulares en PHP, para hacer comparaciones o validar formularios, hay un tutorial dedicado a esto en este BLOG: http://www.arthusu.com.mx/2013/07/phpexpresiones-regulares-pcre.html

Tip3: Otra forma aunque no muy recomendable ya que se valida del lado del cliente, es utilizar INPUTS HTML5, para validar por ejemplo ya sean numeros de telefono, email, etc. Aunque como dije esto no es seguro, es mas seguro validar del lado del servidor, como hizo en su tutorial nuestro amigo rotceh: http://www.arthusu.com.mx/2013/10/porque-no-debes-validar-en-el-lado-del.html

Arrays

Los arrays puede contener varias piezas de informacion separada (ya sean numeros o cadenas), se estructura de forma clave-valor. Hay dos tipos de arrays: los que tienes indices numericos que tienen un numero en la clave del array, y los de indices asociativos que contienen una cadena en la clave del array. Veamos una tabla de ejemplo:

Tabla indices numericos:


Tabla indices asociativos:


En este caso para acceder al valor de un array por ejemplo Shinedown, en caso de que sea numerico seria de la siguiente manera:

$grupos_rock[1]; // accedemos de forma con indice numerico
$grupos_rock['S']; // accedemos de forma con indice asociativo

En este caso la variable $grupos_rock es un array.

PHP incluye varios arrays predefinidos llamados variables superglobales. Ellos son: $_GET, $_POST, $_REQUEST, $_SERVER, $_ENV, $_SESSION, $_COOKIE.

$_GET - Contiene informacion de alguna variable enviada por el metodo $_GET o por la URL
$_POST - Cotiene la informacion enviada desde algun formulario por el metodo $_POST o de manera Oculta (usando cabeceras)
$_REQUEST - Contiene informacion de los metodos $_GET, $_POST, $_COOKIE
$_SERVER - Contiene informacion acerca del servidor
$_ENV - Contiene informacion de variables de entorno
$_SESSION - Contiene informacion sobre las sesiones del usuario
$_COOKIE - Contiene informacion sobre las cookies del usuario

Un error muy comun al imprimir un array seria de manera que estamos usando entre comillas dobles (Ya que son las que interpretan nuestras variables, por que las simples la toman de manera literal). Es no encerrar entre llaves {} nuestro array, por ejemplo:



 <?php
 $grupos_rock = array("LP"=>"Linkin Park","S"=>"Shinedown","N"=>"Nirvana","MCR"=>"My Chemical Romance","FF"=>"Foo Figthers","TDG"=>"Three Days Grace","TK"=>"The Killers");
 echo "Uno de mis grupos de rock preferido es $grupos_rock['LP']";
?>


Esto daria un error como el siguiente:


La manera de corregirlo es encerrar con llaves el array:

 <?php
 $grupos_rock = array("LP"=>"Linkin Park","S"=>"Shinedown","N"=>"Nirvana","MCR"=>"My Chemical Romance","FF"=>"Foo Figthers","TDG"=>"Three Days Grace","TK"=>"The Killers");
 echo "Uno de mis grupos de rock preferido es {$grupos_rock['LP']}";
?>

Dando el resultado correcto o deseado que es valor de nuestro array:



Uno de mis grupos de rock preferido es Linkin Park

Crear un array

Crear un array no es nada del otro mundo, podemos crear un array definiendo elemento por elemento... por ejemplo:



En este caso para crear un array usamos los corchetes como clave ya sea asociativa o numerica (en caso de que sea numerica no es necesario agregar el numero ya va aumentando automaticamente)... Y para acceder usamos su $nombre_variable[clave_numerica] o $nombre_variable["clave_asociativa"] una cosa que debemos tener en cuenta es que si no comenzamos nuestro array con clave numerica desde 1 esta comenzara desde 0 automaticamente.

Como dijimos anteriormente en el caso anterior estabamos definiendo los arrays de elemento por elemento, pero se puede hacer de manera mas rapida y ordenada usando el constructor array().

En el codigo de arriba donde mostrabamos las llaves {} usabamos ese tipo de sintaxis para crear nuestro array con clave asociativa, creemoslo con clave numerica:




 <?php
 $grupos_rock = array(1=>"Linkin Park","Shinedown","Nirvana","My Chemical Romance","Foo Figthers","Three Days Grace","The Killers");
 echo "Uno de mis grupos de rock preferido es $grupos_rock[5]";
?>



Tambien podemos utilizar una funcion muy interesante como lo es range() que crea un array con un rango de elementos:

 
En este caso utilizamos la funcion print_r() para que imprima la informacion de manera que sea legible para humanos sobre una variable, esto pasa por que es un array ya que si usaramos echo solamente mostraria la palabra Array... En este caso podriamos recorrer el array mostrando valor por valor.

Accediendo a arrays de manera completa

Una manera de mostrar la clave y valor de un array es utilizar el constructor foreach() que proporciona un modo sencillo para iterar sobre arrays. Su sintaxis mas basica es:

foreach ($array as $valor){ // Hacer algo con $valor }

Un ejemplo, podriamos mostrar los meses usando un array:

Como puedes ver, esta es una manera de generar contenido dinamico de forma muy facil y tambien de mostrar los valores de un array, ahorrandonos codigo y haciendolo simple, como dijimos en los capitulos de seguridad en php "lo simple es bello" :D.

Arrays multidimensionales

Un array multidimensional es un array y dentro de el contiene otro array, esto es creado cuando tenemos mucha cantidad de informacion que agregar, y la queremos dividir por grupo, por ejemplo:



Como ves incluimos un array dentro de otro y accedemos a el de la misma manera, primero al array grupo dentro de el se encuentra otra llave que seria 0 para linkin park y 1 para shinedown...

Por que como deciamos anteriormente cuando no le damos la clave a un array comienza desde 0.


Tip1: Para contar los elementos de un array podemos utilizar la funcion count(), echo count($nombre_array); // $numero de elementos del array

Tip2: Con la funcion is_array() podemos comprobar si una variable es un array, de la siguiente manera: is_array($nombre_array).

Algunas cosas interesantes mas sobre arrays


Podemos crear un array utilizando alguna cadena junto con su separador, un ejemplo seria el siguiente:



Con la funcion explode() lo que hacemos es primero ingresarle un delimitador (en este caso - ) y luego la cadena (en este caso $usuarios_most) lo que nos crearia un array cortando valor a valor usando el delimitador.

La funcion inversa a explode seria implode() que une los elementos de un array en un string.

Tambien podemos ordenar nuestros arrays utilizando por ejemplo la funcion sort() ordena un array de menor a mayor. Ejemplo:

echo sort($nuestro_array);

La funcion shuffle() al contrario de la funcion sort() mezcla un array de manera aleatoria...

echo shuffle($nuestro_array);

Otro ejemplo es usar un array en un formulario de manera que podamos seleccionar multiples opciones y mostrarlas... obteniendo un array multidimensional:


Repeticiones for y while

Cuando accedimos a un array de manera completa utilizamos una repticion foreach. En este caso mostraremos el uso de las repeticiones o bucles for y while.

La sintaxis de la repeticion while es de la siguiente manera:


while(condicion) {//Hacer algo}

Que significa que mientras la condicion sea verdadera realice lo que esta entre las llaves. 
La sintaxis de la repeticion o bucle for es un poco mas complicada:

for (valor inicial, condicion, aumento o decremento ){//Hacer algo}

Esto significa algo como lo siguiente: para valor incial mientras la condicion se cumpla se repite hasta que deje de ser verdadera y esta va aumentando o decrementando con el paso de la repeticion.

Un ejemplo muy basico seria mostrar el numero de dias que tienes un mes, que por lo general son 30:



O tambien podriamos hacer lo mismo con el bucle while:


Ahora te estaras preguntando ¿Que diferencia hay, cual uso? Pues la experiencia revela que el bucle for se utiliza cuando sabes el numero de veces que quieres repetir determinada accion y el bucle while es utilizado cuando la condicion debe ser verdadera y no sabes el numero de veces que se tiene que repetir. Entonces solo te debes adaptar a esos dos tipos de ambientes.

Nota importante: En PHP tambien existe el bucle do...while



La diferencia de este bucle al de while es que esta es verificada al final de cada iteracion en lugar de al principio.

Hasta aqui terminamos la parte 2 de php espero que les haya gustado, nos vemos en la tercera parte, intente hacer esta parte lo mas corta posible para que no se les hiciera tan aburrido. Si les gusto dejen su comentario eso me ayuda a seguir publicando :P