L'esperienza utente può essere notevolmente migliorata su una funzione di caricamento delle immagini se consentiamo all'utente di visualizzare in anteprima l'immagine che ha selezionato prima di caricarla effettivamente sul server facendo clic sul pulsante di caricamento.
In questo tutorial creeremo un modulo che accetta due input:l'immagine del profilo dell'utente (immagine) e la sua biografia (testo). Quando l'utente compila il modulo e fa clic sul pulsante di caricamento, utilizzeremo il nostro script PHP per acquisire i valori del modulo (l'immagine e la biografia) e salvare l'immagine nella cartella del nostro progetto chiamata immagini. Una volta salvata l'immagine nella cartella del progetto, memorizzeremo un record nel database contenente il nome dell'immagine e la biografia dell'utente.
Dopo aver salvato queste informazioni, creeremo un'altra pagina che interroga i profili utente dal database e li visualizza sulla pagina con la biografia di ciascun utente rispetto alla sua immagine del profilo.
Quindi iniziamo con l'implementazione.
Crea una cartella di progetto e chiamala image-preview-upload. All'interno di questa cartella, crea un file chiamato form.php e una cartella chiamata images per memorizzare le immagini.
form.php:
<?php include_once('processForm.php') ?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Image Preview and Upload PHP</title>
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0/css/bootstrap.min.css" />
<link rel="stylesheet" href="main.css">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-4 offset-md-4 form-div">
<a href="profiles.php">View all profiles</a>
<form action="form.php" method="post" enctype="multipart/form-data">
<h2 class="text-center mb-3 mt-3">Update profile</h2>
<?php if (!empty($msg)): ?>
<div class="alert <?php echo $msg_class ?>" role="alert">
<?php echo $msg; ?>
</div>
<?php endif; ?>
<div class="form-group text-center" style="position: relative;" >
<span class="img-div">
<div class="text-center img-placeholder" onClick="triggerClick()">
<h4>Update image</h4>
</div>
<img src="images/avatar.jpg" onClick="triggerClick()" id="profileDisplay">
</span>
<input type="file" name="profileImage" onChange="displayImage(this)" id="profileImage" class="form-control" style="display: none;">
<label>Profile Image</label>
</div>
<div class="form-group">
<label>Bio</label>
<textarea name="bio" class="form-control"></textarea>
</div>
<div class="form-group">
<button type="submit" name="save_profile" class="btn btn-primary btn-block">Save User</button>
</div>
</form>
</div>
</div>
</div>
</body>
</html>
<script src="scripts.js"></script>
Prima di dire qualcosa sul modulo, creiamo innanzitutto un file di stile denominato main.css per il modulo nella cartella principale del nostro progetto.
main.css:
.form-div { margin-top: 100px; border: 1px solid #e0e0e0; }
#profileDisplay { display: block; height: 210px; width: 60%; margin: 0px auto; border-radius: 50%; }
.img-placeholder {
width: 60%;
color: white;
height: 100%;
background: black;
opacity: .7;
height: 210px;
border-radius: 50%;
z-index: 2;
position: absolute;
left: 50%;
transform: translateX(-50%);
display: none;
}
.img-placeholder h4 {
margin-top: 40%;
color: white;
}
.img-div:hover .img-placeholder {
display: block;
cursor: pointer;
}
Nella prima riga del nostro file form.php, stiamo includendo un file che contiene il nostro script PHP incaricato di ricevere i valori del modulo e di elaborarli (ovvero salvare l'immagine nella cartella immagini e creare un record corrispondente nella tabella utenti nel database).
Se dai un'occhiata al modulo, vedrai che stiamo impostando il valore della visualizzazione della proprietà CSS su nessuno; Lo stiamo facendo perché non vogliamo visualizzare l'elemento di input HTML predefinito per il caricamento dei file. Invece, creeremo un elemento diverso e lo modelleremo come vogliamo e poi quando l'utente fa clic sul nostro elemento, useremo JavaScript sotto il cofano per attivare l'elemento di input del file HTML che ci è nascosto.
Ora aggiungiamo gli script responsabili dell'attivazione dell'elemento di input del file e quindi anche della visualizzazione dell'immagine per l'anteprima.
Crea un file chiamato scripts.js nella radice della tua applicazione e aggiungi questo codice:
script.js:
function triggerClick(e) {
document.querySelector('#profileImage').click();
}
function displayImage(e) {
if (e.files[0]) {
var reader = new FileReader();
reader.onload = function(e){
document.querySelector('#profileDisplay').setAttribute('src', e.target.result);
}
reader.readAsDataURL(e.files[0]);
}
}
Ora, quando l'utente fa clic sull'area rotonda dell'immagine, la funzione triggerClick() attiverà un evento clic sull'elemento di input del file nascosto. Quando l'utente seleziona un'immagine, viene attivato un evento onChange nel campo di input del file e possiamo utilizzare la classe FileReader() di JavaScript per visualizzare temporaneamente l'immagine per l'anteprima.
Quando l'utente fa clic sul pulsante "Salva utente", il modulo di input verrà inviato alla stessa pagina. Quindi, nella stessa pagina form.php, stiamo includendo un file processForm.php che contiene il codice per elaborare il nostro modulo.
Quindi nella cartella principale del progetto crea un file chiamato processForm.php;
processForm.php:
<?php
$msg = "";
$msg_class = "";
$conn = mysqli_connect("localhost", "root", "", "img-upload");
if (isset($_POST['save_profile'])) {
// for the database
$bio = stripslashes($_POST['bio']);
$profileImageName = time() . '-' . $_FILES["profileImage"]["name"];
// For image upload
$target_dir = "images/";
$target_file = $target_dir . basename($profileImageName);
// VALIDATION
// validate image size. Size is calculated in Bytes
if($_FILES['profileImage']['size'] > 200000) {
$msg = "Image size should not be greated than 200Kb";
$msg_class = "alert-danger";
}
// check if file exists
if(file_exists($target_file)) {
$msg = "File already exists";
$msg_class = "alert-danger";
}
// Upload image only if no errors
if (empty($error)) {
if(move_uploaded_file($_FILES["profileImage"]["tmp_name"], $target_file)) {
$sql = "INSERT INTO users SET profile_image='$profileImageName', bio='$bio'";
if(mysqli_query($conn, $sql)){
$msg = "Image uploaded and saved in the Database";
$msg_class = "alert-success";
} else {
$msg = "There was an error in the database";
$msg_class = "alert-danger";
}
} else {
$error = "There was an erro uploading the file";
$msg = "alert-danger";
}
}
}
?>
Questo codice riceve i valori di input inviati dal modulo. Questo input è costituito dall'immagine dell'utente e dalla biografia. Sul server, possiamo accedere al file immagine e a tutte le informazioni relative all'immagine come il nome dell'immagine, la dimensione, l'estensione e così via nella variabile super globale $_FILE[] mentre altre informazioni come il testo si trovano nella $_POST[] variabile superglobale.
Utilizzando le informazioni nella variabile super globale $_FILE[], possiamo convalidare l'immagine. Ad esempio, il nostro codice sorgente può accettare solo immagini di dimensioni inferiori a 200kb. Ovviamente puoi sempre modificare questo valore se vuoi.
Notate nel codice sopra che ci stiamo connettendo a un database chiamato img-upload. Crea questo database e crea una tabella chiamata utenti con i seguenti campi:
tabella utenti:
CREATE TABLE `users` (
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
`profile_image` varchar(255) NOT NULL,
`bio` text NOT NULL
)
Ora apri il modulo sul tuo browser e inserisci alcune informazioni. Se tutto è andato bene, la tua immagine verrà caricata nella cartella delle immagini nel tuo progetto e un record corrispondente salvato nel database.
Visualizzazione dell'immagine dal database
Una volta che la nostra immagine è nel database, visualizzarla è un gioco da ragazzi. Crea un file nella cartella principale e denominalo profiles.php.
profili.php:
<?php
$conn = mysqli_connect("localhost", "root", "", "img-upload");
$results = mysqli_query($conn, "SELECT * FROM users");
$users = mysqli_fetch_all($results, MYSQLI_ASSOC);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Image Preview and Upload</title>
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0/css/bootstrap.min.css" />
</head>
<body>
<div class="container">
<div class="row">
<div class="col-4 offset-md-4" style="margin-top: 30px;">
<a href="form.php" class="btn btn-success">New profile</a>
<br>
<br>
<table class="table table-bordered">
<thead>
<th>Image</th>
<th>Bio</th>
</thead>
<tbody>
<?php foreach ($users as $user): ?>
<tr>
<td> <img src="<?php echo 'images/' . $user['profile_image'] ?>" width="90" height="90" alt=""> </td>
<td> <?php echo $user['bio']; ?> </td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>
Semplice! Questo file si collega al database, interroga tutte le informazioni sul profilo dalla tabella degli utenti ed elenca i profili utente in un formato tabellare visualizzando l'immagine del profilo di ciascun utente rispetto alla loro biografia. Un'immagine viene visualizzata semplicemente utilizzando il nome dell'immagine dal database e puntando alla cartella delle immagini in cui risiede l'immagine.
Conclusione
Spero che questo breve tutorial ti sia piaciuto. Se hai qualche domanda, lasciala nei commenti qui sotto.
Ricordati di supportare condividendo.
Divertiti.