Formulari + base de dades + sessions: tenda Balmes

De Wikijoan
Dreceres ràpides: navegació, cerca

Contingut

Introducció

Pots provar el resultat de com ha de quedar el formulari en el següent enllaç que està al servidor del professor:

PHP+Mysql. Registre, login i sessions

NOTA. La part de login i sessions no la farem. També falta tota la part de Javascript per tal de validar les dades del formulari.

Ja hem vist la teoria de PHP+MySQL. Ara es tracta de posar-ho a la pràctica reprenent el formulari de la tenda del Jaume Balmes, que has fet amb bootstrap.

L'objectiu serà:

Llibreries

Els passwords es guarden encriptats a la base de dades. S'utilitza la funció mcrypt_encrypt():

$ sudo apt-cache search mcrypt
...
php-mcrypt - MCrypt module for php
php7-mcrypt - MCrypt module for php7

$ sudo apt-get install php-mcrypt

$ sudo /etc/init.d/apache2 restart

Base de dades


DROP TABLE login;

CREATE TABLE login (
id_login smallint primary key,
NIF char(9) not null,
nom varchar(30) not null,
cognoms varchar(30) not null,
login varchar(10) not null,
clau varchar(50) not null,
direccio varchar(30),
CP char(5),
poblacio varchar(30),
telefon varchar(20) not null,
mobil varchar(30),
mail varchar(30)
);

Connexió a la base de dades

open_db.php:

<?php
$conn = mysqli_connect("localhost", "alumne", "keiL2lai");
if (!$conn) {
    $log->error('Could not connect: ' . mysql_error());
    die('Could not connect: ' . mysql_error());
}
mysqli_select_db($conn, "jbalmes") or die('Could not select jbalmes database.');
?>

close_db.php:

<?php
	mysqli_close($conn);
?>

Registre: inserció i consulta a la base de dades

contacte.php:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
    <meta name="description" content="">
    <meta name="author" content="">
    <link rel="icon" href="../../favicon.ico">

    <title>Tenda del Balmes</title>

    <!-- Bootstrap core CSS -->
    <link href="css/bootstrap.min.css" rel="stylesheet">

    <!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
    <link href="assets/css/ie10-viewport-bug-workaround.css" rel="stylesheet">

    <!-- Custom styles for this template -->
    <link href="navbar.css" rel="stylesheet">

    <!-- Custom styles for Balmestenda -->
    <link href="css/balmestenda.css" rel="stylesheet">

    <!-- Just for debugging purposes. Don't actually copy these 2 lines! -->
    <!--[if lt IE 9]><script src="../../assets/js/ie8-responsive-file-warning.js"></script><![endif]-->
    <script src="assets/js/ie-emulation-modes-warning.js"></script>

    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
  </head>

  <body>

    <div class="container">

      <!-- Static navbar -->
      <nav class="navbar navbar-default">
        <div class="container-fluid">
          <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
              <span class="sr-only">Toggle navigation</span>
              <span class="icon-bar"></span>
              <span class="icon-bar"></span>
              <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="#">Tenda del Balmes</a>
          </div>
          <div id="navbar" class="navbar-collapse collapse">
            <ul class="nav navbar-nav">
              <li><a href="index.php">Home</a></li>
              <li><a href="#">About</a></li>
              <li class="active"><a href="contacte.php">Contacte</a></li>
              <li class="dropdown">
                <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
                <ul class="dropdown-menu">
                  <li><a href="#">Action</a></li>
                  <li><a href="#">Another action</a></li>
                  <li><a href="#">Something else here</a></li>
                  <li role="separator" class="divider"></li>
                  <li class="dropdown-header">Nav header</li>
                  <li><a href="#">Separated link</a></li>
                  <li><a href="#">One more separated link</a></li>
                </ul>
              </li>
            </ul>
            <ul class="nav navbar-nav navbar-right">
              <li class="active"><a href="./">Default <span class="sr-only">(current)</span></a></li>
              <li><a href="../navbar-static-top/">Static top</a></li>
              <li><a href="../navbar-fixed-top/">Fixed top</a></li>
            </ul>
          </div><!--/.nav-collapse -->
        </div><!--/.container-fluid -->
      </nav>

      <!-- Main component for a primary marketing message or call to action -->
      <div class="jumbotron">
        <?php
        if (isset($_POST['enviar'])) {
          $vnif=trim($_POST['nif']);
          $vnom=trim($_POST['nom']);
          $vcognoms=trim($_POST['cognoms']);
          $vlogin=trim($_POST['login']);
          $vpwd=trim($_POST['pwd']);
          $vdireccio=trim($_POST['direccio']);
          $vcp=trim($_POST['cp']);
          $vpoblacio=trim($_POST['poblacio']);
          $vtelefon=trim($_POST['telefon']);
          $vmobil=trim($_POST['mobil']);
          $vmail=trim($_POST['mail']);

          $key = '123456789012345678901234567890123456789012345678901234567890';

          //$ sudo apt-get install php-mcrypt
          //reiniciar Apache!
          //http://php.net/manual/en/function.mcrypt-encrypt.php
          $vpwd = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, substr($key,0,32), $vpwd, MCRYPT_MODE_CBC,substr($key,32,16));
          $vpwd=bin2hex($vpwd);
          //echo $vpwd;
 
          include("open_db.php");

          $sql = "select max(id_login) as max_id_login from login";
          $result = mysqli_query($conn,$sql);
          $row = mysqli_fetch_assoc($result);

          if (!isset($row['max_id_login'])){
            $vid_login=1;
          } else {
            $vid_login=$row['max_id_login']+1;
          }         

          $sqlstring  = "INSERT INTO login ";
          $sqlstring .= "(id_login,NIF,nom,cognoms,login,clau,direccio,CP,poblacio,telefon,mobil,mail) values (";
          $sqlstring .= $vid_login . ",'" . $vnif . "','" . fixQuotes($vnom) . "','" . fixQuotes($vcognoms) . "','" . fixQuotes($vlogin) . "','" . $vpwd . "',";
          $sqlstring .= "'" . fixQuotes($vdireccio) . "','" . $vcp . "','" . fixQuotes($vpoblacio) . "','" . $vtelefon . "','" . $vmobil . "','" . $vmail . "')";

          //echo $sqlstring;
          $result = mysqli_query($conn,$sqlstring);
          if (!$result) {
             $message  = 'Invalid query: ' . mysql_error() . "\n";
             die($message);
          }

          echo "<h3>S'ha afegit l'usuari ".$vnom." a la base de dades</h3>";
          echo "<h3>Falta validar correctament el formulari (Javascript)</h3>";

          include("close_db.php");
        }

        ?>
        <h2>Formulari de registre</h2>
        <form id="form1" name="form_registre" method="post" action="contacte.php">
        <label>NIF:</label><input type="text" name="nif" /><br />
        <label>Nom:</label><input type="text" name="nom" /><br />
        <label>Cognoms:</label><input type="text" name="cognoms" /><br />
        <label>Login:</label><input type="text" name="login" /><br />
        <label>Clau:</label><input type="password" name="pwd" /><br />
        <label>Repetir clau:</label><input type="password" name="pwd2" /><br />
        <label>Direcció:</label><input type="text" name="direccio" /><br />
        <label>CP:</label><input type="text" name="cp" /><br />
        <label>Població:</label><input type="text" name="poblacio" /><br />
        <label>Telèfon:</label><input type="text" name="telefon" /><br />
        <label>Mòbil:</label><input type="text" name="mobil" /><br />
        <label>Mail:</label><input type="text" name="mail" /><br /><br />
        <label></label><input type="submit" name="enviar" value="Enviar" /><br />
        <!-- <label></label><a class="btn btn-lg btn-primary" role="button" href="#" onclick="document.forms['form_registre'].submit(); return false;">Enviar</a><br /> -->
 
        </form>
     </div>

    </div> <!-- /container -->


    <!-- Bootstrap core JavaScript
    ================================================== -->
    <!-- Placed at the end of the document so the pages load faster -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <script>window.jQuery || document.write('<script src="../../assets/js/vendor/jquery.min.js"><\/script>')</script>
    <script src="js/bootstrap.min.js"></script>
    <!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
    <script src="assets/js/ie10-viewport-bug-workaround.js"></script>
  </body>
</html>

<?php
function fixQuotes($cadena){
  return str_replace("'","''",$cadena);
}
?>

En aquest moment ja pots consultar la taula login de la base de dades, i veure els usuaris que es van registrant, icom la clau es guarda encriptada.

Desenvolupament

L'alumne disposa de tots els recursos (fitxers php, css, imatges, scripts de bd). Per tant, l'única cosa que farà és instal.lar aquests fitxers en el seu servidor web (a l'hora que es mira, entén i estudia el codi). El professor certificarà el bon funcionament de la pràctica. Pots fer diferents captures de pantalla, i fer una select de la taula login.

Nota: per habilitar els warnings i errors en la pantalla del navegador, llegir Llenguatges_de_guions_de_servidor._PHP._Introducció#Gesti.C3.B3_dels_errors_i_logging

obligatori:

1. En la pràctica del formulari de la tenda havies afegit tres camps al formulari: gènere (home/dona), comarca, i comentaris. Ara aquesta informació també s'haurà d'emmagatzemar a la base de dades. Per tant, tindràs que afegir aquests tres camps a la taula login, i modificar el codi PHP del script contacte.php per tal de què en fer insert aquesta informació quedi emmagatzemada a la taula.

2. La pàgina producte.php està buida. Has de crear a la bd la taula PRODUCTE (id_producte, nom, quantitat, preu), ficar-hi (manualment) 10 productes com a mínim, i en la pàgina producte.php has de mostrar els productes, bolcats en una taula (procura que la taula conservi el disseny de la pàgina, pots mirar el full d'estils). Quan funcioni, fes una captura de pantalla)


opcional: Pots categoritzar els productes. Crea la taula categoria (id_categoria, categoria), i afegeix el camp id_categoria a la taula productes. En la taula html que has de formatar t'ha d'aparèixer: id_producte, producte, preu, categoria.

Solució. Millores

Volem que si fiquem accents en la població, comentaris, etc, els accents es guardin bé a la bd. Per això afegirem al final del fitxer open_db.php:

mysql_set_charset('utf8',$conn);

Finalment, hem modificat el fitxer registre.php per tal de què:

ALTER TABLE login ADD COLUMN genere VARCHAR(6) NULL;
ALTER TABLE login ADD COLUMN id_comarca SMALLINT NULL;
ALTER TABLE login ADD COLUMN comentaris VARCHAR(255) NULL;

COMENTARI: Una de les coses que pretén el codi és que quan no fico res en els camps opcionals, a la bd quedi emmagatzemat el valor de NULL (en comptes de cadena buida). Mira dins el codi com es fa això.

Si a la base de dades vull cercar quants usuaris han ficat comentaris, i quants no, hem de saber tractar correctament amb els valors NULL:

select count(*) from login -> 18 files, són les files totals

select count(*) from login where comentaris='' -> 2 -> són els usuaris que havia registrat abans de fer les modificacions
select count(*) from login where comentaris<>'' -> 5 -> són els usuaris que han ficat comentaris
select count(*) from login where comentaris = NULL -> 0 -> això sempre donarà 0, doncs aquesta select està mal plantejada.
select count(*) from login where comentaris IS NULL -> 11 -> els usuaris que no fiquen comentaris tenen un NULL en aquest camp.

Entrega

Recorda la normativa per entregar les pràctiques al Google Classroom: ASIX-M10-UF2#Normativa_d.27entrega_de_les_pr.C3.A0ctiques_al_Google_Classroom


creat per Joan Quintana Compte, desembre 2018

Eines de l'usuari
Espais de noms
Variants
Accions
Navegació
Institut Jaume Balmes
Màquines recreatives
CNC
Informàtica musical
joanillo.org Planet
Eines