PHP UD3 OP MODIFICAR

De MediaWiki
Ir a la navegación Ir a la búsqueda

Introducción

  • Requerimentos previos:


  • 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.




  • 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.
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

  • 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:
 1                     if ($conex->multi_query($proc)){
 2                         $result = $conex->store_result();
 3                         if ($result && ($result->num_rows>0)){
 4                             while($fila=$result->fetch_assoc()){
 5                                 // Procesamos cada fila
 6                             }
 7                             $result->free();
 8                         }
 9                         while($conex->next_result() && $conex->store_result());
10                     }


  • O que temos que facer é:
  • Definir no arquivo bd.inc.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.inc.php

1 define('CONSULTAR_ESTADO_POR_NOME',"SELECT id,descripcion FROM estados WHERE id=%d");
2 define('ACTUALIZAR_ESTADO',"UPDATE estados set descripcion='%s' WHERE id=%d");


Arquivo: consultar_estados.php

 1 <?php
 2 /* Lembrar quitar isto ao probar o scripts sen erros */
 3 ini_set('display_errors', 1);
 4 ini_set('display_startup_errors', 1);
 5 error_reporting(E_ALL);
 6 
 7 require ('/var/www/confBD/bd.inc.php');
 8 
 9 try {
10     $conex = new mysqli(SERVIDOR, USUARIO, PASSWORD,BD);   
11     $conex->set_charset('utf8mb4');
12 
13 ?>
14 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
15     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
16 <html xmlns="http://www.w3.org/1999/xhtml" lang="es" xml:lang="es">
17     <head>
18         <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
19         <title>Xestión de estados</title>
20     </head>
21     <body>
22         <form action="alta_estado.php" method="post">
23             <button type="submit">Novo Estado</button>
24         </form>
25         <table border="1" style="margin-top:20px">
26             <tr>
27                 <th>Estado</th>
28                 <th>Accións</th>
29             </tr>
30         <?php
31 
32             $resultado = $conex->query(CONSULTAR_ESTADOS);
33 
34             while($fila = $resultado->fetch_assoc()) {
35                 $nombre = htmlentities($fila['descripcion']);
36                 echo "<tr>";
37                 echo "<td>$nombre</td>";
38                 echo "<td>";
39                 printf("<td><a href='editar_estado.php?id=%d'>Editar</a>",htmlentities($fila['id']));
40                 printf("<form action='procesar_borrar_estado.php' method='post'>");
41                 printf("<input type='hidden' name='id' value='%s' />",htmlentities($fila['id']));
42                 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" />';
43                 echo '</form>';
44                 echo "</td>";
45 
46                 echo "</tr>";
47             }
48 
49             $resultado->free();
50         ?>    
51         </table>
52 
53 
54         <div>
55             <?php
56                 if(isset($_GET['id'])) printf("<h3>Estado con id %d dado de alta correctamente.</h3>",htmlentities($_GET['id']));
57                 if(isset($_GET['msg'])) printf("<h4>%s</h3>",htmlentities($_GET['msg']));
58                 if(isset($_GET['error'])) printf("<h2>Houbo un erro: %s</h2>",htmlentities($_GET['error']));
59             ?>
60         </div>    
61         
62     </body>    
63 </html>
64 <?php
65 }   // Pecha o try da parte superior da páxina
66 catch (mysqli_sql_exception $e) {
67     die("Erro mysql: " . $e->getMessage());
68 }
69 catch (Expcetion $e) {
70     die("Erro xeral: " . $e->getMessage());
71 }
72 finally{
73   if(!empty($conex)){
74       $conex->close();
75   }
76 }
77 ?>



Arquivo: campos_estado.php

1 <label for="nombre">Descricción:</label>
2 <input type="text" maxlength="100" id="descripcion" name="descripcion" required value="<?php echo isset($descripcion) ? htmlentities($descripcion) : ''; ?>"><br>


Arquivo: editar_estado.php

 1 <?php
 2 /* Lembrar quitar isto ao probar o scripts sen erros */
 3 ini_set('display_errors', 1);
 4 ini_set('display_startup_errors', 1);
 5 error_reporting(E_ALL);
 6 
 7 require ('/var/www/confBD/bd.inc.php');
 8 $conex = new mysqli(SERVIDOR, USUARIO, PASSWORD, BD);
 9 $conex->set_charset('utf8mb4');
10 $erros = '';
11 
12 ?>
13 
14 <?php 
15     $consulta = sprintf(CONSULTAR_ESTADO_POR_NOME,$conex->real_escape_string($_GET['id']));
16     $result=$conex->query($consulta);  // Ven na URL da paxina listar_pistas.php
17     if ($result && $result->num_rows>0){
18         $row = mysqli_fetch_assoc($result); // Os datos serán empregados polos inputs do formulario
19         $descripcion = htmlentities($row['descripcion']);
20         $id = htmlentities($row['id']);  //O id non se amosa ao usuario
21 
22         $result->free();
23     }
24     else {
25         $erros = "Non se atopan os datos da pista!!!!";
26     }
27 
28 
29 ?>
30 <!DOCTYPE html>
31 <html>
32 <head>
33   <title>Modificar Estado</title>
34 </head>
35 <body>  
36     <h3>EDITAR ESTADO</h3>
37 
38   <form method="POST" action="procesar_editar_estado.php">
39     <?php include 'campos_estado.php'; ?>
40     <div>
41         <input type="hidden" name="id_orixinal" value="<?php echo $id; ?>">
42         <input type="submit" value="Modificar" name="btnModificarEstado">
43     </div>
44   </form>
45   <?php 
46     if(!empty($erros)){
47         printf("<h3>$erros</h3>");
48     }
49   ?>
50 </body>
51 </html>


Arquivo: procesar_editar_estado.php

 1 <?php
 2 /* Lembrar quitar isto ao probar o scripts sen erros */
 3 ini_set('display_errors', 1);
 4 ini_set('display_startup_errors', 1);
 5 error_reporting(E_ALL);
 6 
 7 require ('/var/www/confBD/bd.inc.php');
 8 
 9 $conex = new mysqli(SERVIDOR, USUARIO, PASSWORD, BD);
10 $conex->set_charset('utf8mb4');
11 
12 $error = '';
13 $msg = '';
14 if (isset($_POST['btnModificarEstado'])) {
15   try {
16 
17     // Lóxica para dar de alta unha nova pista
18     $desc_novo = $conex->real_escape_string(strtoupper($_POST['descripcion']));
19     if(strlen($desc_novo)<4 || strlen($desc_novo)>100){
20       $error=sprintf("error=O nome do estado non pode ter menos de 4 ou 100 caracteres");
21     }
22     else{
23       $id = $conex->real_escape_string($_POST['id_orixinal']); // Ven nun campo oculto do form
24       $consulta = sprintf(ACTUALIZAR_ESTADO,$desc_novo, $id);
25       $conex->query($consulta);
26   
27       $msg = sprintf("msg=Estado actualizado correctamente.");
28   
29     }
30   }
31   catch (mysqli_sql_exception $e) {
32       $error=sprintf("error='Erro mysql: %s'",htmlentities($e->getMessage()));
33   }
34   catch (Expcetion $e) {
35       $error=sprintf("error='Erro xeral: %s'",htmlentities($e->getMessage()));
36   }
37   finally{
38     if(!empty($conex)){
39       $conex->close();
40     }  
41   }
42 }
43 $url = sprintf("consultar_estados.php?%s&%s",$msg,$error);
44 header("Location:" . $url);
45 
46 ?>






-- Ángel D. Fernández González -- (2023).