Diferencia entre revisiones de «PHP UD3 OP MODIFICAR»
| Línea 37: | Línea 37: | ||
=== Caso Práctico: Modificación === | === Caso Práctico: Modificación === | ||
| + | |||
| + | |||
| + | <br /> | ||
| + | ====Orientado a procedementos==== | ||
* Imos implementar esta opción na páxina '''consultar_estados.php''' continuando có visto [https://wiki.cifprodolfoucha.es/index.php?title=PHP_UD3_OP_ALTA na sección de ALTA]. | * Imos implementar esta opción na páxina '''consultar_estados.php''' continuando có visto [https://wiki.cifprodolfoucha.es/index.php?title=PHP_UD3_OP_ALTA na sección de ALTA]. | ||
: Se estamos a utilizar procedementos almacenados, lembrar que en caso de erro '2014 - Commands out of sync; you can't run this command now', debemos engadir a seguinte liña despois de chamar a un procedemento almacenado: | : Se estamos a utilizar procedementos almacenados, lembrar que en caso de erro '2014 - Commands out of sync; you can't run this command now', debemos engadir a seguinte liña despois de chamar a un procedemento almacenado: | ||
| − | :::<syntaxhighlight lang="java" | + | :::<syntaxhighlight lang="java" enclose="div" highlight="9" > |
if ($conex->multi_query($proc)){ | if ($conex->multi_query($proc)){ | ||
$result = $conex->store_result(); | $result = $conex->store_result(); | ||
| Línea 77: | Línea 81: | ||
<br /> | <br /> | ||
'''Posible solución Caso Práctico: Modificación''' | '''Posible solución Caso Práctico: Modificación''' | ||
| − | |||
'''Arquivo: bd.php''' | '''Arquivo: bd.php''' | ||
| − | ::<syntaxhighlight lang="java" | + | ::<syntaxhighlight lang="java" enclose="div" highlight="" > |
| − | define(' | + | define('CONSULTAR_ESTADO_POR_ID',"SELECT id,descripcion FROM estados WHERE id=%d"); |
define('ACTUALIZAR_ESTADO',"UPDATE estados set descripcion='%s' WHERE id=%d"); | define('ACTUALIZAR_ESTADO',"UPDATE estados set descripcion='%s' WHERE id=%d"); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
| Línea 87: | Línea 90: | ||
'''Arquivo: consultar_estados.php''' | '''Arquivo: consultar_estados.php''' | ||
| − | ::<syntaxhighlight lang="java" | + | ::<syntaxhighlight lang="java" enclose="div" highlight="39" > |
<?php | <?php | ||
/* Lembrar quitar isto ao probar o scripts sen erros */ | /* Lembrar quitar isto ao probar o scripts sen erros */ | ||
| Línea 143: | Línea 146: | ||
<div> | <div> | ||
<?php | <?php | ||
| − | if(isset($_GET['id'])) printf("<h3>Estado con id % | + | if(isset($_GET['id'])) printf("<h3>Estado con id %s dado de alta correctamente.</h3>",htmlentities($_GET['id'])); |
if(isset($_GET['msg'])) printf("<h4>%s</h3>",htmlentities($_GET['msg'])); | if(isset($_GET['msg'])) printf("<h4>%s</h3>",htmlentities($_GET['msg'])); | ||
if(isset($_GET['error'])) printf("<h2>Houbo un erro: %s</h2>",htmlentities($_GET['error'])); | if(isset($_GET['error'])) printf("<h2>Houbo un erro: %s</h2>",htmlentities($_GET['error'])); | ||
| Línea 171: | Línea 174: | ||
'''Arquivo: campos_estado.php''' | '''Arquivo: campos_estado.php''' | ||
| − | ::<syntaxhighlight lang="java" | + | ::<syntaxhighlight lang="java" enclose="div" highlight="2" > |
<label for="nombre">Descricción:</label> | <label for="nombre">Descricción:</label> | ||
<input type="text" maxlength="100" id="descripcion" name="descripcion" required value="<?php echo isset($descripcion) ? htmlentities($descripcion) : ''; ?>"><br> | <input type="text" maxlength="100" id="descripcion" name="descripcion" required value="<?php echo isset($descripcion) ? htmlentities($descripcion) : ''; ?>"><br> | ||
| Línea 179: | Línea 182: | ||
'''Arquivo: editar_estado.php''' | '''Arquivo: editar_estado.php''' | ||
| − | ::<syntaxhighlight lang="java" | + | ::<syntaxhighlight lang="java" enclose="div" highlight="" > |
<?php | <?php | ||
/* Lembrar quitar isto ao probar o scripts sen erros */ | /* Lembrar quitar isto ao probar o scripts sen erros */ | ||
| Línea 194: | Línea 197: | ||
<?php | <?php | ||
| − | $consulta = sprintf( | + | $consulta = sprintf(CONSULTAR_ESTADO_POR_ID,$conex->real_escape_string($_GET['id'])); |
$result=$conex->query($consulta); // Ven na URL da paxina listar_pistas.php | $result=$conex->query($consulta); // Ven na URL da paxina listar_pistas.php | ||
if ($result && $result->num_rows>0){ | if ($result && $result->num_rows>0){ | ||
| Línea 237: | Línea 240: | ||
'''Arquivo: procesar_editar_estado.php''' | '''Arquivo: procesar_editar_estado.php''' | ||
| − | ::<syntaxhighlight lang="java" | + | ::<syntaxhighlight lang="java" enclose="div" highlight="" > |
<?php | <?php | ||
/* Lembrar quitar isto ao probar o scripts sen erros */ | /* Lembrar quitar isto ao probar o scripts sen erros */ | ||
| Línea 257: | Línea 260: | ||
$desc_novo = $conex->real_escape_string(strtoupper($_POST['descripcion'])); | $desc_novo = $conex->real_escape_string(strtoupper($_POST['descripcion'])); | ||
if(strlen($desc_novo)<4 || strlen($desc_novo)>100){ | if(strlen($desc_novo)<4 || strlen($desc_novo)>100){ | ||
| − | $error=sprintf("error=O nome do estado non pode ter menos de 4 ou 100 caracteres"); | + | $error = sprintf("error=%s", urlencode("O nome do estado non pode ter menos de 4 ou 100 caracteres")); |
} | } | ||
else{ | else{ | ||
| Línea 264: | Línea 267: | ||
$conex->query($consulta); | $conex->query($consulta); | ||
| − | $msg = sprintf("msg=Estado actualizado correctamente."); | + | $msg = sprintf("msg=%s", urlencode("Estado actualizado correctamente.")); |
} | } | ||
} | } | ||
catch (mysqli_sql_exception $e) { | catch (mysqli_sql_exception $e) { | ||
| − | $error=sprintf("error='Erro mysql: %s'", | + | $error=sprintf("error='Erro mysql: %s'",urlencode($e->getMessage())); |
} | } | ||
catch (Expcetion $e) { | catch (Expcetion $e) { | ||
| − | $error=sprintf("error='Erro xeral: %s'", | + | $error=sprintf("error='Erro xeral: %s'",urlencode($e->getMessage())); |
} | } | ||
finally{ | finally{ | ||
| Línea 288: | Línea 291: | ||
| + | |||
| + | <br /> | ||
| + | ====Empregando PDO==== | ||
| + | * Imos implementar esta opción na páxina '''consultar_estados.php''' continuando có visto [https://wiki.cifprodolfoucha.es/index.php?title=PHP_UD3_OP_ALTA na sección de ALTA]. | ||
| + | |||
| + | |||
| + | * O que temos que facer é: | ||
| + | :* Definir no arquivo bd.php unha constante coa orde SQL para modificar o nome dun estado a partires dun id dado (clave primaria) | ||
| + | :* Modificar a páxina consultar_estados.php e engadir a opción 'Editar' a cada un dos estados. Debemos ir a unha páxina editar_estado.php. | ||
| + | :: O poderemos facer: | ||
| + | :* Cun enlace href, enviando como parámetro o id do estado a modificar. Eu vou escoller esta opción, pero sodes libres de practicar e intentalo coa outra opción. | ||
| + | :* Cun formulario e un campo oculto có id do estado a modificar. | ||
| + | :* A páxina editar_estado.php terá un formulario cun action a 'procesar_editar_estado.php'. Dentro do formulario fará un include do arquivo campos_estado.php que xa foi feito na páxina de alta de estados. | ||
| + | :: Tamén obterá os datos do estado a partires do id enviado polo enlace href ou polo formulario da páxina consultar_estados.php. Ditos datos serán gardados en variables e o nome será empregado pola páxina campos_estado.php. | ||
| + | :: Modificaremos a páxina campos_estado.php para que teña en conta os datos obtidos da consulta á base de datos. | ||
| + | $e->getCode():* Crear a páxina procesar_borrar_estado.php que dará de baixa o estado e se se produce algún erro deberá de informar á páxina de consultar_estados.php de cal foi o erro. Ao igual que na alta, poderemos enviar dita información nun parámetro na URL de redirección ou veremos nas seguintes seccións como empregar variables de sesión. | ||
| + | :: A xestión do erro en caso de querer borrar un rexistro relacionado non a imos facer. | ||
| + | :: Lembrar que dito control poderíamos facelo no propio procedemento almacenado/páxina php, capturando a excepción ou comprobando cun select previo se existe o rexistro relacionado. | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | <br /> | ||
| + | '''Posible solución Caso Práctico: Modificación''' | ||
| + | '''Arquivo: bd.php''' | ||
| + | ::<syntaxhighlight lang="java" enclose="div" highlight="" > | ||
| + | define('CONSULTAR_ESTADO_POR_ID',"SELECT id,descripcion FROM estados WHERE id=:id_estado"); | ||
| + | define('ACTUALIZAR_ESTADO',"UPDATE estados set descripcion=:descripcion WHERE id=:id_estado"); | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | |||
| + | |||
| + | '''Arquivo: consultar_estados.php''' | ||
| + | ::<syntaxhighlight lang="java" enclose="div" highlight="41" > | ||
| + | <?php | ||
| + | /* Lembrar quitar isto ao probar o scripts sen erros */ | ||
| + | ini_set('display_errors', 1); | ||
| + | ini_set('display_startup_errors', 1); | ||
| + | error_reporting(E_ALL); | ||
| + | |||
| + | require('/var/www/confBD/bd.php'); | ||
| + | |||
| + | try { | ||
| + | $dsn = sprintf("mysql:host=%s;dbname=%s;charset=utf8mb4", SERVIDOR, BD); | ||
| + | $conex = new PDO($dsn, USUARIO, PASSWORD); | ||
| + | $conex->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); | ||
| + | |||
| + | $erro = ""; // Variable que a usaremos para amosar os posibles erros controlados por nos que poidan darse. | ||
| + | ?> | ||
| + | |||
| + | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | ||
| + | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | ||
| + | <html xmlns="http://www.w3.org/1999/xhtml" lang="es" xml:lang="es"> | ||
| + | <head> | ||
| + | <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> | ||
| + | <title>Xestión de estados</title> | ||
| + | </head> | ||
| + | <body> | ||
| + | <form action="alta_estado.php" method="post"> | ||
| + | <button type="submit">Novo Estado</button> | ||
| + | </form> | ||
| + | <table border="1" style="margin-top:20px"> | ||
| + | <tr> | ||
| + | <th>Estado</th> | ||
| + | <th>Accións</th> | ||
| + | </tr> | ||
| + | <?php | ||
| + | $result=$conex->query(CONSULTAR_ESTADOS); // Temos que poñer prepare | ||
| + | if ($result && $result->rowCount() > 0) { | ||
| + | while ($row = $result->fetch(PDO::FETCH_ASSOC)) { | ||
| + | $nombre = htmlentities($row['descripcion']); | ||
| + | echo "<tr>"; | ||
| + | echo "<td>$nombre</td>"; | ||
| + | echo "<td>"; | ||
| + | printf("<a href='editar_estado.php?id=%s'>Editar</a>",urlencode($row['id'])); | ||
| + | echo("<form action='procesar_borrar_estado.php' method='post'>"); | ||
| + | printf("<input type='hidden' name='id' value='%s' />",htmlentities($row['id'])); | ||
| + | echo '<input onclick="return confirm(\'Estás seguro de que queres borrar este estado?\');" type="submit" value="Borrar" name="btnBorrarEstado" style="background:none;border:none;padding:0;margin:0;color: blue; text-decoration:underline; cursor:pointer; font-size:inherit" />'; | ||
| + | echo '</form>'; | ||
| + | echo "</td>"; | ||
| + | echo "</tr>"; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | $result = null; | ||
| + | ?> | ||
| + | </table> | ||
| + | |||
| + | |||
| + | <div> | ||
| + | <?php | ||
| + | if(isset($_GET['id'])) printf("<h3>Estado con id %s dado de alta correctamente.</h3>",htmlentities($_GET['id'])); | ||
| + | if(isset($_GET['msg'])) printf("<h4>%s</h3>",htmlentities($_GET['msg'])); | ||
| + | if(isset($_GET['error'])) printf("<h2>Houbo un erro: %s</h2>",htmlentities($_GET['error'])); | ||
| + | ?> | ||
| + | </div> | ||
| + | |||
| + | </body> | ||
| + | </html> | ||
| + | <?php | ||
| + | } // Pecha o try do principio da páxina | ||
| + | catch (PDOException $e) { | ||
| + | die("Erro PDO: " . $e->getMessage()); | ||
| + | } catch (Exception $e) { | ||
| + | die("Erro xeral: " . $e->getMessage()); | ||
| + | } finally { | ||
| + | $conex = null; // Pechar a conexión | ||
| + | } | ||
| + | ?> | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | '''Arquivo: campos_estado.php''' | ||
| + | ::<syntaxhighlight lang="java" enclose="div" highlight="2" > | ||
| + | <label for="nombre">Descricción:</label> | ||
| + | <input type="text" maxlength="100" id="descripcion" name="descripcion" required value="<?php echo isset($descripcion) ? htmlentities($descripcion) : ''; ?>"> | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | |||
| + | |||
| + | '''Arquivo: editar_estado.php''' | ||
| + | ::<syntaxhighlight lang="java" enclose="div" highlight="" > | ||
| + | <?php | ||
| + | /* Lembrar quitar isto ao probar o scripts sen erros */ | ||
| + | ini_set('display_errors', 1); | ||
| + | ini_set('display_startup_errors', 1); | ||
| + | error_reporting(E_ALL); | ||
| + | |||
| + | require('/var/www/confBD/bd.php'); | ||
| + | |||
| + | try { | ||
| + | $dsn = sprintf("mysql:host=%s;dbname=%s;charset=utf8mb4", SERVIDOR, BD); | ||
| + | $conex = new PDO($dsn, USUARIO, PASSWORD); | ||
| + | $conex->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); | ||
| + | |||
| + | $erro = ""; // Variable que a usaremos para amosar os posibles erros controlados por nos que poidan darse. | ||
| + | |||
| + | $stmt = $conex->prepare(CONSULTAR_ESTADO_POR_ID); | ||
| + | $stmt->bindValue(":id_estado", $_GET['id'], PDO::PARAM_INT); | ||
| + | $result = $stmt->execute(); | ||
| + | if ($result) { | ||
| + | $row = $stmt->fetch(PDO::FETCH_ASSOC); | ||
| + | $id = $row['id']; | ||
| + | $descripcion = htmlentities($row['descripcion']); | ||
| + | |||
| + | $stmt = null; | ||
| + | } else { | ||
| + | $erros = "Non se atopan os datos da pista!!!!"; | ||
| + | } | ||
| + | |||
| + | |||
| + | ?> | ||
| + | <!DOCTYPE html> | ||
| + | <html> | ||
| + | <head> | ||
| + | <title>Modificar Estado</title> | ||
| + | </head> | ||
| + | <body> | ||
| + | <h3>EDITAR ESTADO</h3> | ||
| + | |||
| + | <form method="POST" action="procesar_editar_estado.php"> | ||
| + | <?php include 'campos_estado.php'; ?> | ||
| + | <div> | ||
| + | <input type="hidden" name="id_orixinal" value="<?php echo $id; ?>"> | ||
| + | <input type="submit" value="Modificar" name="btnModificarEstado"> | ||
| + | </div> | ||
| + | </form> | ||
| + | <?php | ||
| + | if(!empty($erros)){ | ||
| + | printf("<h3>$erros</h3>"); | ||
| + | } | ||
| + | ?> | ||
| + | </body> | ||
| + | </html> | ||
| + | |||
| + | <?php | ||
| + | } // Pecha o try do principio da páxina | ||
| + | catch (PDOException $e) { | ||
| + | die("Erro PDO: " . $e->getMessage()); | ||
| + | } catch (Exception $e) { | ||
| + | die("Erro xeral: " . $e->getMessage()); | ||
| + | } finally { | ||
| + | $conex = null; // Pechar a conexión | ||
| + | } | ||
| + | ?> | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | |||
| + | |||
| + | '''Arquivo: procesar_editar_estado.php''' | ||
| + | ::<syntaxhighlight lang="java" enclose="div" highlight="" > | ||
| + | <?php | ||
| + | /* Lembrar quitar isto ao probar o scripts sen erros */ | ||
| + | ini_set('display_errors', 1); | ||
| + | ini_set('display_startup_errors', 1); | ||
| + | error_reporting(E_ALL); | ||
| + | |||
| + | require('/var/www/confBD/bd.php'); | ||
| + | |||
| + | try { | ||
| + | $dsn = sprintf("mysql:host=%s;dbname=%s;charset=utf8mb4", SERVIDOR, BD); | ||
| + | $conex = new PDO($dsn, USUARIO, PASSWORD); | ||
| + | $conex->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); | ||
| + | |||
| + | |||
| + | $error = ''; | ||
| + | $msg = ''; | ||
| + | if (isset($_POST['btnModificarEstado'])) { | ||
| + | |||
| + | $desc_novo = strtoupper($_POST['descripcion']); | ||
| + | if (strlen($desc_novo) < 4 || strlen($desc_novo) > 100) { | ||
| + | $error = sprintf("error=%s", urlencode("O nome do estado non pode ter menos de 4 ou 100 caracteres")); | ||
| + | } else { | ||
| + | $stmt = $conex->prepare(ACTUALIZAR_ESTADO); // Temos que poñer prepare | ||
| + | $stmt->bindValue(':id_estado', $_POST['id_orixinal'], PDO::PARAM_INT); | ||
| + | $stmt->bindValue(':descripcion', $desc_novo, PDO::PARAM_STR); | ||
| + | $result = $stmt->execute(); | ||
| + | |||
| + | if ($result) { | ||
| + | $msg = sprintf("msg=%s", urlencode("Estado actualizado correctamente.")); | ||
| + | } else { | ||
| + | $error = sprintf("error=$s", urlencode("Houbo un problema na actualización.")); | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | } catch (PDOException $e) { | ||
| + | $error = sprintf("error=PDO:%s", urlencode($e->getMessage())); | ||
| + | } catch (Exception $e) { | ||
| + | $error = sprintf("error=ERRO XERAL:%s", urlencode($e->getMessage())); | ||
| + | } finally { | ||
| + | $conex = null; // Pechar a conexión | ||
| + | } | ||
| + | $url = sprintf("consultar_estados.php?%s&%s", $msg, $error); | ||
| + | header("Location:" . $url); | ||
| + | |||
| + | </syntaxhighlight> | ||
| Línea 294: | Línea 540: | ||
| − | <br> -- [[Usuario:angelfg|Ángel D. Fernández González]] -- ( | + | <br> -- [[Usuario:angelfg|Ángel D. Fernández González]] -- (2025). |
Revisión del 17:08 6 nov 2025
Sumario
Introducción
- Requerimentos previos:
- Ter creada a base de datos indicada nunha sección anterior
- Ter gardados os parámetros de conexión nun arquivo separado como foi indicado nunha sección anterior
- Estes exercicios están baseados nunha versión de PHP 8.1 ou superior onde as ordes PHP para manexar a base de datos lanzan expcecións. Se tedes unha vesión anterior, teredes que facer o indicado na sección de consultas e na sección de conexión.
- NOTA IMPORTANTE: Vimos en seccións anteriores que cando empregmos datos dun formulario, existen unhas técnicas para evitar posibles ataques. Todos os exercicios que veñen a continuación empregan ditas técnicas. Existe un tipo de ataque que non se ten en conta ao non ter chegado á sección de emprego de variables de sesións. En dita sección se explica o que temos que facer. É importante que vos acordedes de aplicar a técnica descrita cando vexades os contidos.
- A modificación se produce cando executamos a orde SQL UPDATE.
- Ao igual que no caso INSERT, se modificamos as claves primarias, farase o action recollido na creación das táboas.
- Normalmente non se debe modificar a clave primaria das táboas e o que modificaremos será algún dos atributos da táboa.
- A orde SQL UPDATE levará como parámetros os novos valores a modificar e enviarase a clave primaria para que poida buscar a fila concreta que vai modificarse.
- Ao igual que no caso da orde INSERT, podemos saber o número de rexistros afectados chamando á función mysqi_affected_rows.
- Neste exercicio dita función debería devolver sempre 1, pero podería aplicarse a outros exemplo no que queremos informar ao usuario de cantos rexistros foron afectados pola opción.
- Nota: Lembrar que nesta solución estamos a utilizar a chamada a multi_query pero se podería utilizar a chamada a query no caso de que o procedemento non devolva resultados (teña un select que queiramos recoller en PHP).
Caso Práctico: Modificación
Orientado a procedementos
- Imos implementar esta opción na páxina consultar_estados.php continuando có visto na sección de ALTA.
- Se estamos a utilizar procedementos almacenados, lembrar que en caso de erro '2014 - Commands out of sync; you can't run this command now', debemos engadir a seguinte liña despois de chamar a un procedemento almacenado:
if ($conex->multi_query($proc)){ $result = $conex->store_result(); if ($result && ($result->num_rows>0)){ while($fila=$result->fetch_assoc()){ // Procesamos cada fila } $result->free(); } while($conex->next_result() && $conex->store_result()); }
- O que temos que facer é:
- Definir no arquivo bd.php unha constante coa orde SQL para modificar o nome dun estado a partires dun id dado (clave primaria)
- Modificar a páxina consultar_estados.php e engadir a opción 'Editar' a cada un dos estados. Debemos ir a unha páxina editar_estado.php.
- O poderemos facer:
- Cun enlace href, enviando como parámetro o id do estado a modificar. Eu vou escoller esta opción, pero sodes libres de practicar e intentalo coa outra opción.
- Cun formulario e un campo oculto có id do estado a modificar.
- A páxina editar_estado.php terá un formulario cun action a 'procesar_editar_estado.php'. Dentro do formulario fará un include do arquivo campos_estado.php que xa foi feito na páxina de alta de estados.
- Tamén obterá os datos do estado a partires do id enviado polo enlace href ou polo formulario da páxina consultar_estados.php. Ditos datos serán gardados en variables e o nome será empregado pola páxina campos_estado.php.
- Modificaremos a páxina campos_estado.php para que teña en conta os datos obtidos da consulta á base de datos.
$e->getCode():* Crear a páxina procesar_borrar_estado.php que dará de baixa o estado e se se produce algún erro deberá de informar á páxina de consultar_estados.php de cal foi o erro. Ao igual que na alta, poderemos enviar dita información nun parámetro na URL de redirección ou veremos nas seguintes seccións como empregar variables de sesión.
- A xestión do erro en caso de querer borrar un rexistro relacionado non a imos facer.
- Lembrar que dito control poderíamos facelo no propio procedemento almacenado/páxina php, capturando a excepción ou comprobando cun select previo se existe o rexistro relacionado.
Posible solución Caso Práctico: Modificación
Arquivo: bd.php
define('CONSULTAR_ESTADO_POR_ID',"SELECT id,descripcion FROM estados WHERE id=%d"); define('ACTUALIZAR_ESTADO',"UPDATE estados set descripcion='%s' WHERE id=%d");
Arquivo: consultar_estados.php
<?php /* Lembrar quitar isto ao probar o scripts sen erros */ ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL); require ('/var/www/confBD/bd.php'); try { $conex = new mysqli(SERVIDOR, USUARIO, PASSWORD,BD); $conex->set_charset('utf8mb4'); ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="es" xml:lang="es"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>Xestión de estados</title> </head> <body> <form action="alta_estado.php" method="post"> <button type="submit">Novo Estado</button> </form> <table border="1" style="margin-top:20px"> <tr> <th>Estado</th> <th>Accións</th> </tr> <?php $resultado = $conex->query(CONSULTAR_ESTADOS); while($fila = $resultado->fetch_assoc()) { $nombre = htmlentities($fila['descripcion']); echo "<tr>"; echo "<td>$nombre</td>"; echo "<td>"; printf("<td><a href='editar_estado.php?id=%d'>Editar</a>",urlencode($fila['id'])); printf("<form action='procesar_borrar_estado.php' method='post'>"); printf("<input type='hidden' name='id' value='%s' />",htmlentities($fila['id'])); echo '<input onclick="return confirm(\'Estás seguro de que queres borrar este estado?\');" type="submit" value="Borrar" name="btnBorrarEstado" style="background:none;border:none;padding:0;maring:0;color: blue; text-decoration:underline; cursor:pointer; font-size:inherit" />'; echo '</form>'; echo "</td>"; echo "</tr>"; } $resultado->free(); ?> </table> <div> <?php if(isset($_GET['id'])) printf("<h3>Estado con id %s dado de alta correctamente.</h3>",htmlentities($_GET['id'])); if(isset($_GET['msg'])) printf("<h4>%s</h3>",htmlentities($_GET['msg'])); if(isset($_GET['error'])) printf("<h2>Houbo un erro: %s</h2>",htmlentities($_GET['error'])); ?> </div> </body> </html> <?php } // Pecha o try da parte superior da páxina catch (mysqli_sql_exception $e) { die("Erro mysql: " . $e->getMessage()); } catch (Expcetion $e) { die("Erro xeral: " . $e->getMessage()); } finally{ if(!empty($conex)){ $conex->close(); } } ?>
Arquivo: campos_estado.php
<label for="nombre">Descricción:</label> <input type="text" maxlength="100" id="descripcion" name="descripcion" required value="<?php echo isset($descripcion) ? htmlentities($descripcion) : ''; ?>"><br>
Arquivo: editar_estado.php
<?php /* Lembrar quitar isto ao probar o scripts sen erros */ ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL); require ('/var/www/confBD/bd.php'); $conex = new mysqli(SERVIDOR, USUARIO, PASSWORD, BD); $conex->set_charset('utf8mb4'); $erros = ''; ?> <?php $consulta = sprintf(CONSULTAR_ESTADO_POR_ID,$conex->real_escape_string($_GET['id'])); $result=$conex->query($consulta); // Ven na URL da paxina listar_pistas.php if ($result && $result->num_rows>0){ $row = mysqli_fetch_assoc($result); // Os datos serán empregados polos inputs do formulario $descripcion = htmlentities($row['descripcion']); $id = htmlentities($row['id']); //O id non se amosa ao usuario $result->free(); } else { $erros = "Non se atopan os datos da pista!!!!"; } ?> <!DOCTYPE html> <html> <head> <title>Modificar Estado</title> </head> <body> <h3>EDITAR ESTADO</h3> <form method="POST" action="procesar_editar_estado.php"> <?php include 'campos_estado.php'; ?> <div> <input type="hidden" name="id_orixinal" value="<?php echo $id; ?>"> <input type="submit" value="Modificar" name="btnModificarEstado"> </div> </form> <?php if(!empty($erros)){ printf("<h3>$erros</h3>"); } ?> </body> </html>
Arquivo: procesar_editar_estado.php
<?php /* Lembrar quitar isto ao probar o scripts sen erros */ ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL); require ('/var/www/confBD/bd.php'); $conex = new mysqli(SERVIDOR, USUARIO, PASSWORD, BD); $conex->set_charset('utf8mb4'); $error = ''; $msg = ''; if (isset($_POST['btnModificarEstado'])) { try { // Lóxica para dar de alta unha nova pista $desc_novo = $conex->real_escape_string(strtoupper($_POST['descripcion'])); if(strlen($desc_novo)<4 || strlen($desc_novo)>100){ $error = sprintf("error=%s", urlencode("O nome do estado non pode ter menos de 4 ou 100 caracteres")); } else{ $id = $conex->real_escape_string($_POST['id_orixinal']); // Ven nun campo oculto do form $consulta = sprintf(ACTUALIZAR_ESTADO,$desc_novo, $id); $conex->query($consulta); $msg = sprintf("msg=%s", urlencode("Estado actualizado correctamente.")); } } catch (mysqli_sql_exception $e) { $error=sprintf("error='Erro mysql: %s'",urlencode($e->getMessage())); } catch (Expcetion $e) { $error=sprintf("error='Erro xeral: %s'",urlencode($e->getMessage())); } finally{ if(!empty($conex)){ $conex->close(); } } } $url = sprintf("consultar_estados.php?%s&%s",$msg,$error); header("Location:" . $url); ?>
Empregando PDO
- Imos implementar esta opción na páxina consultar_estados.php continuando có visto na sección de ALTA.
- O que temos que facer é:
- Definir no arquivo bd.php unha constante coa orde SQL para modificar o nome dun estado a partires dun id dado (clave primaria)
- Modificar a páxina consultar_estados.php e engadir a opción 'Editar' a cada un dos estados. Debemos ir a unha páxina editar_estado.php.
- O poderemos facer:
- Cun enlace href, enviando como parámetro o id do estado a modificar. Eu vou escoller esta opción, pero sodes libres de practicar e intentalo coa outra opción.
- Cun formulario e un campo oculto có id do estado a modificar.
- A páxina editar_estado.php terá un formulario cun action a 'procesar_editar_estado.php'. Dentro do formulario fará un include do arquivo campos_estado.php que xa foi feito na páxina de alta de estados.
- Tamén obterá os datos do estado a partires do id enviado polo enlace href ou polo formulario da páxina consultar_estados.php. Ditos datos serán gardados en variables e o nome será empregado pola páxina campos_estado.php.
- Modificaremos a páxina campos_estado.php para que teña en conta os datos obtidos da consulta á base de datos.
$e->getCode():* Crear a páxina procesar_borrar_estado.php que dará de baixa o estado e se se produce algún erro deberá de informar á páxina de consultar_estados.php de cal foi o erro. Ao igual que na alta, poderemos enviar dita información nun parámetro na URL de redirección ou veremos nas seguintes seccións como empregar variables de sesión.
- A xestión do erro en caso de querer borrar un rexistro relacionado non a imos facer.
- Lembrar que dito control poderíamos facelo no propio procedemento almacenado/páxina php, capturando a excepción ou comprobando cun select previo se existe o rexistro relacionado.
Posible solución Caso Práctico: Modificación
Arquivo: bd.php
define('CONSULTAR_ESTADO_POR_ID',"SELECT id,descripcion FROM estados WHERE id=:id_estado"); define('ACTUALIZAR_ESTADO',"UPDATE estados set descripcion=:descripcion WHERE id=:id_estado");
Arquivo: consultar_estados.php
<?php /* Lembrar quitar isto ao probar o scripts sen erros */ ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL); require('/var/www/confBD/bd.php'); try { $dsn = sprintf("mysql:host=%s;dbname=%s;charset=utf8mb4", SERVIDOR, BD); $conex = new PDO($dsn, USUARIO, PASSWORD); $conex->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $erro = ""; // Variable que a usaremos para amosar os posibles erros controlados por nos que poidan darse. ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="es" xml:lang="es"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>Xestión de estados</title> </head> <body> <form action="alta_estado.php" method="post"> <button type="submit">Novo Estado</button> </form> <table border="1" style="margin-top:20px"> <tr> <th>Estado</th> <th>Accións</th> </tr> <?php $result=$conex->query(CONSULTAR_ESTADOS); // Temos que poñer prepare if ($result && $result->rowCount() > 0) { while ($row = $result->fetch(PDO::FETCH_ASSOC)) { $nombre = htmlentities($row['descripcion']); echo "<tr>"; echo "<td>$nombre</td>"; echo "<td>"; printf("<a href='editar_estado.php?id=%s'>Editar</a>",urlencode($row['id'])); echo("<form action='procesar_borrar_estado.php' method='post'>"); printf("<input type='hidden' name='id' value='%s' />",htmlentities($row['id'])); echo '<input onclick="return confirm(\'Estás seguro de que queres borrar este estado?\');" type="submit" value="Borrar" name="btnBorrarEstado" style="background:none;border:none;padding:0;margin:0;color: blue; text-decoration:underline; cursor:pointer; font-size:inherit" />'; echo '</form>'; echo "</td>"; echo "</tr>"; } } $result = null; ?> </table> <div> <?php if(isset($_GET['id'])) printf("<h3>Estado con id %s dado de alta correctamente.</h3>",htmlentities($_GET['id'])); if(isset($_GET['msg'])) printf("<h4>%s</h3>",htmlentities($_GET['msg'])); if(isset($_GET['error'])) printf("<h2>Houbo un erro: %s</h2>",htmlentities($_GET['error'])); ?> </div> </body> </html> <?php } // Pecha o try do principio da páxina catch (PDOException $e) { die("Erro PDO: " . $e->getMessage()); } catch (Exception $e) { die("Erro xeral: " . $e->getMessage()); } finally { $conex = null; // Pechar a conexión } ?>
Arquivo: campos_estado.php
<label for="nombre">Descricción:</label> <input type="text" maxlength="100" id="descripcion" name="descripcion" required value="<?php echo isset($descripcion) ? htmlentities($descripcion) : ''; ?>">
Arquivo: editar_estado.php
<?php /* Lembrar quitar isto ao probar o scripts sen erros */ ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL); require('/var/www/confBD/bd.php'); try { $dsn = sprintf("mysql:host=%s;dbname=%s;charset=utf8mb4", SERVIDOR, BD); $conex = new PDO($dsn, USUARIO, PASSWORD); $conex->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $erro = ""; // Variable que a usaremos para amosar os posibles erros controlados por nos que poidan darse. $stmt = $conex->prepare(CONSULTAR_ESTADO_POR_ID); $stmt->bindValue(":id_estado", $_GET['id'], PDO::PARAM_INT); $result = $stmt->execute(); if ($result) { $row = $stmt->fetch(PDO::FETCH_ASSOC); $id = $row['id']; $descripcion = htmlentities($row['descripcion']); $stmt = null; } else { $erros = "Non se atopan os datos da pista!!!!"; } ?> <!DOCTYPE html> <html> <head> <title>Modificar Estado</title> </head> <body> <h3>EDITAR ESTADO</h3> <form method="POST" action="procesar_editar_estado.php"> <?php include 'campos_estado.php'; ?> <div> <input type="hidden" name="id_orixinal" value="<?php echo $id; ?>"> <input type="submit" value="Modificar" name="btnModificarEstado"> </div> </form> <?php if(!empty($erros)){ printf("<h3>$erros</h3>"); } ?> </body> </html> <?php } // Pecha o try do principio da páxina catch (PDOException $e) { die("Erro PDO: " . $e->getMessage()); } catch (Exception $e) { die("Erro xeral: " . $e->getMessage()); } finally { $conex = null; // Pechar a conexión } ?>
Arquivo: procesar_editar_estado.php
<?php /* Lembrar quitar isto ao probar o scripts sen erros */ ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL); require('/var/www/confBD/bd.php'); try { $dsn = sprintf("mysql:host=%s;dbname=%s;charset=utf8mb4", SERVIDOR, BD); $conex = new PDO($dsn, USUARIO, PASSWORD); $conex->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $error = ''; $msg = ''; if (isset($_POST['btnModificarEstado'])) { $desc_novo = strtoupper($_POST['descripcion']); if (strlen($desc_novo) < 4 || strlen($desc_novo) > 100) { $error = sprintf("error=%s", urlencode("O nome do estado non pode ter menos de 4 ou 100 caracteres")); } else { $stmt = $conex->prepare(ACTUALIZAR_ESTADO); // Temos que poñer prepare $stmt->bindValue(':id_estado', $_POST['id_orixinal'], PDO::PARAM_INT); $stmt->bindValue(':descripcion', $desc_novo, PDO::PARAM_STR); $result = $stmt->execute(); if ($result) { $msg = sprintf("msg=%s", urlencode("Estado actualizado correctamente.")); } else { $error = sprintf("error=$s", urlencode("Houbo un problema na actualización.")); } } } } catch (PDOException $e) { $error = sprintf("error=PDO:%s", urlencode($e->getMessage())); } catch (Exception $e) { $error = sprintf("error=ERRO XERAL:%s", urlencode($e->getMessage())); } finally { $conex = null; // Pechar a conexión } $url = sprintf("consultar_estados.php?%s&%s", $msg, $error); header("Location:" . $url);
-- Ángel D. Fernández González -- (2025).