Seconda prova informatica: "studio dentistico" Esame di Stato
2a
prova di informatica:
Traccia:
Uno
studio medico associato, in cui operano medici di base e medici specialisti, dà
incarico a una società d’informatica di progettare e realizzare un database
contenente i dati anagrafici e professionali dei medici, l’orario delle visite,
i tempi medi previsti per ogni visita, il costo delle singole prestazioni, i
dati anagrafici dei pazienti e le prestazioni richieste.
Elaborare,
dopo aver descritto le caratteristiche dell’applicativo che si intende
utilizzare, il progetto definendone i dati necessari e dettagliando la
procedura per risolvere la prima e altre due richieste tra quelle indicate:
1. Definire
il modello concettuale
2. Definire
il modello logico
3. Definire
il modello fisico del database e delle tabelle in sql
4. Verificare
la normalizzazione del database
5. Verificare
l’integrità referenziale
6. Definire
le chiavi primarie e le chiavi esterne
7. Creare
il sito Web completo html, css, php e mysqli con area riservata (password
criptata) che gestisce il database
8. Una
pagina php con l’elenco giornaliero delle visite prenotate per ogni singolo
medico;
9. Una
pagina php con l’elenco giornaliero delle visite prenotate e non effettuate;
10.Una
pagina php con l’elenco settimanale contenente gli appuntamenti di ciascun
medico suddivisi per giorno e per ora;
11.
Una
pagina php con l’elenco cronologico delle visite usufruite da ciascun paziente.
12.
Realizzare,
infine, la pagina web con la quale lo studio medico pubblicizza la propria
attività fornendo l’indicazione dei servizi e il quadro orario.
13.
Dati
mancanti opportunamente scelti.
Per
sviluppare la soluzione, seguiamo i seguenti passaggi:
Caratteristiche
dell'Applicativo
L'applicativo
sarà un sistema di gestione delle informazioni mediche basato su un database
relazionale. L'interfaccia sarà un sito web in HTML, CSS e PHP, con
l'interazione con il database tramite MySQLi. L'accesso sarà regolato tramite
aree riservate con password criptate.
Progetto
del Database
Dati Necessari
1. Medici:
- ID Medico
- Nome
-
Cognome
- Specializzazione
- Dati Anagrafici
2. Pazienti:
- ID Paziente
- Nome
- Cognome
- Dati Anagrafici
3. Appuntamenti:
- ID Appuntamento
- ID Medico
- ID Paziente
- Data e Ora
- Prestazione Richiesta
- Stato (Prenotata, Non Effettuata,
Conclusa)
4. Prestazioni:
- ID Prestazione
- Descrizione
- Costo
- Tempo Medio
Attività
Richieste
Scegliamo
le seguenti attività:
1. Definire
il modello concettuale.
2. Definire
il modello logico.
3. Definire
il modello fisico e le tabelle SQL.
1.
Modello Concettuale
Nella
fase concettuale, usiamo un diagramma ER (Entity-Relationship):
- Entità:
Medico, Paziente, Appuntamento, Prestazione
- Relazioni:
- Medico ha molti Appuntamenti
- Paziente ha molti Appuntamenti
- Appuntamento include una Prestazione
2. Modello Logico
Nel
modello logico, determiniamo le relazioni tra le entità:
- Medico
(ID Medico, Nome, Cognome, Specializzazione)
- Paziente (ID Paziente, Nome, Cognome)
- Prestazione
(ID Prestazione, Descrizione, Costo, Tempo Medio)
- Appuntamento
(ID Appuntamento, ID Medico, ID Paziente, ID Prestazione, Data, Ora, Stato)
3.
Modello Fisico e SQL
Creiamo
le tabelle in SQL:
```sql
CREATE
TABLE Medico (
ID_Medico INT AUTO_INCREMENT PRIMARY KEY,
Nome VARCHAR(50),
Cognome VARCHAR(50),
Specializzazione VARCHAR(100)
);
CREATE
TABLE Paziente (
ID_Paziente INT AUTO_INCREMENT PRIMARY KEY,
Nome VARCHAR(50),
Cognome VARCHAR(50)
);
CREATE TABLE Prestazione (
ID_Prestazione INT AUTO_INCREMENT PRIMARY
KEY,
Descrizione VARCHAR(255),
Costo DECIMAL(10,2),
Tempo_Medio INT
);
CREATE
TABLE Appuntamento (
ID_Appuntamento INT AUTO_INCREMENT PRIMARY
KEY,
ID_Medico INT,
ID_Paziente INT,
ID_Prestazione INT,
Data DATE,
Ora TIME,
Stato ENUM('Prenotata', 'Non Effettuata',
'Conclusa'),
FOREIGN KEY (ID_Medico) REFERENCES
Medico(ID_Medico),
FOREIGN KEY (ID_Paziente) REFERENCES
Paziente(ID_Paziente),
FOREIGN KEY (ID_Prestazione) REFERENCES
Prestazione(ID_Prestazione)
);
```
Questo
schema copre le esigenze descritte nella traccia, permettendo la gestione delle
informazioni dei medici, dei pazienti e delle prestazioni, con un focus sugli
appuntamenti. Puoi continuare sviluppando il front-end con pagine PHP per
visualizzare le prenotazioni, gestire l’accesso riservato con password, e
pubblicizzare i servizi dello studio medico.
Continuiamo
con lo sviluppo delle pagine PHP e l'integrazione front-end.
Pagine PHP
per Gestione Appuntamenti
1.
Elenco Giornaliero delle Visite Prenotate per Ogni Singolo Medico
Creiamo una pagina `elenco_visite.php` che
mostra le visite giornaliere prenotate:
```php
<?php
include 'connessione_db.php'; // Include il
file di connessione al database
$data_oggi = date('Y-m-d');
$query = "SELECT Medico.Nome as
NomeMedico, Medico.Cognome as CognomeMedico, Appuntamento.Ora, Paziente.Nome as
NomePaziente, Paziente.Cognome as CognomePaziente
FROM Appuntamento
JOIN Medico ON
Appuntamento.ID_Medico = Medico.ID_Medico
JOIN Paziente ON
Appuntamento.ID_Paziente = Paziente.ID_Paziente
WHERE Appuntamento.Data =
'$data_oggi' AND Appuntamento.Stato = 'Prenotata'
ORDER BY Medico.Nome,
Medico.Cognome, Appuntamento.Ora";
$result = mysqli_query($conn, $query);
while ($row = mysqli_fetch_assoc($result)) {
echo "<p>Dr. " .
$row['NomeMedico'] . " " . $row['CognomeMedico'] . " - " .
$row['Ora'] . " - " . $row['NomePaziente'] . " " .
$row['CognomePaziente'] . "</p>";
}
mysqli_close($conn);
?>
```
2.
Elenco Giornaliero delle Visite Prenotate e Non Effettuate
Questa pagina mette in evidenza gli
appuntamenti prenotati ma non effettuati (`elenco_non_effettuate.php`):
```php
<?php
include 'connessione_db.php';
$query = "SELECT Medico.Nome as
NomeMedico, Medico.Cognome as CognomeMedico, Appuntamento.Data,
Appuntamento.Ora, Paziente.Nome as NomePaziente, Paziente.Cognome as
CognomePaziente
FROM Appuntamento
JOIN Medico ON
Appuntamento.ID_Medico = Medico.ID_Medico
JOIN Paziente ON
Appuntamento.ID_Paziente = Paziente.ID_Paziente
WHERE Appuntamento.Stato = 'Non
Effettuata'
ORDER BY Appuntamento.Data,
Appuntamento.Ora";
$result = mysqli_query($conn, $query);
= mysqli_fetch_assoc($result)) {
echo "<p>Dr. " .
$row['NomeMedico'] . " " . $row['CognomeMedico'] . " - " .
$row['Data'] . " " . $row['Ora'] . " - " .
$row['NomePaziente'] . " " . $row['CognomePaziente'] .
"</p>";
}
mysqli_close($conn);
?>
```
3.
Pagina con Cronologia delle Visite di Ciascun Paziente
Per mostrare la cronologia delle visite
effettuate da ciascun paziente, creare `cronologia_visite.php`:
```php
<?php
include 'connessione_db.php';
$query = "SELECT Paziente.Nome as
NomePaziente, Paziente.Cognome as CognomePaziente, Appuntamento.Data,
Appuntamento.Ora, Medico.Nome as NomeMedico, Medico.Cognome as CognomeMedico
FROM Appuntamento
JOIN Medico ON
Appuntamento.ID_Medico = Medico.ID_Medico
JOIN Paziente ON
Appuntamento.ID_Paziente = Paziente.ID_Paziente
WHERE Appuntamento.Stato =
'Conclusa'
ORDER BY Paziente.ID_Paziente,
Appuntamento.Data";
$result = mysqli_query($conn, $query);
while ($row = mysqli_fetch_assoc($result)) {
echo "<p>Paziente: " .
$row['NomePaziente'] . " " . $row['CognomePaziente'] . " - Dr.
" . $row['NomeMedico'] . " " . $row['CognomeMedico'] . " -
" . $row['Data'] . " " . $row['Ora'] . "</p>";
}
mysqli_close($conn);
?>
```
Pubblicità
dello Studio Medico
Infine,
per pubblicizzare lo studio medico e i suoi servizi, creiamo una pagina web
statica `pubblicita.php`:
```html
<!DOCTYPE
html>
<html
lang="it">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, initial-scale=1.0">
<title>Studio Medico Associato -
Servizi</title>
<link rel="stylesheet"
href="stile.css">
</head>
<body>
<header>
<h1>Benvenuti allo Studio Medico
Associato</h1>
</header>
<main>
<section>
<h2>Servizi
Offerti</h2>
<p>Offriamo una vasta gamma
di servizi medici, dai controlli di routine alle specializzazioni più
avanzate.</p>
</section>
<section>
<h2>Orario di
Apertura</h2>
<ul>
<li>Lunedì - Venerdì: 8:00 - 20:00</li>
<li>Sabato: 9:00 -
13:00</li>
<li>Chiuso la
Domenica</li>
</ul>
</section>
</main>
<footer>
<p>Contattaci al numero:
123-456-789</p>
</footer>
</body>
</html>
```
Note
Finali step 1
Assicurati
di avere un sistema di sicurezza robusto per gestire i dati sensibili,
utilizzando protocolli HTTPS per proteggere le comunicazioni. Inoltre, per la
gestione delle password, usa funzioni di hashing sicure come `password_hash` in
PHP.
Questa
implementazione serve come base per espandere ulteriormente le funzionalità
secondo le esigenze specifiche dello studio medico. Puoi integrare calendari
dinamici, sistemi di notifiche e moduli di contatto per migliorare l'esperienza
dell'utente.
Step 2
Creare
un sito web completo con funzionalità di login per un livello di accesso
amministrativo richiede l'implementazione delle seguenti componenti:
1.
Struttura del Progetto
- PHP Pages: Per gestire il back-end.
- HTML & CSS: Per creare un'interfaccia
utente.
- Database MySQL: Per memorizzare i dati
relativi al sistema di login e alle operazioni CRUD (Create, Read, Update,
Delete).
2.
Database Setup
Iniziamo con il setup del database:
```sql
CREATE DATABASE studio_dentistico;
USE studio_dentistico;
CREATE TABLE Utenti (
ID_Utente INT AUTO_INCREMENT PRIMARY
KEY,
Username VARCHAR(50) NOT NULL UNIQUE,
Password_Hashed VARCHAR(255) NOT NULL,
Ruolo ENUM('amministratore', 'utente')
DEFAULT 'utente'
);
CREATE TABLE Pazienti (
ID_Paziente INT AUTO_INCREMENT PRIMARY
KEY,
Nome VARCHAR(50),
Cognome VARCHAR(50),
Data_Nascita DATE
);
CREATE TABLE Appuntamenti (
ID_Appuntamento INT AUTO_INCREMENT PRIMARY
KEY,
ID_Paziente INT,
Data DATE,
Ora TIME,
Descrizione VARCHAR(255),
FOREIGN KEY (ID_Paziente) REFERENCES
Pazienti(ID_Paziente)
);
```
3.
Connessione al Database
- connessione_db.php
```php
<?php
$host = 'localhost';
$db = 'studio_dentistico';
$user = 'root';
$pass = '';
$conn = new mysqli($host, $user, $pass,
$db);
if ($conn->connect_error) {
die("Connessione fallita: "
. $conn->connect_error);
}
?>
```
4.
Sistema di Login
- login.php
```php
<?php
session_start();
require 'connessione_db.php';
if ($_SERVER['REQUEST_METHOD'] === 'POST')
{
$username = $_POST['username'];
$password = $_POST['password'];
$query = "SELECT * FROM Utenti
WHERE Username=?";
$stmt = $conn->prepare($query);
$stmt->bind_param('s', $username);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows > 0) {
$utente =
$result->fetch_assoc();
if (password_verify($password,
$utente['Password_Hashed'])) {
$_SESSION['utente'] =
$utente['Username'];
$_SESSION['ruolo'] =
$utente['Ruolo'];
header("Location:
dashboard.php");
} else {
echo "Password non
corretta!";
}
} else {
echo "Utente non
trovato!";
}
}
?>
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<title>Login Studio
Dentistico</title>
<link rel="stylesheet"
href="stile.css">
</head>
<body>
<form action="login.php"
method="post">
<label
for="username">Username:</label>
<input type="text"
name="username" required><br>
<label
for="password">Password:</label>
<input type="password"
name="password" required><br>
<input type="submit"
value="Login">
</form>
</body>
</html>
```
5.
Dashboard e Operazioni CRUD
- dashboard.php (Pagina principale)
```php
<?php
session_start();
if (!isset($_SESSION['utente']) ||
$_SESSION['ruolo'] !== 'amministratore') {
header("Location:
login.php");
exit();
}
?>
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<title>Admin
Dashboard</title>
<link rel="stylesheet"
href="stile.css">
</head>
<body>
<h1>Benvenuto,
Amministratore</h1>
<nav>
<a
href="gestione_utenti.php">Gestione Utenti</a>
<a href="gestione_pazienti.php">Gestione
Pazienti</a>
<a
href="gestione_appuntamenti.php">Gestione Appuntamenti</a>
<a
href="logout.php">Logout</a>
</nav>
</body>
</html>
```
6.
Gestione Utenti
Implementare le pagine necessarie per la
gestione CRUD di utenti, pazienti e appuntamenti (i file `gestione_utenti.php`,
`gestione_pazienti.php`, `gestione_appuntamenti.php`) seguendo la stessa
struttura fondamentale di operazioni CRUD con controlli di accesso.
7.
Stile CSS
- stile.css
```css
body {
font-family: Arial, sans-serif;
background-color: #f4f4f9;
margin: 0;
padding: 0;
}
form {
background: #fff;
padding: 20px;
margin: 50px auto;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0,
0.1);
width: 300px;
}
label {
display: block;
margin-bottom: 5px;
}
input[type="text"],
input[type="password"] {
width: 100%;
padding: 8px;
margin-bottom: 10px;
border-radius: 5px;
border: 1px solid #ddd;
}
input[type="submit"] {
background: #0288d1;
color: #fff;
padding: 10px;
border: none;
border-radius: 5px;
cursor: pointer;
}
nav a {
margin: 0 10px;
color: #0288d1;
text-decoration: none;
}
nav a:hover {
text-decoration: underline;
}
```
8.
Logout
- logout.php
```php
<?php
session_start();
session_destroy();
header("Location: login.php");
exit();
```
Considerazioni
Finali
- Per
creare un sistema di login robusto, assicurati di implementare protezioni
contro SQL Injection usando PDO o MySQLi moderni con prepared statements.
-
Assicurati che tutte le password siano salvate usando funzioni di hashing
sicure, come `password_hash`.
-
L'accesso a operazioni CRUD deve essere rigorosamente riservato agli
amministratori, con il controllo impostato all'inizio di ciascun script PHP.
-
Considera l'uso di HTTPS per garantire la sicurezza dei dati in transito.
Questa
struttura offre una base per ulteriori espansioni e personalizzazioni, in base
alle necessità dello studio dentistico.
Step 3
Creare
una gestione completa delle tabelle in PHP per medici, pazienti, appuntamenti e
prestazioni include la possibilità di eseguire le funzioni CRUD (Create, Read,
Update, Delete) su ciascuna di queste tabelle. Procederò a fornire una
struttura di base per ogni componente:
Struttura
del Sistema
1. Connessione al Database
- connessione_db.php
```php
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "studio_medico";
$conn = new mysqli($servername,
$username, $password, $dbname);
if ($conn->connect_error) {
die("Connessione fallita: "
. $conn->connect_error);
}
?>
```
2. Pagina di gestione per
ciascuna tabella
A. Gestione Medici
- gestione_medici.php
```php
<?php
session_start();
require 'connessione_db.php';
if (!isset($_SESSION['utente']) ||
$_SESSION['ruolo'] !== 'amministratore') {
header("Location:
login.php");
exit();
}
if ($_SERVER['REQUEST_METHOD'] === 'POST')
{
if (!empty($_POST['action'])) {
$action = $_POST['action'];
$id = $_POST['id'] ?? null;
if ($action == 'create') {
$nome = $_POST['nome'];
$cognome = $_POST['cognome'];
$specializzazione =
$_POST['specializzazione'];
$query = "INSERT INTO
Medici (Nome, Cognome, Specializzazione) VALUES (?, ?, ?)";
$stmt =
$conn->prepare($query);
$stmt->bind_param('sss',
$nome, $cognome, $specializzazione);
$stmt->execute();
} elseif ($action == 'update'
&& $id) {
$nome = $_POST['nome'];
$cognome = $_POST['cognome'];
$specializzazione =
$_POST['specializzazione'];
$query = "UPDATE Medici SET Nome=?,
Cognome=?, Specializzazione=? WHERE ID_Medico=?";
$stmt =
$conn->prepare($query);
$stmt->bind_param('sssi',
$nome, $cognome, $specializzazione, $id);
$stmt->execute();
} elseif ($action == 'delete'
&& $id) {
$query = "DELETE FROM
Medici WHERE ID_Medico=?";
$stmt =
$conn->prepare($query);
$stmt->bind_param('i',
$id);
$stmt->execute();
}
}
}
$result = $conn->query("SELECT *
FROM Medici");
?>
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<title>Gestione
Medici</title>
<link rel="stylesheet"
href="stile.css">
</head>
<body>
<h1>Gestione Medici</h1>
<form
action="gestione_medici.php" method="post">
<input type="hidden"
name="action" value="create">
<input type="text"
name="nome" placeholder="Nome" required>
<input type="text"
name="cognome" placeholder="Cognome" required>
<input type="text"
name="specializzazione" placeholder="Specializzazione"
required>
<input type="submit"
value="Aggiungi Medico">
</form>
<table>
<tr>
<th>ID</th>
<th>Nome</th>
<th>Cognome</th>
<th>Specializzazione</th>
<th>Azioni</th>
</tr>
<?php while ($medico =
$result->fetch_assoc()) { ?>
<tr>
<form
action="gestione_medici.php" method="post">
<input
type="hidden" name="action" value="update">
<input
type="hidden" name="id" value="<?php echo
$medico['ID_Medico']; ?>">
<td><?php echo
$medico['ID_Medico']; ?></td>
<td><input
type="text" name="nome" value="<?php echo
$medico['Nome']; ?>" required></td>
<td><input
type="text" name="cognome" value="<?php echo
$medico['Cognome']; ?>" required></td>
<td><input
type="text" name="specializzazione" value="<?php
echo $medico['Specializzazione']; ?>" required></td>
<td>
<input
type="submit" value="Aggiorna">
</form>
<form
action="gestione_medici.php" method="post"
style="display:inline;">
<input
type="hidden" name="action" value="delete">
<input
type="hidden" name="id" value="<?php echo
$medico['ID_Medico']; ?>">
<input
type="submit" value="Elimina">
</form>
</td>
</tr>
<?php } ?>
</table>
</body>
</html>
```
B. Gestione Pazienti
- gestione_pazienti.php:
Segue la stessa struttura di `gestione_medici.php`, adattando i campi e le
query alla tabella dei pazienti. Sostituisci `Medici` con `Pazienti` e modifica
i relativi campi.
C. Gestione Appuntamenti
- gestione_appuntamenti.php
```php
<?php
session_start();
require 'connessione_db.php';
if (!isset($_SESSION['utente']) ||
$_SESSION['ruolo'] !== 'amministratore') {
header("Location:
login.php");
exit();
}
if ($_SERVER['REQUEST_METHOD'] === 'POST')
{
$action = $_POST['action'];
$id = $_POST['id'] ?? null;
if ($action == 'create') {
$id_paziente =
$_POST['id_paziente'];
$data = $_POST['data'];
$ora = $_POST['ora'];
$descrizione =
$_POST['descrizione'];
$query = "INSERT INTO Appuntamenti
(ID_Paziente, Data, Ora, Descrizione) VALUES (?, ?, ?, ?)";
$stmt = $conn->prepare($query);
$stmt->bind_param('isss',
$id_paziente, $data, $ora, $descrizione);
$stmt->execute();
} elseif ($action == 'update'
&& $id) {
$id_paziente =
$_POST['id_paziente'];
$data = $_POST['data'];
$ora = $_POST['ora'];
$descrizione =
$_POST['descrizione'];
$query = "UPDATE Appuntamenti
SET ID_Paziente=?, Data=?, Ora=?, Descrizione=? WHERE ID_Appuntamento=?";
$stmt = $conn->prepare($query);
$stmt->bind_param('isssi',
$id_paziente, $data, $ora, $descrizione, $id);
$stmt->execute();
} elseif ($action == 'delete' && $id)
{
$query = "DELETE FROM
Appuntamenti WHERE ID_Appuntamento=?";
$stmt = $conn->prepare($query);
$stmt->bind_param('i', $id);
$stmt->execute();
}
}
$result = $conn->query("SELECT *
FROM Appuntamenti JOIN Pazienti ON Appuntamenti.ID_Paziente =
Pazienti.ID_Paziente");
?>
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<title>Gestione Appuntamenti</title>
<link rel="stylesheet"
href="stile.css">
</head>
<body>
<h1>Gestione
Appuntamenti</h1>
<form
action="gestione_appuntamenti.php" method="post">
<input type="hidden"
name="action" value="create">
<input type="number" name="id_paziente"
placeholder="ID Paziente" required>
<input type="date"
name="data" required>
<input type="time"
name="ora" required>
<input type="text"
name="descrizione" placeholder="Descrizione" required>
<input type="submit"
value="Aggiungi Appuntamento">
</form>
<table>
<tr>
<th>ID</th>
<th>ID
Paziente</th>
<th>Data</th>
<th>Ora</th>
<th>Descrizione</th>
<th>Azioni</th>
</tr>
<?php while ($appuntamento =
$result->fetch_assoc()) { ?>
<tr>
<form
action="gestione_appuntamenti.php" method="post">
<input
type="hidden" name="action" value="update">
<input
type="hidden" name="id" value="<?php echo
$appuntamento['ID_Appuntamento']; ?>">
<td><?php echo
$appuntamento['ID_Appuntamento']; ?></td>
<td><input
type="number" name="id_paziente" value="<?php echo
$appuntamento['ID_Paziente']; ?>" required></td>
<td><input
type="date" name="data" value="<?php echo
$appuntamento['Data']; ?>" required></td>
<td><input
type="time" name="ora" value="<?php echo
$appuntamento['Ora']; ?>" required></td>
<td><input
type="text" name="descrizione" value="<?php echo
$appuntamento['Descrizione']; ?>" required></td>
<td>
<input
type="submit" value="Aggiorna">
</form>
<form
action="gestione_appuntamenti.php" method="post"
style="display:inline;">
<input
type="hidden" name="action" value="delete">
<input
type="hidden" name="id" value="<?php echo
$appuntamento['ID_Appuntamento']; ?>">
<input
type="submit" value="Elimina">
</form>
</td>
</tr>
<?php } ?>
</table>
</body>
</html>
```
D. Gestione Prestazioni
- gestione_prestazioni.php: Simile agli
altri, adattato per la tabella `Prestazioni`.
Considerazioni
Finali
- Sicurezza:
Assicurati che le interazioni col database siano sicure, usando sempre prepared
statements per prevenire SQL injection.
- Responsive
Design: Adatta lo stile CSS affinché il sito sia utilizzabile su diversi dispositivi.
- Autenticazione:
Mantieni la gestione delle sessioni e l'autenticazione rigorose, specialmente
per le operazioni amministrative.
- Validazione
input: Implementa la validazione degli input lato server per evitare la
corruzione dei dati.
Seguendo
questa guida, puoi completare la gestione di tutte le tabelle richieste con
operazioni CRUD.
Per
completare la gestione con la creazione delle tabelle mancanti e le pagine PHP,
segui i passi dettagliati di seguito. Creeremo le tabelle `Medici`, `Pazienti`,
`Appuntamenti` e `Prestazioni` nel database MySQL e svilupperemo le pagine PHP
per le operazioni CRUD (Create, Read, Update, Delete) per ciascuna di esse.
Creazione
delle Tabelle
Assicuriamoci
di avere tutte le tabelle necessarie nel database `studio_medico`:
```sql
CREATE
DATABASE IF NOT EXISTS studio_medico;
USE
studio_medico;
CREATE
TABLE IF NOT EXISTS Medici (
ID_Medico INT AUTO_INCREMENT PRIMARY KEY,
Nome VARCHAR(50),
Cognome VARCHAR(50),
Specializzazione VARCHAR(100)
);
CREATE
TABLE IF NOT EXISTS Pazienti (
ID_Paziente INT AUTO_INCREMENT PRIMARY KEY,
Nome VARCHAR(50),
Cognome VARCHAR(50),
Data_Nascita DATE
);
CREATE
TABLE IF NOT EXISTS Appuntamenti (
ID_Appuntamento INT AUTO_INCREMENT PRIMARY
KEY,
ID_Paziente INT,
ID_Medico INT,
Data DATE,
Ora TIME,
Descrizione VARCHAR(255),
FOREIGN KEY (ID_Paziente) REFERENCES
Pazienti(ID_Paziente),
FOREIGN KEY (ID_Medico) REFERENCES
Medici(ID_Medico)
);
CREATE
TABLE IF NOT EXISTS Prestazioni (
ID_Prestazione INT AUTO_INCREMENT PRIMARY
KEY,
Descrizione VARCHAR(255),
Costo DECIMAL(10, 2),
Durata INT
-- durata in minuti
);
```
Pagina
PHP per Gestione Medici
- gestione_medici.php
Questa
pagina consente la gestione dei medici con tutte le operazioni CRUD.
```php
<?php
session_start();
require
'connessione_db.php';
//
Verifica se l'utente è loggato e ha il ruolo di amministratore
if
(!isset($_SESSION['utente']) || $_SESSION['ruolo'] !== 'amministratore') {
header("Location: login.php");
exit();
}
//
Gestione delle azioni CRUD
if
($_SERVER['REQUEST_METHOD'] === 'POST') {
$action = $_POST['action'];
$id = $_POST['id'] ?? null;
if ($action == 'create') {
$nome = $_POST['nome'];
$cognome = $_POST['cognome'];
$specializzazione =
$_POST['specializzazione'];
$query = "INSERT INTO Medici
(Nome, Cognome, Specializzazione) VALUES (?, ?, ?)";
$stmt = $conn->prepare($query);
$stmt->bind_param('sss', $nome,
$cognome, $specializzazione);
$stmt->execute();
} elseif ($action == 'update' &&
$id) {
$nome = $_POST['nome'];
$cognome = $_POST['cognome'];
$specializzazione =
$_POST['specializzazione'];
$query = "UPDATE Medici SET
Nome=?, Cognome=?, Specializzazione=? WHERE ID_Medico=?";
$stmt = $conn->prepare($query);
$stmt->bind_param('sssi', $nome,
$cognome, $specializzazione, $id);
$stmt->execute();
} elseif ($action == 'delete' &&
$id) {
$query = "DELETE FROM Medici WHERE
ID_Medico=?";
$stmt = $conn->prepare($query);
$stmt->bind_param('i', $id);
$stmt->execute();
}
}
$result
= $conn->query("SELECT * FROM Medici");
?>
<!DOCTYPE
html>
<html
lang="it">
<head>
<meta charset="UTF-8">
<title>Gestione Medici</title>
<link rel="stylesheet"
href="stile.css">
</head>
<body>
<h1>Gestione Medici</h1>
<form action="gestione_medici.php"
method="post">
<input type="hidden"
name="action" value="create">
<input type="text"
name="nome" placeholder="Nome" required>
<input type="text"
name="cognome" placeholder="Cognome" required>
<input type="text"
name="specializzazione" placeholder="Specializzazione"
required>
<input type="submit"
value="Aggiungi Medico">
</form>
<table>
<tr>
<th>ID</th>
<th>Nome</th>
<th>Cognome</th>
<th>Specializzazione</th>
<th>Azioni</th>
</tr>
<?php while ($medico =
$result->fetch_assoc()) { ?>
<tr>
<form
action="gestione_medici.php" method="post">
<input type="hidden"
name="action" value="update">
<input
type="hidden" name="id" value="<?php echo
$medico['ID_Medico']; ?>">
<td><?php echo
$medico['ID_Medico']; ?></td>
<td><input
type="text" name="nome" value="<?php echo $medico['Nome'];
?>" required></td>
<td><input
type="text" name="cognome" value="<?php echo
$medico['Cognome']; ?>" required></td>
<td><input
type="text" name="specializzazione" value="<?php
echo $medico['Specializzazione']; ?>" required></td>
<td>
<input
type="submit" value="Aggiorna">
</form>
<form
action="gestione_medici.php" method="post"
style="display:inline;">
<input
type="hidden" name="action" value="delete">
<input
type="hidden" name="id" value="<?php echo
$medico['ID_Medico']; ?>">
<input
type="submit" value="Elimina">
</form>
</td>
</tr>
<?php } ?>
</table>
</body>
</html>
Gestione
Pazienti
- gestione_pazienti.php
Simile
alla gestione medici, questa pagina permette di gestire i pazienti.
```php
<?php
session_start();
require
'connessione_db.php';
//
Verifica se l'utente è loggato e ha il ruolo di amministratore
if
(!isset($_SESSION['utente']) || $_SESSION['ruolo'] !== 'amministratore') {
header("Location: login.php");
exit();
}
Gestione
delle azioni CRUD
if
($_SERVER['REQUEST_METHOD'] === 'POST') {
$action = $_POST['action'];
$id = $_POST['id'] ?? null;
if ($action == 'create') {
$nome = $_POST['nome'];
$cognome = $_POST['cognome'];
$data_nascita = $_POST['data_nascita'];
$query = "INSERT INTO Pazienti
(Nome, Cognome, Data_Nascita) VALUES (?, ?, ?)";
$stmt = $conn->prepare($query);
$stmt->bind_param('sss', $nome,
$cognome, $data_nascita);
$stmt->execute();
} elseif ($action == 'update' &&
$id) {
$nome = $_POST['nome'];
$cognome = $_POST['cognome'];
$data_nascita = $_POST['data_nascita'];
$query = "UPDATE Pazienti SET
Nome=?, Cognome=?, Data_Nascita=? WHERE ID_Paziente=?";
$stmt = $conn->prepare($query);
$stmt->bind_param('sssi', $nome,
$cognome, $data_nascita, $id);
$stmt->execute();
} elseif ($action == 'delete' &&
$id) {
$query = "DELETE FROM Pazienti
WHERE ID_Paziente=?";
$stmt = $conn->prepare($query);
$stmt->bind_param('i', $id);
$stmt->execute();
}
}
$result
= $conn->query("SELECT * FROM Pazienti");
?>
<!DOCTYPE
html>
<html
lang="it">
<head>
<meta charset="UTF-8">
<title>Gestione
Pazienti</title>
<link rel="stylesheet"
href="stile.css">
</head>
<body>
<h1>Gestione Pazienti</h1>
<form
action="gestione_pazienti.php" method="post">
<input type="hidden"
name="action" value="create">
<input type="text"
name="nome" placeholder="Nome" required>
<input type="text"
name="cognome" placeholder="Cognome" required>
<input type="date"
name="data_nascita" required>
<input type="submit"
value="Aggiungi Paziente">
</form>
<table>
<tr>
<th>ID</th>
<th>Nome</th>
<th>Cognome</th>
<th>Data di Nascita</th>
<th>Azioni</th>
</tr>
<?php while ($paziente =
$result->fetch_assoc()) { ?>
<tr>
<form
action="gestione_pazienti.php" method="post">
<input
type="hidden" name="action" value="update">
<input
type="hidden" name="id" value="<?php echo
$paziente['ID_Paziente']; ?>">
<td><?php echo
$paziente['ID_Paziente']; ?></td>
<td><input type="text"
name="nome" value="<?php echo $paziente['Nome']; ?>"
required></td>
<td><input
type="text" name="cognome" value="<?php echo
$paziente['Cognome']; ?>" required></td>
<td><input
type="date" name="data_nascita" value="<?php echo
$paziente['Data_Nascita']; ?>" required></td>
<td>
<input
type="submit" value="Aggiorna">
</form>
<form
action="gestione_pazienti.php" method="post"
style="display:inline;">
<input type="hidden"
name="action" value="delete">
<input
type="hidden" name="id" value="<?php echo
$paziente['ID_Paziente']; ?>">
<input
type="submit" value="Elimina">
</form>
</td>
</tr>
<?php } ?>
</table>
</body>
</html>
```
Gestione
Appuntamenti
- gestione_appuntamenti.php
Questa
pagina permette la gestione degli appuntamenti, inclusi medici e pazienti.
```php
<?php
session_start();
require
'connessione_db.php';
//
Verifica se l'utente è loggato e ha il ruolo di amministratore
if
(!isset($_SESSION['utente']) || $_SESSION['ruolo'] !== 'amministratore') {
header("Location: login.php");
exit();
}
//
Gestione delle azioni CRUD
if
($_SERVER['REQUEST_METHOD'] === 'POST') {
$action = $_POST['action'];
$id = $_POST['id'] ?? null;
if ($action == 'create') {
$id_paziente = $_POST['id_paziente'];
$id_medico = $_POST['id_medico'];
$data = $_POST['data'];
$ora = $_POST['ora'];
$descrizione = $_POST['descrizione'];
$query = "INSERT INTO Appuntamenti
(ID_Paziente, ID_Medico, Data, Ora, Descrizione) VALUES (?, ?, ?, ?, ?)";
$stmt = $conn->prepare($query);
$stmt->bind_param('iisss',
$id_paziente, $id_medico, $data, $ora, $descrizione);
$stmt->execute();
} elseif ($action == 'update' &&
$id) {
$id_paziente = $_POST['id_paziente'];
$id_medico = $_POST['id_medico'];
$data = $_POST['data'];
$ora = $_POST['ora'];
$descrizione = $_POST['descrizione'];
$query = "UPDATE Appuntamenti SET
ID_Paziente=?, ID_Medico=?, Data=?, Ora=?, Descrizione=? WHERE
ID_Appuntamento=?";
$stmt = $conn->prepare($query);
$stmt->bind_param('iisssi',
$id_paziente, $id_medico, $data, $ora, $descrizione, $id);
$stmt->execute();
} elseif ($action == 'delete' &&
$id) {
$query = "DELETE FROM Appuntamenti
WHERE ID_Appuntamento=?";
$stmt = $conn->prepare($query);
$stmt->bind_param('i', $id);
$stmt->execute();
}
}
$appuntamenti
= $conn->query("SELECT Appuntamenti.ID_Appuntamento, Pazienti.Nome as
NomePaziente, Medici.Nome as NomeMedico, Appuntamenti.Data, Appuntamenti.Ora,
Appuntamenti.Descrizione FROM Appuntamenti JOIN Pazienti ON
Appuntamenti.ID_Paziente = Pazienti.ID_Paziente JOIN Medici ON
Appuntamenti.ID_Medico = Medici.ID_Medico");
?>
<!DOCTYPE
html>
<html
lang="it">
<head>
<meta charset="UTF-8">
<title>Gestione Appuntamenti</title>
<link rel="stylesheet"
href="stile.css">
</head>
<body>
<h1>Gestione Appuntamenti</h1>
<form
action="gestione_appuntamenti.php" method="post">
<input type="hidden"
name="action" value="create">
<input type="number"
name="id_paziente" placeholder="ID Paziente" required>
<input type="number"
name="id_medico" placeholder="ID Medico" required>
<input type="date"
name="data" required>
<input type="time"
name="ora" required>
<input type="text"
name="descrizione" placeholder="Descrizione" required>
<input type="submit"
value="Aggiungi Appuntamento">
</form>
<table>
<tr>
<th>ID</th>
<th>Paziente</th>
<th>Medico</th>
<th>Data</th>
<th>Ora</th>
<th>Descrizione</th>
<th>Azioni</th>
</tr>
<?php while ($appuntamento =
$appuntamenti->fetch_assoc()) { ?>
<tr>
<form action="gestione_appuntamenti.php"
method="post">
<input
type="hidden" name="action" value="update">
<input
type="hidden" name="id" value="<?php echo
$appuntamento['ID_Appuntamento']; ?>">
<td><?php echo
$appuntamento['ID_Appuntamento']; ?></td>
<td><input
type="number" name="id_paziente" value="<?php echo
$appuntamento['ID_Paziente']; ?>" required></td>
<td><input
type="number" name="id_medico" value="<?php echo
$appuntamento['ID_Medico']; ?>" required></td>
<td><input
type="date" name="data" value="<?php echo
$appuntamento['Data']; ?>" required></td>
<td><input
type="time" name="ora" value="<?php echo
$appuntamento['Ora']; ?>" required></td>
<td><input
type="text" name="descrizione" value="<?php echo
$appuntamento['Descrizione']; ?>" required></td>
<td>
<input
type="submit" value="Aggiorna">
</form>
<form
action="gestione_appuntamenti.php" method="post"
style="display:inline;">
<input
type="hidden" name="action" value="delete">
<input
type="hidden" name="id" value="<?php echo
$appuntamento['ID_Appuntamento']; ?>">
<input
type="submit" value="Elimina">
</form>
</td>
</tr>
<?php } ?>
</table>
</body>
</html>
```
Gestione
Prestazioni
- gestione_prestazioni.php
Ultima
pagina per gestire le prestazioni disponibili nello studio.
```php
<?php
session_start();
require
'connessione_db.php';
//
Verifica se l'utente è loggato e ha il ruolo di amministratore
if
(!isset($_SESSION['utente']) || $_SESSION['ruolo'] !== 'amministratore') {
header("Location: login.php");
exit();
}
//
Gestione delle azioni CRUD
if
($_SERVER['REQUEST_METHOD'] === 'POST') {
$action = $_POST['action'];
$id = $_POST['id'] ?? null;
if ($action == 'create') {
$descrizione = $_POST['descrizione'];
$costo = $_POST['costo'];
$durata = $_POST['durata'];
$query = "INSERT INTO Prestazioni
(Descrizione, Costo, Durata) VALUES (?, ?, ?)";
$stmt = $conn->prepare($query);
$stmt->bind_param('sdi',
$descrizione, $costo, $durata);
$stmt->execute();
} elseif ($action == 'update' &&
$id) {
$descrizione = $_POST['descrizione'];
$costo = $_POST['costo'];
$durata = $_POST['durata'];
$query = "UPDATE Prestazioni SET
Descrizione=?, Costo=?, Durata=? WHERE ID_Prestazione=?";
$stmt = $conn->prepare($query);
$stmt->bind_param('sdii',
$descrizione, $costo, $durata, $id);
$stmt->execute();
} elseif ($action == 'delete' &&
$id) {
$query = "DELETE FROM Prestazioni
WHERE ID_Prestazione=?";
$stmt = $conn->prepare($query);
$stmt->bind_param('i', $id);
$stmt->execute();
}
}
$result
= $conn->query("SELECT * FROM Prestazioni");
?>
<!DOCTYPE html>
<html
lang="it">
<head>
<meta charset="UTF-8">
<title>Gestione
Prestazioni</title>
<link rel="stylesheet"
href="stile.css">
</head>
<body>
<h1>Gestione Prestazioni</h1>
<form
action="gestione_prestazioni.php" method="post">
<input type="hidden"
name="action" value="create">
<input type="text"
name="descrizione" placeholder="Descrizione" required>
<input type="text"
name="costo" placeholder="Costo" required>
<input type="number"
name="durata" placeholder="Durata (minuti)" required>
<input type="submit"
value="Aggiungi Prestazione">
</form>
<table>
<tr>
<th>ID</th>
<th>Descrizione</th>
<th>Costo</th>
<th>Durata</th>
<th>Azioni</th>
</tr>
<?php while ($prestazione =
$result->fetch_assoc()) { ?>
<tr>
<form
action="gestione_prestazioni.php" method="post">
<input
type="hidden" name="action" value="update">
<input
type="hidden" name="id" value="<?php echo
$prestazione['ID_Prestazione']; ?>">
<td><?php echo
$prestazione['ID_Prestazione']; ?></td>
<td><input
type="text" name="descrizione" value="<?php echo
$prestazione['Descrizione']; ?>" required></td>
<td><input
type="text" name="costo" value="<?php echo
$prestazione['Costo']; ?>" required></td>
<td><input
type="number" name="durata" value="<?php echo
$prestazione['Durata']; ?>" required></td>
<td>
<input type="submit"
value="Aggiorna">
</form>
<form
action="gestione_prestazioni.php" method="post"
style="display:inline;">
<input
type="hidden" name="action" value="delete">
<input type="hidden"
name="id" value="<?php echo $prestazione['ID_Prestazione'];
?>">
<input
type="submit" value="Elimina">
</form>
</td>
</tr>
<?php } ?>
</table>
</body>
</html>
Considerazioni
Finali step 3
1. Sicurezza:
Utilizza prepared statements per prevenire SQL injection e continui controlli
di sessione per l’accesso amministrativo.
2. Usabilità:
Assicurati che il sito sia facilmente navigabile e che tutte le pagine siano
collegate correttamente.
3. Design:
Personalizza il CSS (`stile.css`) per rendere il sito visivamente più
accattivante e funzionale.
Questa
semplice impalcatura può essere ampliata secondo necessità per adattarsi a
scenari di pratica reale, includendo miglioramenti di UI/UX e funzionalità
avanzate come la gestione delle agende dei medici o notifiche per gli utenti.
Step 4
La
normalizzazione del database è il processo di organizzazione delle tabelle e
dei campi in un database per ridurre la ridondanza dei dati e migliorare
l'integrità dei dati. Esaminiamo il nostro schema di database per garantire che
sia normalizzato almeno fino alla Terza Forma Normale (3NF), che è spesso lo
standard accettato nei sistemi informativi.
1.
Prima Forma Normale (1NF)
La 1NF
richiede che:
- Ogni
tabella contenga righe con dati atomici (nessun gruppo ripetuto o tabelle
annidate).
- Ogni
colonna contenga dati dello stesso tipo.
- Ogni
riga sia univocamente identificabile (spesso tramite chiave primaria).
Analisi per la 1NF:
- Tutte
le tabelle (`Medici`, `Pazienti`, `Appuntamenti`, `Prestazioni`) hanno colonne
con valori atomici.
- Ogni
colonna è prevista per un solo tipo di dati (e.g., `VARCHAR`, `DATE`).
- Ogni
tabella ha una chiave primaria (`ID_Medico`, `ID_Paziente`, `ID_Appuntamento`,
`ID_Prestazione`).
2.
Seconda Forma Normale (2NF)
La 2NF è
rispettata se:
- La
tabella è già in 1NF.
- Tutti
gli attributi non chiave dipendono completamente dalla chiave primaria (elimina
la dipendenza parziale).
Analisi
per la 2NF:
- In
`Medici`, `Pazienti`, `Prestazioni`, ogni attributo è pienamente dipendente dal
rispettivo ID.
-
`Appuntamenti` contiene `ID_Paziente` e `ID_Medico`, la dipendenza è completa
perché `Data`, `Ora` e `Descrizione` sono legate all'appuntamento identificato
dall'ID di quell'appuntamento (nessuna dipendenza parziale basata su un
sottoinsieme della chiave).
3.
Terza Forma Normale (3NF)
La 3NF è
rispettata se:
- È in
2NF.
- Nessun
attributo non chiave dipende transitivamente dalla chiave primaria.
Analisi
per la 3NF:
-
Nessuna delle tabelle contiene attributi che dipendono transitivamente dalla
chiave primaria. Ogni attributo non chiave è legato solo alla chiave primaria e
non esistono combinazioni indirette di dipendenze tra colonne.
Risultati
della normalizzazione
Il
database presentato è normalizzato fino alla Terza Forma Normale (3NF):
- Medici:
Tutti i campi (Nome, Cognome, Specializzazione) dipendono solo dalla chiave
primaria `ID_Medico`.
- Pazienti:
Nome, Cognome, Data_Nascita dipendono solo da `ID_Paziente`.
- Appuntamenti:
`ID_Paziente`, `Data`, `Ora`, `Descrizione`, `ID_Medico` sono attribuiti
causali legati alla singola entità dell'appuntamento.
- Prestazioni:
Descrizione, Costo, Durata sono completamente dipendenti dall'unica chiave `ID_Prestazione`.
Procedura
di Normalizzazione Seguita:
1. Convertire
dati in tabelle: Definire formalmente le tabelle e inserire ogni tipo di dato
in colonne corrette.
2. Assicurare
atomicità dei dati: Controllare che non ci siano campi che potrebbero essere
suddivisi.
3. Identificare
chiavi primarie: Assicurarsi che ogni riga sia univocamente identificabile
tramite una chiave primaria.
4. Eliminare
dipendenze parziali: Verificare che gli attributi non siano parzialmente
dipendenti da alcun sottoinsieme della chiave in chiavi composte.
5. Eliminare
dipendenze transitive: Garantire che nessuna colonna non chiave dipenda
indirettamente dalla chiave primaria.
Questo
approccio fornisce integrità dei dati all'interno del database, minimizzando la
ridondanza e prevenendo anomalie di inserimento, aggiornamento e cancellazione.
Lezione: Regole di normalizzazione di un database (30 nov 2017)
http://paololatella.blogspot.it/2017/02/regole-di-normalizzazione-di-un-data.html
Soluzione proposta dal Corriere della Sera (con errori individuati dal prof. Paolo Latella nel modello logico concettuale):
http://www.corriere.it/Speciali/Cronache/2007/Maturita/Istituti%20tecnici/CorrezioneEsameInformatica.pdf
Commenti
Posta un commento