User Tools

Site Tools


es:web_development:forms:insert

This is an old revision of the document!


Desarrollo Web Lección 8 - Formularios

INSERT Consultas

Objetivo

  • En esta actividad aprenderá cómo obtener datos de un formulario e insertarlos en una tabla de base de datos.

Configuración

  • Continuaremos usando 'form.php' y 'process_form.php'. Si necesitas el código de nuevo, aquí está.

INSERTAR Consulta

  • Para ver cómo funciona esto, comenzaremos en PHPMyAdmin.
  • Inicie sesión y abra la tabla 'héroes' en la base de datos 'webdev'.
  • Abra la pestaña 'Insertar'.
  • Observe que cada uno de los campos de nuestra tabla está representado por una fila.
  • Elija un héroe/villano de la siguiente lista y agréguelo a la tabla. Si estás trabajando en una clase, cada uno elige un personaje diferente.
aliasidentityhero_villainfirst_appearedpower
ThorThor OdinsonHero1962Magic
Red SkullJohan SchmidtVillain1941Biological
Bucky BarnesWinter SoldierVillain1941Tech
Clint BartonHawkeyeHero1969Skill
OdinOdinHero1962Magic
Nick FuryNick FuryHero1963Skill
Phil CoulsonAgent CoulsonHero2008Skill
Peter QuillStarlordHero1976Tech
GamoraGamoraHero1975Skill
Pepper PottsRescueHero1963Tech
  • Ingrese la información de su héroe en los campos apropiados en la columna 'Valor' y presione 'Ir'.
  • Vea la consulta utilizada para agregar los datos justo debajo de la fila amarilla en la parte superior de la página.
INSERT INTO `heroes` (`alias`, `identity`, `hero_villain`, `first_appeared`, `power`) VALUES ('Bucky Barnes', 'Winter Soldier', 'Villain', '1941', 'Tech'); 
  • Este es el formato que debemos usar para nuestra consulta de inserción en 'process_form.php'.
  • Una consulta INSERT siempre comienza con 'INSERT INTO' y el nombre de la tabla que usaremos, luego una lista de los campos que queremos agregar.
  • Esto es seguido por 'VALORES' y una lista de los valores a ser insertados.

Declaración de 'Switch'

  • Recuerde que en realidad tenemos dos formularios enviados a esta página mediante dos botones de envío.
  • Podemos identificar qué formulario procesar por el valor de '$_POST['submit']'.
  • Podríamos hacer esto con una declaración 'si', como esta.
    switch ($variable) {
        case 'value':
            # code...
            break;
        
        default:
            # code...
            break;
    }
  • Esto funcionaría, pero hay una mejor manera.
  • Una 'sentencia switch' no es tan flexible como una 'sentencia if', que permite condiciones completamente nuevas en cada línea, pero es más potente a su manera.
  • Abra 'process_form.php' en Visual Studio Code.
  • Al final del primer bloque de PHP, escriba 'cambiar' y seleccione la segunda opción. Agregará el siguiente código automáticamente.
switch ($edad) {
    case 1:
    case 17:
    case 43:
        # code...
        break;
    case 22:
    case 39:
        # code...
        break;
}
  • Queremos ejecutar una consulta diferente dependiendo del valor de $_POST['submit'], así que reemplace '$variable' con $_POST['submit'].
  • Ahora configure un caso para 'Agregar héroe' y 'Agregar apariencia'.
    switch ($_POST['submit']) {
        case 'Agregar Héroe':
            break;
        case 'Agregar apariencia':
            break;
        default:
            break;
    }
  • Inserte nuestro código que usamos para ejecutar consultas de base de datos después de case 'Agregar Héroe':.
            $query = "";
            $args  = array();
            $rslt  = $pdo->prepare($query);
            $rslt->execute($args)
  • Ahora podemos copiar nuestra consulta de PHPMyAdmin a la cadena de consulta.
  • Debido a que los piratas informáticos pueden realizar una “inyección SQL” para obtener información sobre su base de datos o incluso para agregarse como un usuario administrador agregando código SQL como datos, vamos a eliminar los datos de nuestra consulta.
  • Reemplace cada valor con ? luego agregue la entrada de usuario respectiva como elementos en la matriz '$args'.
            $query = "INSERT INTO `heroes` (`alias`, `identity`, `hero_villain`, `first_appeared`, `power`) VALUES (?,?,?,?,?)";
            $args  = array($_POST['alias'], $_POST['identity'], $_POST['alias'], $_POST['side'], $_POST['year'], $_POST['power']);
  • Este código funcionará a menos que haya un problema para acceder a la base de datos o una entrada de usuario no válida.
  • Como queremos saber si hay un problema y decirle al usuario, agreguemos una verificación.
  • Cambie $rslt->execute($args) a lo siguiente.
            if ($rslt->execute($args)) {

            } else {
            
            }
  • Agregue un mensaje en este bloque de código.
            if ($rslt->execute($args)) {
                $message = "{$_POST['name']} was inserted successfully.";
            } else {
                $message = "There was a problem inserting {$_POST['name']}.";
            }
  • El primer mensaje se mostrará cuando la consulta se haya ejecutado correctamente.
  • El segundo mensaje se mostrará si no lo fue.

Insertos Múltiples

  • El formulario Agregar apariencias permite al usuario agregar varias películas, pero cada una es su propia línea en la tabla de la base de datos.
  • Podríamos crear una consulta separada para cada película, pero también es posible agregar varias líneas en la misma consulta haciendo algo como esto.
INSERT INTO appearances (character_name, movie) VALUES ('Thor Odinson', 'Thor: Dark World'), ('Thor Odinson', 'Avengers: Age of Ultron')

Empuje de Matriz

  • Dejemos la consulta para el final porque necesitaremos filtrar las apariencias ya existentes.
  • Primero, construyamos nuestro conjunto de argumentos: un par para cada película.
  • Cada par de argumentos es el nombre de nuestro héroe y el nombre de la película, lo que podemos hacer en 'foreach' bucle.
            foreach($_POST['movie'] as $movie) {

            }
  • Y podemos agregarlos a una matriz existente usando la 'array_push' función.
                        array_push($args, $_POST['hero'], $movie);
  • El primer parámetro de esta función debe ser una matriz, y los valores posteriores se agregan al final de la matriz.
  • Por supuesto, primero debemos crear la matriz, y no queremos que se vuelva a crear cada vez que hacemos un bucle, por lo que debemos crearla antes foreach.
            $args = array();
            foreach($_POST['movie'] as $movie) {
                        array_push($args, $_POST['hero'], $movie);
            }
  • Pero no queremos agregar películas que ya están incluidas en la base de datos, por lo que primero debemos verificar si existen.
                    // check if it exists already
                    $mquery = "SELECT * FROM appearances WHERE character_name=? AND movie=?";
                    $margs  = array($_POST['hero'], $movie);
                    $rslt  = $pdo->prepare($mquery);
                    $rslt->execute($margs);
                    if (!$row = $rslt->fetch()) {
                        array_push($args, $_POST['hero'], $movie);
                    }
  • ¿Puedes leer este código por ti mismo?
  • $mquery es la consulta que pregunta si el par héroe/película ya existe.
  • $margs es la matriz de parámetros para la consulta.
  • Luego ejecutamos la consulta y, si no existe (if (!$row = $rslt->fetch())), la agregamos a la lista de argumentos.
  • ¿Y si es una nueva película? No queremos agregar la palabra 'nuevo' como título de la película. Tenemos que cambiarlo a $_POST['new_movie'] su lugar.
  • Verifiquemos usando una 'sentencia if'.
                if ($movie == 'new') {
                    array_push($args, $_POST['hero'], $_POST['new_movie']);
                } else {
                    // check if it exists already
                    $mquery = "SELECT * FROM appearances WHERE character_name=? AND movie=?";
                    $margs  = array($_POST['hero'], $movie);
                    $rslt  = $pdo->prepare($mquery);
                    if (!$rslt->execute($margs)) {
                        array_push($args, $_POST['hero'], $movie);
                    }
                }
  • Si es nuevo, lo usamos $_POST['new_movie']como el nombre de la película en lugar del valor almacenado en $_POST['movie'].

Contar

  • Podríamos haber creado la consulta primero y agregado piezas en el bucle, pero hay una forma más elegante.
  • Si sabemos cuántas películas se han agregado, simplemente podemos agregar el número correcto (?,?) al final de la consulta.
  • Podemos obtener el número de elementos en la $args matriz usando count y luego reducirlo a la mitad.
  • count es como .length en Javascript, contando el número de elementos en una matriz.
  • Agregue el siguiente código después del foreach bucle.
            $movies = count($args)/2;

Cadena Repetitiva

  • Luego, debemos agregar exactamente esa cantidad de copias de (?,?) al final de la consulta, pero deben estar separadas por un , .
            $values = str_repeat('(?,?), ', $movies-1) . '(?,?)';
  • Esta técnica utiliza una función llamada str_repeat para repetir una cadena establecida varias veces. Si repetimos '(?,?),' el número correcto de veces, tendríamos un colgante , al final que provocaría un error. En cambio, agregamos uno menos que la cantidad requerida ( count($movies) -1), luego agregamos (?,?) al final.
  • Ahora, nuestra consulta es:
            $query = "INSERT INTO heroes ('alias', 'movie') VALUES $values";
  • Antes de ejecutar nuestra consulta, debemos verificar que el código funcione, que tanto la consulta como los argumentos se vean como deberían.
  • Agregue lo siguiente antes de break.
            error_log("MURRAY: $query\n" . print_r($args, 1);
  • Guarde y cargue el código, luego abra 'form.php' en su navegador.
  • Elija un héroe y seleccione una serie de películas, incluida la nueva. Ingrese una película que aún no esté en nuestra lista en ningún lugar y haga clic en 'Agregar apariencia'.
  • Ahora verifique los registros de errores en Putty.
  • Si la matriz de consultas y argumentos se ve bien, es hora de enviarlos a la base de datos.
                $rslt  = $pdo->prepare($query);
                if ($rslt->execute($args)) {
                    $message = "$movies appearances were inserted successfully.";
                } else {
                    $message = "There was a problem inserting $movies appearances.";
                }
  • Este código también incluye la verificación para ver si la consulta fue exitosa y agrega un mensaje apropiado en cualquier caso.
  • Guarde y cargue su código, luego abra 'form.php' y envíe algunas apariencias nuevas para verificar que todo funcione.
  • El único problema que aún tenemos es que si el usuario solo agrega películas que ya están en la base de datos, estamos creando una consulta e intentando enviarla sin valores.
  • Arreglemos eso deteniéndonos si no hay nuevas películas para agregar.
            if ($movies > 0) {
                $values = str_repeat('(?,?), ', $movies-1) . '(?,?)';
                $query = "INSERT INTO appearances (alias, movie) VALUES $values";
                error_log("MURRAY: $query    " . print_r($args, 1));
                $rslt  = $pdo->prepare($query);
                if ($rslt->execute($args)) {
                    $message = "$movies appearances were inserted successfully.";
                } else {
                    $message = "There was a problem inserting $movies appearances.";
                }
            } else {
                $checked = count($_POST['movie']);
                $message = "All $checked appearances are already in the database.";
            }
  • En lugar de referirme a $movies, que será 0 en este caso, cambié el mensaje para que se refiera al número original de películas enviadas e indique que ya estaban todas en la base de datos.
  • Esta ha sido una gran actividad, pero hay más que hacer en la próxima actividad.

Codigo Final

es/web_development/forms/insert.1657135903.txt.gz · Last modified: 2023/08/16 09:33 (external edit)