Diferencia entre revisiones de «PHP UD3 OP BAIXA»

De MediaWiki
Ir a la navegación Ir a la búsqueda
Línea 47: Línea 47:
 
=== Caso Práctico: Baixa ===
 
=== Caso Práctico: Baixa ===
  
−
* Imos implementar esta opción na páxina '''Xestionar_Estados.php'''.
+
* 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:
−
 
 
−
: Cargaremos nunha <select> todos os estados e premendo o botón 'Baixa' daremos de baixa o estado seleccionado.
 
−
 
 
−
: Faremos uso dun procedemento almacenado de nome '''BORRAR_ESTADO''' que terá como parámetro o id do estado a borrar e fará a sentenza sql DELETE.
 
−
: Faremos uso do procedemento almacenado 'CONSULTAR_ESTADOS' que devolverá nun select o id e descrición dos estados para cargar na lista.
 
−
 
 
−
: Nesta solución non comprobamos se xa existen datos relacionados con ese estado antes de borralos e usaremos como base o código feito na solución '''Xestionar_Estados_Proc.php''' feito anteriormente.
 
−
 
 
−
 
 
−
* 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" line enclose="div" highlight="9" >
 
:::<syntaxhighlight lang="java" line enclose="div" highlight="9" >
 
                     if ($conex->multi_query($proc)){
 
                     if ($conex->multi_query($proc)){
Línea 70: Línea 59:
 
                         }
 
                         }
 
                         while($conex->next_result() && $conex->store_result());
 
                         while($conex->next_result() && $conex->store_result());
 +
                    }
 
</syntaxhighlight>
 
</syntaxhighlight>
  
  
  
−
* A xestión do erro en caso de querer borrar un rexistro relacionado a imos facer na páxina PHP comprobando que o valor numérico do erro sexa o 1451, que se corresponde co erro 'Cannot delete or update a parent row: a foreign key constraint fails'.
+
* O que temos que facer é:
−
: Lembrar que dito control poderíamos facelo no propio procedemento almacenado capturando a excepción ou comprobando cun select previo se existe o rexistro relacionado.
+
:* Definir no arquivo bd.inc.php unha constante coa orde SQL para dar de baixa a un estado.
 +
:* Modificar a páxina consultar_estados.php e engadir a opción 'Eliminar' a cada un dos estados. Debemos ir a unha páxina procesar_borrar_estado.php.
 +
:: O poderemos facer:
 +
:* Cun enlace href, enviando como parámetro o id do estado a borrar.
 +
:* Cun formulario e un campo oculto có id do estado a borrar. Eu vou escoller esta opción, pero sodes libres de practicar e intentalo coa primimeira.
 +
:* 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 a imos facer na páxina PHP comprobando que o valor numérico do erro sexa o 1451, que se corresponde co erro 'Cannot delete or update a parent row: a foreign key constraint fails'.
 +
:: Lembrar que dito control poderíamos facelo no propio procedemento almacenado capturando a excepción ou comprobando cun select previo se existe o rexistro relacionado.
  
  
  
−
* <u>Nota:</u> 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).
+
* <u>Nota:</u>  
 +
:* Lembrar que nesta solución estamos a utilizar a chamada a '''multi_query''' para obter o número de rexistros borrados, pero se podería utilizar a chamada a '''query''' no caso de que o procedemento non devolva resultados ou non nos interese obter o número de rexistros borrados.
 +
:*: Nesta solución non comprobamos se xa existen datos relacionados con ese estado antes de borralos.
 +
:* Usaremos como base o código feito na solución '''consultar_estados.php''' [https://wiki.cifprodolfoucha.es/index.php?title=PHP_UD3_OP_ALTA feito anteriormente na sección de alta].
  
  
  
−
'''Posible solución Caso Práctico: Baixa'''
 
  
−
 
−
'''Procedemento almacenado en Mysql: CONSULTAR_ESTADOS'''
 
−
:::<syntaxhighlight lang="java" line enclose="div" highlight="" >
 
−
DELIMITER $$
 
−
 
−
CREATE DEFINER=`root`@`localhost` PROCEDURE `CONSULTAR_ESTADOS`()
 
−
BEGIN
 
−
SELECT id_estado,descripcion
 
−
FROM ESTADOS
 
−
ORDER BY descripcion;
 
−
 
−
END
 
−
</syntaxhighlight>
 
−
 
−
 
−
'''Procedemento almacenado en Mysql: BORRAR_ESTADO'''
 
−
:::<syntaxhighlight lang="java" line enclose="div" highlight="" >
 
−
DELIMITER $$
 
−
 
−
CREATE DEFINER=`root`@`localhost` PROCEDURE `BORRAR_ESTADO`(_id_estado int)
 
−
BEGIN
 
−
 
−
DELETE FROM ESTADOS
 
−
WHERE id_estado = _id_estado;
 
−
 
−
END
 
−
</syntaxhighlight>
 
  
  
 +
<br />
 +
'''Posible solución Caso Práctico: Baixa'''
  
−
'''Arquivo bd.inc.php'''
+
'''Arquivo bd.inc.php'''. Engadimos o seguinte ao que xa tiñamos.
−
:::<syntaxhighlight lang="java" line enclose="div" highlight="" >
+
:::<syntaxhighlight lang="java" enclose="div" highlight="" >
−
define ('PROCEDEMENTO_BORRAR_ESTADO',"BORRAR_ESTADO(%d)");
+
define('BORRAR_ESTADO','DELETE FROM estados where id=%d');
−
define ('PROCEDEMENTO_CONSULTAR_ESTADOS',"CONSULTAR_ESTADOS()");
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
  
  
−
 
+
'''Arquivo consultar_estados.php'''
−
'''Arquivo Xestionar_Estados_Proc.php'''
+
:::<syntaxhighlight lang="java" enclose="div" highlight="39-42,56" >
−
:::<syntaxhighlight lang="java" line enclose="div" highlight="36-57,69-86" >
 
 
<?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.inc.php');
 
require ('/var/www/confBD/bd.inc.php');
−
//error_reporting(0);
 
  
−
$conex = new mysqli(SERVIDOR,USUARIO,PASSWORD,BD);
+
try {
−
$conex->set_charset('utf8');
+
    $conex = new mysqli(SERVIDOR, USUARIO, PASSWORD,BD);  
 +
    $conex->set_charset('utf8mb4');
  
−
if ($conex->connect_error){
 
−
    die('Erro de Conexi&oacute;n (' . mysqli_connect_errno() . ') ' . mysqli_connect_error());
 
−
}
 
−
$erro="";  // Variable que a usaremos para amosar os posibles erros que poidan darse
 
 
?>
 
?>
−
 
−
 
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
Línea 146: Línea 116:
 
     <head>
 
     <head>
 
         <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
 
         <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
−
         <title>Xestionar t&aacute;boa Estados BD</title>
+
         <title>Xestión de estados</title>
 
     </head>
 
     </head>
−
 
 
     <body>
 
     <body>
−
        <!-- Esta parte poderíase facer con javascript -->
+
         <form action="alta_estado.php" method="post">
−
         <form action="<?php echo htmlentities($_SERVER['PHP_SELF']) ?>" method='post'>
+
             <button type="submit">Novo Estado</button>
−
            <h2>Escolle a operación a facer sobre a táboa ESTADOS</h2>
 
−
            <input <?php echo (isset($_POST['rbtnOperacion']) && $_POST['rbtnOperacion']=='ALTA') ? "checked='checked'" : "";  ?>
 
−
                onclick='javascript:this.form-submit()' type='radio' name="rbtnOperacion" value='ALTA'>ALTA</input>
 
−
            <input <?php echo (isset($_POST['rbtnOperacion']) && $_POST['rbtnOperacion']=='BAIXA') ? "checked='checked'" : "";  ?>
 
−
                onclick='javascript:this.form-submit()'  type='radio' name="rbtnOperacion" value='BAIXA'>BAIXA</input>
 
−
            <input <?php echo (isset($_POST['rbtnOperacion']) && $_POST['rbtnOperacion']=='MODIFICACION') ? "checked='checked'" : "";  ?>
 
−
                onclick='javascript:this.form-submit()'  type='radio' name="rbtnOperacion" value='MODIFICACION'>MODIFICACI&Oacute;N</input>
 
−
        <?php 
 
−
 
 
−
        // Operación BAIXA => TEN QUE IR ANTES XA QUE DESPOIS CARGAMOS A LISTA COS ESTADOS!!!
 
−
        if (!empty($_POST['btnOperacion']) && $_POST['btnOperacion']=='BAIXA'){ 
 
−
            $id_estado = $_POST['lstEstados'];
 
−
            if (!filter_var($id_estado,FILTER_VALIDATE_INT)){
 
−
                $error='<h4>O estado indicado non &eacute; v&aacute;lido...</h4>';
 
−
            }
 
−
            else {
 
−
                $proc = sprintf(PROCEDEMENTO_BORRAR_ESTADO,$conex->mysql_real_escape($id_estado));
 
−
                $proc = sprintf("CALL %s",$proc);
 
−
                if ($conex->multi_query($proc)){
 
−
                    printf("<h4>Num. rexistros borrados:%d</h4>", $conex->affected_rows);
 
−
                    echo "<script>alert('Rexistro dado de baixa correctamente');</script>";
 
−
                    while($conex->next_result() && $conex->store_result());
 
−
                }
 
−
                else{
 
−
                    echo "<h5>Falló CALL: (" . $conex->errno . ") " . $conex->error . "</h5>";
 
−
                    if ($conex->errno==1451){  // Clave foránea relacionada
 
−
                        echo "<script>alert('O rexistro non se pode dar de baixa. Está sendo utilizado por outras táboas.');</script>";
 
−
                    }
 
−
                }
 
−
             }
 
−
        }  // Fin da operación de BAIXA
 
−
       
 
−
       
 
−
        // CARGAMOS AS DIFERENTES OPCIONS DE FORMULARIO EN BASE A OPERACION ESCOLLIDA DOS RADIOBUTTON: ALTA-BAIXA-MODIFICACION
 
−
        if (!empty($_POST['rbtnOperacion'])){  // Premimos unha opción => Xeramos o formulario
 
−
            switch ($_POST['rbtnOperacion']){
 
−
                case 'ALTA':
 
−
                    printf("<div>Nome do novo estado:");
 
−
                    printf("<input name='txtEstado' type='text' size='50' maxlength='100' /></div>");
 
−
                    printf("<div><input name='btnOperacion' type='submit' value='ALTA' />");
 
−
                    printf("<input type='reset' value='BORRAR' /></div>");
 
−
                    break;
 
−
                case 'BAIXA':
 
−
                    printf("<div>Lista de estados:");
 
−
                    $proc = sprintf("CALL %s",PROCEDEMENTO_CONSULTAR_ESTADOS);
 
−
                    printf("<select name='lstEstados'>");
 
−
                    if ($conex->multi_query($proc)){
 
−
                        $result = $conex->store_result();
 
−
                        if ($result && ($result->num_rows>0)){
 
−
                            while($fila=$result->fetch_assoc()){
 
−
                                printf("<option value='%d'>%s</option>",$fila['id_estado'],$fila['descripcion']);
 
−
                            }
 
−
                            $result->free();
 
−
                        }
 
−
                        while($conex->next_result() && $conex->store_result());
 
−
                    }
 
−
                    printf("</select>");
 
−
                    printf("</div>");
 
−
                    printf("<div><input name='btnOperacion' type='submit' value='BAIXA' />");
 
−
                    break;
 
−
            }
 
−
        }
 
−
        ?>       
 
 
         </form>
 
         </form>
−
          
+
         <table border="1" style="margin-top:20px">
 +
            <tr>
 +
                <th>Estado</th>
 +
                <th>Accións</th>
 +
            </tr>
 
         <?php
 
         <?php
−
        // Xestionamos a operacion do segundo formulario => Alta
+
 
−
        if (!empty($_POST['btnOperacion']) && $_POST['btnOperacion']=='ALTA'){ 
+
            $resultado = $conex->query(CONSULTAR_ESTADOS);
−
            if (strlen($_POST['txtEstado'])>100){
+
 
−
                 $erro = ">A lonxitude da cadea non pode ter máis de 100 caracteres...";
+
            while($fila = $resultado->fetch_assoc()) {
 +
                $nombre = htmlentities($fila['descripcion']);
 +
                echo "<tr>";
 +
                echo "<td>$nombre</td>";
 +
                echo "<td>";
 +
                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>";
 
             }
 
             }
−
             else {
+
 
−
                // Eliminamos caracteres non permitidos
+
             $resultado->free();
−
                $novoEstado = filter_var($_POST['txtEstado'],FILTER_SANITIZE_STRING);
+
        ?>   
−
                // Escapamos as comillas simples e dobres
+
        </table>
−
                $novoEstado = $conex->real_escape_string($novoEstado);
+
 
−
                $proc=sprintf(PROCEDEMENTO_INSERIR_ESTADO,$novoEstado);
+
 
−
                $proc = sprintf("CALL %s",$proc);
+
        <div>
−
                if ($conex->multi_query($proc)){
+
            <?php
−
                    $result = $conex->store_result();
+
                if(isset($_GET['id'])) printf("<h3>Estado con id %d dado de alta correctamente.</h3>",htmlentities($_GET['id']));
−
                    if ($result && ($result->num_rows>0)){
+
                if(isset($_GET['msg'])) printf("<h4>%s</h3>",htmlentities($_GET['msg']));
−
                        $fila=$result->fetch_assoc();
+
                 if(isset($_GET['error'])) printf("<h2>Houbo un erro: %s</h2>",htmlentities($_GET['error']));
−
                        switch($fila['valor_devolto']){
+
            ?>
−
                            case -1:
+
         </div>   
−
                                $erro = "Ese valor xa est&aacute; dado de alta na base de datos...";
 
−
                                break;
 
−
                            default:
 
−
                                printf("<h2>Valor dado de alta correctamente</h2>");
 
−
                                printf("<h3>Nova clave %d</h3>",$fila['valor_devolto']);
 
−
                               
 
−
                                break;
 
−
                        }
 
−
                        $result->free();
 
−
                    }
 
−
                    else{  // Sempre ten que devolver algo como temos implementado o proc.
 
−
                        $erro = 'Houbo un erro na chamada á base de datos';
 
−
                    }
 
−
                    while($conex->next_result() && $conex->store_result());
 
−
                 }
 
−
                else{
 
−
                    $erro = 'Houbo un erro na chamada á base de datos';
 
−
                }
 
−
            } 
 
−
               
 
−
        }  // Fin da operacion de ALTA
 
−
       
 
−
       
 
−
       
 
−
        ?>
 
−
        <?php       
 
−
        if ($erro!='') {
 
−
            printf("<h3>%s</h3>",$erro);
 
−
        }
 
−
        $conex->close(); // Pechamos a conexión
 
−
       
 
−
        ?>      
 
−
          
 
 
          
 
          
 
     </body>     
 
     </body>     
 
</html>
 
</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();
 +
  }
 +
}
 +
?>
 +
</syntaxhighlight>
 +
 +
  
−
</syntaxhighlight>
 
  
 +
<br />
 +
'''Arquivo procesar_borrar_estado.php'''
 +
:::<syntaxhighlight lang="java" enclose="div" highlight="19" >
 +
<?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.inc.php');
 +
 +
$msg='';
 +
$error = '';
 +
if (isset($_POST['btnBorrarEstado'])) {
 +
  try {
 +
    $conex = new mysqli(SERVIDOR, USUARIO, PASSWORD, BD);
 +
    $conex->set_charset('utf8mb4');
 +
 +
    // Lóxica para dar de alta unha nova pista
 +
    $id = $conex->real_escape_string($_POST['id']);
 +
    $consulta = sprintf(BORRAR_ESTADO,$id);
 +
    if ($conex->multi_query($consulta)){
 +
      $msg = sprintf("msg=Num. rexistros borrados:%d", $conex->affected_rows);
 +
      while($conex->next_result() && $conex->store_result());
 +
    }
  
 +
  }  // Pecha o try da parte superior da páxina. Lembrar que aos usuarios non se lle deben amosar os erros. Isto está posto a nivel informativo para os programadores
 +
  catch (mysqli_sql_exception $e) {
 +
      $error=sprintf("error='Erro mysql: %s'",htmlentities($e->getMessage()));
 +
  }
 +
  catch (Expcetion $e) {
 +
      $error=sprintf("error='Erro xeral: %s'",htmlentities($e->getMessage()));
 +
  }
 +
  finally{
 +
      if(!empty($conex)){
 +
          $conex->close();
 +
      }
 +
  }
 +
 
 +
   
 +
}
 +
$url = sprintf("consultar_estados.php?%s&%s",$msg,$error);
 +
header("Location:" . $url);
  
  
 +
</syntaxhighlight>
  
  

Revisión del 08:56 25 oct 2023

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.




  • Podemos eliminar unha fila ou un conxunto de filas en base a uns criterios (parte WHERE da cláusula DELETE)
  • Ao igual que fixemos anteriormente, podemos borrar directamente en PHP facendo uso da orde DELETE ou chamar a un procedemento almacenado, enviando os datos necesarios e executando a sentenza.


  • IMPORTANTE: Temos que ter en conta que nas bases de datos relacionais, dar de baixa un rexistro pode implicar borrar rexistros relacionados.
Cando creamos as táboas indicamos as relacións entre elas por medio de claves foráneas, nas que indicamos como queremos que se comporten cando se produce un borrado ou unha modificación. Máis información neste enlace.


Por exemplo, na táboa LIBROS_AUTORES:
1 CREATE TABLE `LIBROS_AUTORES` (
2   `libro_id` int(11) NOT NULL,
3   `autor_id` int(11) NOT NULL,
4   PRIMARY KEY (`libro_id`,`autor_id`),
5   KEY `fk_LIBROS_AUTORES_AUTORES_idx` (`autor_id`),
6   CONSTRAINT `fk_LIBROS_AUTORES_AUTORES` FOREIGN KEY (`autor_id`) REFERENCES `AUTORES` (`id_autor`) ON DELETE NO ACTION ON UPDATE CASCADE,
7   CONSTRAINT `fk_LIBROS_AUTORES_LIBROS` FOREIGN KEY (`libro_id`) REFERENCES `LIBROS` (`id_libro`) ON DELETE NO ACTION ON UPDATE CASCADE
8 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_spanish2_ci;
No exemplo estamos a indicar que en caso de borrar unha fila de táboa AUTORES, non se vai permitir se existen filas na táboa LIBROS_AUTORES.
Se actualizamos a clave primaria da táboa AUTORES, actualizará a clave na táboa AUTORES_LIBROS (parte ON UPDATE CASCADE).


  • Polo tanto, será tarefa do programador comprobar se os datos están sendo utilizados noutras táboas e avisar en caso de que o usuario intente borralos ou ben permitir borrados en cascada ou ben capturar o erro que dará o mysql en caso de intentar borrar datos relacionados e informar ao usuario do problema.


Caso Práctico: Baixa

  • 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 dar de baixa a un estado.
  • Modificar a páxina consultar_estados.php e engadir a opción 'Eliminar' a cada un dos estados. Debemos ir a unha páxina procesar_borrar_estado.php.
O poderemos facer:
  • Cun enlace href, enviando como parámetro o id do estado a borrar.
  • Cun formulario e un campo oculto có id do estado a borrar. Eu vou escoller esta opción, pero sodes libres de practicar e intentalo coa primimeira.
  • 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 a imos facer na páxina PHP comprobando que o valor numérico do erro sexa o 1451, que se corresponde co erro 'Cannot delete or update a parent row: a foreign key constraint fails'.
Lembrar que dito control poderíamos facelo no propio procedemento almacenado capturando a excepción ou comprobando cun select previo se existe o rexistro relacionado.


  • Nota:
  • Lembrar que nesta solución estamos a utilizar a chamada a multi_query para obter o número de rexistros borrados, pero se podería utilizar a chamada a query no caso de que o procedemento non devolva resultados ou non nos interese obter o número de rexistros borrados.
    Nesta solución non comprobamos se xa existen datos relacionados con ese estado antes de borralos.
  • Usaremos como base o código feito na solución consultar_estados.php feito anteriormente na sección de alta.





Posible solución Caso Práctico: Baixa

Arquivo bd.inc.php. Engadimos o seguinte ao que xa tiñamos.

define('BORRAR_ESTADO','DELETE FROM estados 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.inc.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("<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 %d 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 procesar_borrar_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.inc.php');

$msg='';
$error = '';
if (isset($_POST['btnBorrarEstado'])) {
  try {
    $conex = new mysqli(SERVIDOR, USUARIO, PASSWORD, BD);
    $conex->set_charset('utf8mb4');

    // Lóxica para dar de alta unha nova pista
    $id = $conex->real_escape_string($_POST['id']);
    $consulta = sprintf(BORRAR_ESTADO,$id);
    if ($conex->multi_query($consulta)){
      $msg = sprintf("msg=Num. rexistros borrados:%d", $conex->affected_rows);
      while($conex->next_result() && $conex->store_result());
    }

  }   // Pecha o try da parte superior da páxina. Lembrar que aos usuarios non se lle deben amosar os erros. Isto está posto a nivel informativo para os programadores
  catch (mysqli_sql_exception $e) {
      $error=sprintf("error='Erro mysql: %s'",htmlentities($e->getMessage()));
  }
  catch (Expcetion $e) {
      $error=sprintf("error='Erro xeral: %s'",htmlentities($e->getMessage()));
  }
  finally{
      if(!empty($conex)){
          $conex->close();
      }
  }
  
    
}
$url = sprintf("consultar_estados.php?%s&%s",$msg,$error);
header("Location:" . $url);






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