Curso PHP 5 VI || Aprendamos sobre Formularios

Actividades V

Crea un programa en PHP a forma de calculadora utilizando el mínimo de funciones posible.


<?php 

function calcula($num, $oper, $num2) { 
    switch (
$oper) { 
     
        case 
'+': 
            
$res = $num + $num2; 
        break;; 
        case 
'-': 
            
$res = $num - $num2; 
        break;; 
        case 
'*': 
            
$res = $num * $num2; 
        break;; 
        case 
'/': 
            
$res = $num / $num2; 
        break;; 
        case 
'%': 
            
$res = $num % $num2; 
    } 
    return 
$res; 
} 

echo 
calcula(2,'+',2); # Resultado: 4 
?> 



Crea un programa en PHP en el que tengas que exponer todo lo aprendido en este apartado
Este ejercicio era bastante libre, y podíais aplicar todo lo aprendido o solo lo de la última clase. Aquí las soluciones son infinitas.


<?php 

$message 
= "Este es mi mensaje! saludos, nax"; 

$fake = givetome($message, "nax", "thief"); 
echo 
$fake; 

function 
givetome($original, $autor, $ladron) { 
    
$original = explode(' ', $original); 
    if (
in_array($autor,$original)) 
        
$original[array_search($autor,$original)] = $ladron;     
    return 
implode(' ',$original); 
} 
?> 


Este ejemplo toma un mensaje original y cambia el autor por el que le indicamos, un ejemplo como cualquier otro que me hayas enviado.

VIII. Introducción a los formularios


Ya hemos dado todos los puntos que me había propuesto para este tutorial/curso, por lo tanto voy a dar una clase práctica de integración con formularios y ya doy por cerrado este curso.

Por supuesto seguiré trayendo cosas tanto en Bl4ck-P0rt4l y CUH como en mi blog. Así que si seguís interesados en el mundo de PHP y sus áreas derivadas no os alejéis mucho.

Empecemos por el principio:

Un formulario web es, a día de hoy, un elemento imprescindible para una página web dinámica, gracias a ellos podemos loguear y registrar usuarios, enviar mensajes, publicar encuestas, comentarios, etc.
Por lo tanto conocer su funcionamiento y proporcionar facilidades a los usuarios es una tarea importante en el desarrollo web.
Hay mucha gente, quizá por comodidad o facilidad, que crea un .html para los formularios y un .php para el código, yo tengo por costumbre hacerlo todo en vista de código y por lo tanto siempre lo hago todo en un .php así que vamos a aprender a hacerlo de esa forma.

Un simple formulario:

Vamos a ver un ejemplo simple.


<?php 

if (isset($_POST['nombre'])) { 
    echo 
"Bienvenido ". $_POST['nombre']; 
} else { 
    echo 
'<form action="'.$_SERVER['PHP_SELF'].'" method="post"> 
          Bienvenido desconocido por favor dinos tu nombre: 
          <input name="nombre" type="text" /> 
            <input type="submit" name="Submit" id="button" value="Enviar" /> 
          </form>'
; 
} 
?> 


Este es un ejemplo muy claro, una página que se envía un form a sí mismo.
El if() comprueba que se haya enviado la variable, en caso de ser así es porque se nos ha enviado un nombre para mostrar, sino, mostramos el formulario pidiéndole que nos dé su nombre.

En este ejemplo ya podemos destacar dos cosas, la variable $_SERVER y la variable $_POST, como ya comenté anteriormente la variable $_SERVER es una variable propia del sistema PHP lo mismo pasa con $_POST ambas tienen su función y existen más variables de servidor que explicaremos a continuación.

Variables de Servidor útiles:

La variable $_SERVER contiene un montón de elementos más, pero nos vamos a centrar en aquellos que nos puedan ser de mayor utilidad.

Elemento Ejemplo Descripción
PHP_SELF /pagina.php Nos devuelve la ruta de la página en que se ejecuta
QUERY_STRING id=3&post=4 Es la parte que vemos en la url (store.php?id=3)
PATH_INFO pagina.php?/browse Es parecido a lo anterior pero con directorios
SERVER_NAME http://www.bl4ck-p0rtal.org Nombre del servidor que ejecuta el intérprete
DOCUMENT_ROOT /usr/local/htdocs Ruta local de la carpeta html
REMOTE_ADDR 175.56.23.2 IP del usuario/cliente
REMOTE_HOST pool.cvx.dialup.. Nombre del host del usuario/cliente
HTTP_REFERER foro.el-hacker.com Si se hizo clic para llegar al link esta variable lo contiene
HTTP_USER_AGENT Mozilla/4.0… Información del navegador y sistema operativo.

Os invito a probar el resto estas son, quizá, las más utilizadas.

Procesando y accediendo a los parámetros de los documentos:

Los formularios funcionan con dos métodos POST y GET.
La principal diferencia entre ambos (y las que nos interesa ahora) es que POST se envía en segundo plano y GET se puede ver fácilmente en la barra de direcciones (esto no implica que los POST no se puedan ver, solo que es más ‘dificil’).

Entonces te preguntarás ¿y porqué existe GET si POST es claramente mejor? Bueno, mi profesor de PHP me enseñó en su momento que en PHP si hay 2 formas de hacer las cosas siempre prevalece la mejor y la otra se elimina de el intérprete, pero en el caso de que ambas formas sean útiles en determinados momentos se mantienen ambas. Es decir, un POST es útil con un formulario que, por ejemplo envía una contraseña para que no se vea en la URL, pero sin embargo no podemos enviar datos a otra página (o a la misma) sin usar un formulario y en ese momento es GET el que entra en acción.

Un claro ejemplo de variables GET son los foros SMF todo lo que va detrás de .php? se está enviando vía GET.

Entonces, como conclusión usaremos POST para los formularios y GET para las url. En php accedemos a los métodos con $_POST y $_GET. En los formularios el parámetro name es el que marca el nombre que tendrá en el $_POST o $_GET.

Los elementos de múltiples valores serán enviados como un array:

<?php 

if (isset($_POST['nombre'])) { 
    echo 
"Bienvenido ". $_POST['nombre'] . 
    
'<br />Hoy quieres comer: ' . $_POST['food'][0] .  

    ' y ' . $_POST['food'][1]; 
} else { 
    echo 
'<form action="'.$_SERVER['PHP_SELF'].'" method="post"> 
          Bienvenido desconocido por favor dinos tu nombre: 
          <input name="nombre" type="text" /> <br /> 
            
         <select name="food[]" multiple> 
             <option value="Fideos"> Fideos </option> 
            <option value="carne"> Carne </option> 
            <option value="pescado"> Pescado </option> 
         </select> 
          
         <br /><input type="submit" name="Submit" id="button" 

         value="Enviar" /> 
         </form>'
; 
} 
?> 



Como veis en el form agregamos una lista en la cual al nombre ya le indicamos que será un array con los signos [] y le damos el parámetro múltiple.

En el ejemplo estamos dando por supuesto que se recibirán 2 parámetros, para asegurarnos de ello deberíamos crear una función en JS para asesorarnos que es así.

Comprobar direcciones de correo:

Como este último capitulo pretende ser un repaso muy por encima de los formularios no voy a hablar de validación de datos, pero si os voy a dejar la forma de validar, en parte, un correo electrónico.

Luego, cuando estéis más acostumbrados a PHP se puede verificar que estos correos existan de verdad haciendo consultas whois y cosas por el estilo. Pero con este ejemplo nos aseguraremos de que al menos la sintaxis del correo sea correcta

<?php 

if (! preg_match('/^[^@s]+@([-a-z0-9]+.)+[a-z]{2,}$/i', $_POST['email'])) { 
    
$errores[] = 'Introduce un email valido'; 
?> 


Valores por defecto:

Al principio hablábamos de dar comodidad al usuario. Una de las formas de hacerlo es recordando los datos que se ingresaron y en caso de haber algún error rellenar los datos que el usuario tiene bien y otra forma es crear valores por defecto a modo de ejemplo.

<?php 

if ($_POST['_check']) { 
    
$defaults = $_POST; 
} else { 
    
$defaults = array( 'nombre' => 'nax', 
                        
'edad'  => '20', 
                        
'ciudad' => 'Villanax' ); 
} 
?> 


Con este ejemplo tenemos una variable llamada _check que en caso de no existir significa que no se envió un formulario y por lo tanto nombramos nuestros valores por defecto, sino lo que estaríamos haciendo es guardar los valores enviados.

Para establecer valores por defecto es imperativo hacer los form en PHP. Un ejemplo de cómo se cargarán dichos valores es:

<?php 

if ($_POST['_check']) { 
    
$defaults = $_POST; 
} else { 
    
$defaults = array( 'nombre' => 'nax', 
                        
'edad'  => '20', 
                        
'ciudad' => 'Villanax' ); 
} 
echo 
'<form action="'.$_SERVER['PHP_SELF'].'" method="post">  
          Bienvenido desconocido por favor dinos tu nombre:  
          <input name="nombre" type="text" value="'
. 

          $defaults['nombre'].'" /> <br />  
             
          Edad: <input name="nedad" type="text" value="'
. 

          $defaults['edad'].'" /> <br /> 
           
          Ciudad: <input name="ciudad" type="text" value="'
.

          $defaults['ciudad'].'" /> <br /> 
          <br /><input type="submit" name="Submit" 

          id="button" value="Enviar" /> 
          </form>'
; 
?> 


Con esta buena práctica ahorramos muchos dolores de cabeza a las personas con tendencia a equivocarse en los formularios de registro por ejemplo, y si... lo digo por experiencia propia.


Y bien, con este último capítulo doy por concluido el tutorial de PHP 5. Gracias a todos los que lo han ido siguiendo día a día, a los que enviaron los ejercicios y a los comentarios de crítica (tanto buenos como malos).
Si creen que falta algo o creen que sería bueno ampliar alguna parte del tutorial solo háganmelo saber.

Para:
~ Syntax Error ~
Bl4ck~P0rtal -
http://foro.el-hacker.com

Saludos Nax.


Version .doc:Formularios.doc
Version .pdf: Formularios.pdf

Bug en Mysql en tipos BINARY, VARCHAR, CHAR

Como un artículo anterior este viene de la mano de ^Tifa^ y como su descubridora todos los méritos a su persona.

El escenario




mysql> CREATE TABLE ejemplo(
    -> nombres BINARY(20));
Query OK, 0 rows affected (0.39 sec)
 
mysql> INSERT INTO ejemplo VALUES('Juan'),('Pepe'),('Jose');
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0
 
mysql> SELECT * FROM ejemplo;
+----------------------+
| nombres              |
+----------------------+
| Juan                 |
| Pepe                 |
| Jose                 |
+----------------------+
3 rows IN SET (0.00 sec)
 
 
Ese es el escenario.
Ahora una actualización de datos:
mysql> UPDATE ejemplo SET nombres = 'Carlos' WHERE nombres = hex('Juan');
Query OK, 0 rows affected (0.00 sec)
Rows matched: 0  Changed: 0  Warnings: 0
 
mysql> UPDATE ejemplo SET nombres = 'Carlos' WHERE nombres = 'Juan';
Query OK, 0 rows affected (0.00 sec)
Rows matched: 0  Changed: 0  Warnings: 0
 
mysql> DELETE FROM ejemplo WHERE nombres = 'Pepe';
Query OK, 0 rows affected (0.00 sec)
 
mysql> SELECT * FROM ejemplo;
+----------------------+
| nombres              |
+----------------------+
| Juan                 |
| Pepe                 |
| Jose                 |
+----------------------+
3 rows IN SET (0.00 sec) 

Como se aprecia ni se actualiza ni se borra...

Intentamos solucionar el tema con un alter:

 
mysql> DESCRIBE ejemplo;
+---------+------------+------+-----+---------+-------+
| FIELD   | Type       | NULL | KEY | DEFAULT | Extra |
+---------+------------+------+-----+---------+-------+
| nombres | BINARY(20) | YES  |     | NULL    |       |
+---------+------------+------+-----+---------+-------+
1 row IN SET (0.00 sec)
 
mysql> ALTER TABLE ejemplo MODIFY nombres varchar(25);
Query OK, 3 rows affected (0.45 sec)
Records: 3  Duplicates: 0  Warnings: 0
 
mysql> UPDATE ejemplo SET nombres = 'Carlos' WHERE nombres = 'Juan';
Query OK, 0 rows affected (0.00 sec)
Rows matched: 0  Changed: 0  Warnings: 0
 
mysql> DELETE FROM ejemplo WHERE nombres = 'Pepe';
Query OK, 0 rows affected (0.00 sec)
 
mysql> SELECT * FROM ejemplo;
+----------------------+
| nombres              |
+----------------------+
| Juan                 |
| Pepe                 |
| Jose                 |
+----------------------+
3 rows IN SET (0.00 sec)
 
 
ni por ahí...
Esto también se aplica también a tablas con datos tipo char, varchar,etc 
si se altera a binary.
 
mysql> CREATE TABLE ejemplo2(
    -> nombres varchar(20));
Query OK, 0 rows affected (0.38 sec)
 
mysql> INSERT INTO ejemplo2 VALUES('pepe'),('Juan'),('pedro'),('luis');
Query OK, 4 rows affected (0.00 sec)
Records: 4  Duplicates: 0  Warnings: 0
 
mysql> SELECT * FROM ejemplo2;
+---------+
| nombres |
+---------+
| pepe    |
| Juan    |
| pedro   |
| luis    |
+---------+
4 rows IN SET (0.00 sec)

Un ejemplo con varchar funcionando perfectamente

mysql> UPDATE ejemplo2 SET nombres = 'Cucu' WHERE nombres = 'pepe';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0
 
mysql> SELECT * FROM ejemplo2;
+---------+
| nombres |
+---------+
| Cucu    |
| Juan    |
| pedro   |
| luis    |
+---------+
4 rows IN SET (0.00 sec)
 
 
Ahora alteramos a Binary
mysql> ALTER TABLE ejemplo2 MODIFY nombres BINARY(20);
Query OK, 4 rows affected (0.27 sec)
Records: 4  Duplicates: 0  Warnings: 0
 
mysql> SELECT * FROM ejemplo2;
+----------------------+
| nombres              |
+----------------------+
| Cucu                 |
| Juan                 |
| pedro                |
| luis                 |
+----------------------+
4 rows IN SET (0.00 sec)
 
mysql> UPDATE ejemplo2 SET nombres = 'Marta' WHERE nombres = 'Cucu';
Query OK, 0 rows affected (0.00 sec)
Rows matched: 0  Changed: 0  Warnings: 0
 
 
se jodió la tabla...
volvemos a varchar
 
mysql> ALTER TABLE ejemplo2 MODIFY nombres varchar(20);
Query OK, 4 rows affected (0.10 sec)
Records: 4  Duplicates: 0  Warnings: 0
 
mysql> DESCRIBE ejemplo2;
+---------+-------------+------+-----+---------+-------+
| FIELD   | Type        | NULL | KEY | DEFAULT | Extra |
+---------+-------------+------+-----+---------+-------+
| nombres | varchar(20) | YES  |     | NULL    |       |
+---------+-------------+------+-----+---------+-------+
1 row IN SET (0.00 sec)
 
mysql> UPDATE ejemplo2 SET nombres = 'Marta' WHERE nombres = 'Cucu';
Query OK, 0 rows affected (0.00 sec)
Rows matched: 0  Changed: 0  Warnings: 0
 
Como se aprecia gracias al Changed: 0
no se actualizaron los datos pese a su tipo varchar.
 
 
Fuente original: Mini-Bug en Mysql 

Recuperar el password de MySQL en Windows

La información me llega desde elhacker.net de la mano de ^Tifa^.

Una de las posibles maneras de recuperar una contraseña en MySQL.

Lo vamos a explicar bajo una plataforma Windows.

Necesario:

- Ser administrador o privilegios de administrador.


Proceso:

- Inicio > ejecutar > cmd o win+R cmd

- Detenemos el Proceso de MySQL, esta parte depende de cada uno... si es un Cpanel o nuestro windows.

En windows puede hacerse así por ejemplo:
C:\> net stop mysql

- nos dirijimos a la carpeta de mysql/bin o si tenemos el path para usar mysql desde cualquier dirección (Tutorial aquí), escribimos:

c:\>cd path/to/bin

- ejecutamos la siguiente sentencia:
c:\> mysqld.exe -u root --skip-grant-tables

donde root es el usuario, pero va especialmente orientado a root.

- Ahora abrimos otra cmd y escribimos

c:\> mysql

- ya deberiamos haber logueado sin ningún tipo de problema.

- ahora ejecutamos una query para ver si el usuario existe realmente.
mysql> select user from mysql.user;

- y updateamos el campo password
mysql> update mysql.user set password = password('TU_NUEVA_CONTRASENA') where user = 'root';

- por último
mysql> flush privileges;

- ahora ya cerramos la anterior cmd e iniciamos el proceso mysql

c:\>net start mysql

Usar mySQL desde consola de comandos msdos

Bueno lo haremos con un XAMPP pero la idea es básicamente encontrar donde está el mysql.exe y hacer los mismos pasos.


Paso 1 Buscar myql.exe

Yo uso XAMPP instalado por default así que está aquí:

C:\xampp\mysql\bin
Paso 2: Agregar a variables de entorno

una ves con esta ruta vamos a:

inicio - mipc - propiedades - opciones avanzadas - variables de entorno

seleccionamos PATH y damos a modificar.

agregamos un ; y la ruta anteriormente citada a mi me quedaria así:


C:\Archivos de programa\Nmap;C:\xampp\mysql\bin
Aceptamos todo, y abrimos una cmd.


Paso 3: comandos básicos

Para entrar en MYSQL escribimos:


mysql -u usuario -p
(si no hay password no ponemos -p)

ya estamos en mysql modo consola

voy a listar una serie de comandos básicos de mysql, mas adelante pondré mas.

show databases;
muestra todas las BD


mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| cdcol              |
| main               |
| mydb               |
| mysql              |
| pbxt               |
| phpmyadmin         |
| scam               |
| smf_test           |
| users              |
| website            |
| z_test             |
+--------------------+
12 rows in set (0.00 sec)
use nom_db;
seleccionamos una DB.


mysql> use z_test;
Database changed
show tables;
mostramos todas las tablas.


mysql> show tables;
+------------------+
| Tables_in_z_test |
+------------------+
| monsters         |
| mvp              |
| players          |
+------------------+
3 rows in set (0.00 sec)
describe tabla;
hace una descripción de la tabla


mysql> describe monsters;
+-----------+--------------+------+-----+---------+----------------+
| Field     | Type         | Null | Key | Default | Extra          |
+-----------+--------------+------+-----+---------+----------------+
| id        | int(11)      | NO   | PRI | NULL    | auto_increment |
| monster   | varchar(100) | YES  |     | NULL    |                |
| dead      | int(11)      | YES  |     | NULL    |                |
| id_player | int(11)      | YES  |     | NULL    |                |
+-----------+--------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
select * from tabla;
vemos todo los datos de la tabla.


mysql> select * from monsters;
+----+-----------+------+-----------+
| id | monster   | dead | id_player |
+----+-----------+------+-----------+
|  1 | monster 1 |    0 |         1 |
|  2 | monster 2 |    5 |         1 |
|  3 | monster 2 |    4 |         2 |
|  4 | monster 1 |    0 |         2 |
+----+-----------+------+-----------+
4 rows in set (0.02 sec)
exit;
salir

mysql> exit
Bye
A partir de aquí simplemente hacemos consultas SQL. Hay algunos comandos interesantes pero lo dejaremos para otra ocasión.

No os olvideis de poner el punto y coma al final de las sentencias.

Curiosidad con tablas, echo y funciones en PHP

Después de varios días depurando las tablas SQL (os explicaré otro día dicho proceso) por fin empieza la etapa desarollo de un proyecto web.

El principal "problema" del proyecto es que tiene que ser compatible a SMF por lo que la metodología que usa es similar (que no igual).

El index.php trabaja de la siguiente forma:
- Carga unos textos
- Carga unas funciones básicas
- Carga las funciones gráficas y de procesos de la sección que se quiere acceder.
Para mostrarlo se llama a 3 procesos:
head(); middle(); foot();

La primera es variable según los metadatos y la última, en principio, es fija.
La que mas varía es la del medio.

head(): marca el principio de la tabla y la deja a medias para rellenarla con middle(), una vez que middle() acabó se llama a la función foot() que cierra todo.

Ahora, donde está la curiosidad? Esta está en middle(), al llamar a la función esta hace un echo con HTML y llama algunas funciones. Aquí viene el problema.

index.php
<?php
include_once('text.php');
include_once(
'functions/basic.php');
 
if (
$_GET['ac'] == 'news')
   include_once(
'news.php');
 
head(); //las 3 mas abajo
middle();
foot();
//no es exactamente así pero para que se entienda xD
?>


functions/basic.php

<?php

function head() {
      echo 
'los heads y el inicio de una tabla';
}
function 
foot() {
     echo 
'el final de la tabla y el pie de pagina';
} 
?>


news.php
<?php
 
function middle() {
 
echo 
'la continuacion de la tabla'.funcion().'cierro celdas'; //lo raro esta aqui
}
function 
funcion {
 echo 
'por ejemplo el contenido de la celda';
 
}
?>
 


como veis en news.php se concatena un string con una funcion que trae un string.
Bueno, ponga un echo o un return resulta que las tablas se descuadran totalmente y el código HTML se situa donde no debe ir.

Un par de imágenes para entenderlo:

asi está mal:


así esta bien:





como apreciais, al concatenar, el recuadro del menú se descuadra a una posición inferior y las tablas parecen no estar bien creadas.

Solución a esta curiosidad?

<?php echo 'la continuacion de la tabla'; funcion() ; echo 'cierro celdas'; ?>

en vez de concatenar echo lo que hacemos es separar sentencias con un ; y a otra cosa mariposa...