+ * Esercizio "Maratona" in PHP
+ * Testo dell'esercizio disponibile sul sito web dell'autore (www.andreacaravano.net)
+ * Ultima modifica: 30/06/2020
+ * Descrizione: Possibile soluzione all'esercizio "Maratona" in PHP
+ * N.B.: L'esercizio scaturisce dalla sola fantasia dell'autore e intende rappresentare una applicazione didattica.
+ * I dettagli in esso contenuti potrebbero non essere corrispondenti alla realtà e intendono valutare le abilità nella gestione delle strutture dati proposte.
+$tipologiaDocumento = "";
+$identificativoDocumento = "";
+$strumentiElettronici = "";
+function tornaCheckBox($vettCheckBox)
+ foreach ($vettCheckBox as $elemento) {
+ if (array_search($elemento, $vettCheckBox) != count($vettCheckBox) - 1) {
+function stampaPassword($pass)
+ for ($i = 0; $i < strlen($pass); $i++) {
+ if ($i == 0 || $i == strlen($pass) - 1 || $i == strlen($pass) - 2 || $i == strlen($pass) - 3) {
+ } else $ritorno .= "*";
+function controlloServer()
+ global $cognome, $nome, $dataNascita, $comune, $nazione, $tipologiaDocumento, $identificativoDocumento, $codiceFiscale, $numeroTessera, $categoria, $strumentiElettronici, $mail, $pass, $esito, $continuaStampa;
+ $continuaStampa = false;
+ $cognome = $_REQUEST["cognome"];
+ $nome = $_REQUEST["nome"];
+ $dataNascita = $_REQUEST["data-nascita"];
+ $comune = $_REQUEST["comune"];
+ $nazione = $_REQUEST["nazione"];
+ $tipologiaDocumento = $_REQUEST["tipologia-documento"];
+ $identificativoDocumento = $_REQUEST["identificativo-documento"];
+ $codiceFiscale = $_REQUEST["codice-fiscale"];
+ $numeroTessera = $_REQUEST["numero-tessera"];
+ $categoria = $_REQUEST["categoria"];
+ $strumentiElettronici = $_REQUEST["strumenti-elettronici"];
+ $mail = $_REQUEST["mail"];
+ $pass = $_REQUEST["pass"];
+ $regexDataNascita = "/^[0-9]{4}[-]{1}[0-9]{2}[-]{1}[0-9]{2}$/";
+ $regexIdentificativoDocumento = "/^[A-Za-z]{2}[0-9]{1,}$/";
+ $regexCodiceFiscale = "/^[A-Z]{6}[0-9]{2}[A-Z]{1}[0-9]{2}[A-Z]{1}[0-9]{3}[A-Z]{1}$/";
+ $regexNumeroTessera = "/^[0-9]{9}129$/";
+ $regexMail = "/^[a-z0-9._-]{1,}@[a-z0-9.-]{3,}\\.[a-z]{2,}$/";
+ $regexCategoriaAtleta = "/^[1-7]$/";
+ if (strlen($cognome) < 1 || strlen($cognome) > 150) {
+ $vettErrori[$contaErrori] = "cognome";
+ if (strlen($nome) < 1 || strlen($nome) > 100) {
+ $vettErrori[$contaErrori] = "nome";
+ if (preg_match($regexDataNascita, $dataNascita) == false) {
+ $vettErrori[$contaErrori] = "Data di nascita";
+ if (strlen($comune) < 2) {
+ $vettErrori[$contaErrori] = "Comune di nascita";
+ if (strlen($nazione) < 3) {
+ $vettErrori[$contaErrori] = "Nazione di nascita";
+ if (isset($tipologiaDocumento) == false || ($tipologiaDocumento == "Carta d'identità" || $tipologiaDocumento == "Patente di guida") == false) {
+ $vettErrori[$contaErrori] = "Tipologia documento";
+ if (preg_match($regexIdentificativoDocumento, $identificativoDocumento) == false) {
+ $vettErrori[$contaErrori] = "Identificativo del documento";
+ if (preg_match($regexCodiceFiscale, $codiceFiscale) == false || strlen($codiceFiscale) != 16) {
+ $vettErrori[$contaErrori] = "Codice Fiscale";
+ if (preg_match($regexNumeroTessera, $numeroTessera) == false || strlen($numeroTessera) != 12) {
+ $vettErrori[$contaErrori] = "Numero tessera";
+ if (isset($categoria) == false || preg_match($regexCategoriaAtleta, $categoria) == false) {
+ $vettErrori[$contaErrori] = "Categoria atleta";
+ if (count($strumentiElettronici) == 0 || (array_search("Fascia di rilevazione delle cardio-frequenze", $strumentiElettronici) >= 0 || array_search("Contapassi", $strumentiElettronici) >= 0 || array_search("Sensori di rilevazione dei grassi e calorie consumate", $strumentiElettronici) >= 0) == false) {
+ $vettErrori[$contaErrori] = "Strumenti elettronici";
+ if (preg_match($regexMail, $mail) == false || strlen($mail) < 8) {
+ $vettErrori[$contaErrori] = "E-mail";
+ if (strlen($pass) < 10 || strlen($pass) > 80) {
+ $vettErrori[$contaErrori] = "Password";
+ if ($contaErrori > 0) {
+ $continuaStampa = false;
+ $esito = "<span style='color: #FF7070; font-weight: bold;'>Rilevati errori nei campi: ";
+ for ($i = 0; $i < $contaErrori; $i++) {
+ $esito .= $vettErrori[$i];
+ if ($i != $contaErrori - 1)
+ $continuaStampa = true;
+ $esito = "<span style='color: #339966; font-weight: bold;'>Registrazione conclusa con successo. Riepilogo dati:</span>";
+ } catch (Exception $e) {
+ $continuaStampa = false;
+ $esito = "<span style='color: #FF7070; font-weight: bold;'>Errore di elaborazione dei dati. Si prega di riprovare, verificando di aver fornito tutti i dati richiesti.</span>";
+if (isset($_POST["submit"]) /* Alternativa: !empty($_REQUEST) */) {
+ if ((isset($_REQUEST["cognome"]) && isset($_REQUEST["nome"]) && isset($_REQUEST["data-nascita"]) &&
+ isset($_REQUEST["comune"]) && isset($_REQUEST["nazione"]) && isset($_REQUEST["tipologia-documento"]) &&
+ isset($_REQUEST["identificativo-documento"]) && isset($_REQUEST["codice-fiscale"]) && isset($_REQUEST["numero-tessera"]) &&
+ isset($_REQUEST["categoria"]) && isset($_REQUEST["strumenti-elettronici"]) && isset($_REQUEST["mail"]) && isset($_REQUEST["pass"])) == false) {
+ $continuaStampa = false;
+ $esito = "<span style='color: #FF7070; font-weight: bold;'>ATTENZIONE! Non sono stati compilati alcuni campi o non è stato possibile ricavarne i valori. Riprovare.</span>";
+ $continuaStampa = true;
+ Registrazione alla maratona
+ <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
+ integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh"
+ crossorigin="anonymous">
+ <main role="main" class="container" style="padding-top: 30px;">
+ <h1 style="padding-bottom: 30px; text-align: center;">
+ Ricevuta di registrazione
+ <table class="table table-striped table-bordered table-hover">
+ Ricevuta di registrazione
+ if ($continuaStampa == false)
+ echo controlloServer();
+ $dataNascita = explode("-", $dataNascita);
+ $dataNascita = $dataNascita[2] . "/" . $dataNascita[1] . "/" . $dataNascita[0];
+ Tipologia di documento:
+ echo $tipologiaDocumento;
+ Identificativo del documento:
+ echo $identificativoDocumento;
+ Categoria di appartenenza:
+ echo $categoria . "<sup>a</sup> categoria";
+ $giornata = "19 maggio";
+ $giornata = "18 maggio";
+ $giornata = "15 maggio";
+ $giornata = "14 maggio";
+ $giornata = "13 maggio";
+ $giornata = "12 maggio";
+ $giornata = "11 maggio";
+ $giornata = "Errore nella determinazione della giornata di gara.";
+ Numero di maglia (provvisorio):
+ Strumenti elettronici addizionali
+ echo tornaCheckBox($strumentiElettronici);
+ echo stampaPassword($pass);
+ Codice univoco di prenotazione:
+ 1. Trasformazione del cognome nelle corrispondenti codifiche decimali ASCII Standard (solo se stampabili, dunque esclusi spazi, caratteri speciali e non stampabili).
+ 2. Trasformazione del nome nelle corrispondenti codifiche decimali ASCII Standard (solo se stampabili, dunque esclusi spazi, caratteri speciali e non stampabili).
+ 3. Trasformazione della data di nascita nel corrispettivo formato concatenato GGMMAAAA.
+ 4. Estrapolazione delle prime 9 cifre del numero di tessera
+ for ($i = 0; $i < strlen($cognome); $i++) {
+ if (ctype_print($cognome[$i])) {
+ $codiceUnivoco .= ord($cognome[$i]);
+ for ($i = 0; $i < strlen($nome); $i++) {
+ if (ctype_print($nome[$i])) {
+ $codiceUnivoco .= ord($nome[$i]);
+ $codiceUnivoco .= str_replace("/", "", $dataNascita);;
+ $codiceUnivoco .= substr($numeroTessera, 0, 9);
+ Data e orario correnti:
+ echo date("d/m/Y - H:i:s")
+ <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"
+ integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n"
+ crossorigin="anonymous"></script>
+ <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"
+ integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"
+ crossorigin="anonymous"></script>
+ <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"
+ integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6"
+ crossorigin="anonymous"></script>
+ if (strlen($esito) != 0)
+ Registrazione alla maratona
+ <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
+ integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh"
+ crossorigin="anonymous">
+ <script type="text/javascript">
+ function controlloClient() {
+ var cognome = document.modulo.cognome.value;
+ var nome = document.modulo.nome.value;
+ var dataNascita = document.getElementById("data-nascita").value;
+ var comuneNascita = document.modulo.comune.value;
+ var nazioneNascita = document.modulo.nazione.value;
+ var tipologiaDocumento = tornaRadioCheckbox(document.getElementsByName("tipologia-documento"));
+ var identificativoDocumento = document.getElementById("identificativo-documento").value;
+ var codiceFiscale = document.getElementById("codice-fiscale").value;
+ var numeroTessera = document.getElementById("numero-tessera").value;
+ var categoriaAtleta = tornaSelect(document.modulo.categoria);
+ var strumentiElettronici = tornaRadioCheckbox(document.getElementsByName("strumenti-elettronici[]"));
+ var mail = document.modulo.mail.value;
+ var pass = document.modulo.pass.value;
+ var regexDataNascita = new RegExp("^[0-9]{4}[-]{1}[0-9]{2}[-]{1}[0-9]{2}$");
+ var regexIdentificativoDocumento = new RegExp("^[A-Za-z]{2}[0-9]{1,}$");
+ var regexCodiceFiscale = new RegExp("^[A-Z]{6}[0-9]{2}[A-Z]{1}[0-9]{2}[A-Z]{1}[0-9]{3}[A-Z]{1}$");
+ var regexNumeroTessera = new RegExp("^[0-9]{9}129$");
+ var regexMail = new RegExp("^[a-z0-9._-]{1,}@[a-z0-9.-]{3,}\\.[a-z]{2,}$");
+ var regexCategoriaAtleta = new RegExp("^[1-7]$");
+ if (cognome.length < 1 || cognome.length > 150) {
+ alert("Errore sul campo cognome!");
+ document.modulo.cognome.focus();
+ if (nome.length < 1 || nome.length > 100) {
+ alert("Errore sul campo nome!");
+ document.modulo.nome.focus();
+ if (regexDataNascita.test(dataNascita) == false) {
+ alert("Errore sul campo Data di nascita!");
+ document.getElementById("data-nascita").focus();
+ if (comuneNascita.length < 2) {
+ alert("Errore sul campo Comune di nascita!");
+ document.modulo.comune.focus();
+ if (nazioneNascita.length < 3) {
+ alert("Errore sul campo Nazione di nascita!");
+ document.modulo.nazione.focus();
+ if (tipologiaDocumento.length == 0 || (tipologiaDocumento == "Carta d'identità" || tipologiaDocumento == "Patente di guida") == false) {
+ alert("Errore sul campo Tipologia documento!");
+ if (regexIdentificativoDocumento.test(identificativoDocumento) == false || identificativoDocumento.length > 15) {
+ alert("Errore sul campo Identificativo del documento!");
+ document.getElementById("identificativo-documento").focus();
+ if (regexCodiceFiscale.test(codiceFiscale) == false || codiceFiscale.length != 16) {
+ alert("Errore sul campo Codice Fiscale!");
+ document.getElementById("codice-fiscale").focus();
+ if (regexNumeroTessera.test(numeroTessera) == false || numeroTessera.length != 12) {
+ alert("Errore sul campo Numero tessera!");
+ document.getElementById("numero-tessera").focus();
+ if (categoriaAtleta.length == 0 || regexCategoriaAtleta.test(categoriaAtleta) == false) {
+ alert("Errore sul campo Categoria atleta!");
+ if (strumentiElettronici.length == 0 || (strumentiElettronici.includes("Fascia di rilevazione delle cardio-frequenze") || strumentiElettronici.includes("Contapassi") || strumentiElettronici.includes("Sensori di rilevazione dei grassi e calorie consumate")) == false) {
+ alert("Errore sul campo Strumenti elettronici!");
+ if (regexMail.test(mail) == false || mail.length < 8) {
+ alert("Errore sul campo E-mail!");
+ document.modulo.mail.focus();
+ if (pass.length < 10 || pass.length > 80) {
+ alert("Errore sul campo Password!");
+ document.modulo.pass.focus();
+ console.log("Identificati " + contaErrori + " errori.");
+ console.warn("Eccezione non gestita: " + ERR);
+ function tornaRadioCheckbox(elemento) {
+ var contaSelezionati = 0;
+ for (var j = 0; j < elemento.length; j++) {
+ if (elemento[j].checked) {
+ var contaRitornati = 0;
+ for (var i = 0; i < elemento.length; i++) {
+ if (elemento[i].checked) {
+ ritorno += elemento[i].value;
+ if (contaSelezionati != contaRitornati)
+ function tornaSelect(elemento) {
+ return elemento.options[elemento.selectedIndex].value;
+ <main role="main" class="container" style="padding-top: 30px;">
+ <h1 style="padding-bottom: 30px; text-align: center;">
+ Modulo di registrazione alla maratona
+ <form id="modulo" name="modulo" action="<?php echo $_SERVER["PHP_SELF"] ?>" method="POST"
+ onsubmit="return controlloClient();">
+ <div class="form-group">
+ <table class="table table-striped table-bordered table-hover">
+ Modulo di registrazione
+ <input type="text" id="cognome" name="cognome" minlength="1" maxlength="150"
+ <input type="text" id="nome" name="nome" minlength="1" maxlength="100"
+ <label for="data-nascita">
+ <input type="date" id="data-nascita" name="data-nascita"
+ pattern="^[0-9]{4}[-]{1}[0-9]{2}[-]{1}[0-9]{2}$" required/>
+ <input type="text" id="comune" name="comune" minlength="2" required/>
+ <input type="text" id="nazione" name="nazione" minlength="3" required/>
+ Tipologia di documento:
+ <input type="radio" id="carta-identita" name="tipologia-documento"
+ value="Carta d'identità" checked/>
+ <label for="carta-identita">
+ Carta d'identià
+ <input type="radio" id="patente" name="tipologia-documento"
+ value="Patente di guida"/>
+ <label for="identificativo-documento">
+ Identificativo del documento:
+ <input type="text" id="identificativo-documento"
+ name="identificativo-documento"
+ maxlength="15" pattern="^[A-Za-z]{2}[0-9]{1,}$" required/>
+ <label for="codice-fiscale">
+ <input type="text" id="codice-fiscale" name="codice-fiscale" minlength="16"
+ maxlength="16" size="16"
+ pattern="^[A-Z]{6}[0-9]{2}[A-Z]{1}[0-9]{2}[A-Z]{1}[0-9]{3}[A-Z]{1}$"
+ <label for="numero-tessera">
+ <input type="number" id="numero-tessera" name="numero-tessera"
+ maxlength="12" size="12" pattern="^[0-9]{9}129$" required/>
+ <label for="categoria">
+ Categoria di appartenenza:
+ <select id="categoria" name="categoria">
+ for ($i = 1; $i <= 7; $i++) {
+ echo "<option value='" . $i . "'" . (($i == 1) ? " selected='selected'" : "") . ">" . $i . "° categoria</option>";
+ Strumenti elettronici addizionali
+ <input type="checkbox" id="fascia-cardio" name="strumenti-elettronici[]"
+ value="Fascia di rilevazione delle cardio-frequenze"/>
+ <label for="fascia-cardio">
+ Fascia di rilevazione delle cardio-frequenze
+ <input type="checkbox" id="contapassi" name="strumenti-elettronici[]"
+ <label for="contapassi">
+ <input type="checkbox" id="sensori-grassi-calorie"
+ name="strumenti-elettronici[]"
+ value="Sensori di rilevazione dei grassi e calorie consumate"/>
+ <label for="sensori-grassi-calorie">
+ Sensori di rilevazione dei grassi e calorie consumate
+ <input type="email" id="mail" name="mail" minlength="8"
+ pattern="^[a-z0-9._-]{1,}@[a-z0-9.-]{3,}\.[a-z]{2,}$" required/>
+ <input type="password" id="pass" name="pass" minlength="10" maxlength="80"
+ <td style="text-align: right;">
+ <input type="submit" name="submit" class="btn btn-primary"
+ value="Conferma invio dati"/>
+ <input type="reset" class="btn btn-secondary"
+ value="Azzera i campi del modulo"/>
+ <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"
+ integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n"
+ crossorigin="anonymous"></script>
+ <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"
+ integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"
+ crossorigin="anonymous"></script>
+ <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"
+ integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6"
+ crossorigin="anonymous"></script>