Σε αυτό το παράδειγμα θα δούμε πως θα ανεβάσουμε ένα post, που θα έχει έναν
τίτλο, μιά εικόνα, και το άρθρο.
Θα επικυρώσουμε τα δεδομένα από την φόρμα πρώτα
με javascript για να μην υπάρχει η καθηστέρηση του server, και μετα με php για να
κάνουμε την εφαρμογή ασφαλη, και θα τα εισάγουμε σε μια mysql βάση.
Θα χρειαστούμε τρία αρχεία.
- Το index.php για την html φόρμα
- Ένα script.php για τόν κώδικα php
- Καί ένα script.js για την javascript
index.php
<body>
<!-- Πρέπει να συμπεριλάβουμε το php αρχείο για να τρέχει ο κώδικας κάθε
φορά που φορτώνει η σελίδα. -->
<?php require 'script.php'; ?>
<!-- Είναι σημαντικό σε κάθε φόρμα που έχουμε file upload να έχουμε το attribute (ιδιότητα)
enctype="multipart/form-data" αλλιώς το αρχείο δεν θα ανέβει. -->
<form action="" method="post" enctype="multipart/form-data">
<h2>Μεταφόρτωση άρθρου με φωτό</h2>
<!-- Θέλουμε ένα πεδίο για να εισάγουμε τον τίτλο -->
<fieldset>
<legend>Δώσε έναν τίτλο στο άρθρο</legend>
<!-- Όπως βλέπετε στο value του τίτλου έχουμε μια php μεταβλητή η οποία
κρατάει ότι έχουμε πληκτρολογήσει στο πεδίο. Αυτό το κάνουμε γιατί σε περίπτωση σφάλματος
θέλουμε το πεδίο να κρατήσει την τιμή που πληκτρολογήσαμε -->
<input type="text" name="title" value="<?php echo @$title; ?>">
<!-- Θέλουμε να τυπώνουνε και όποια σφάλματα προκύψουν κατά
την επικύρωση μέσα σε ένα p tag, εδώ η μεταβλητή @$title_error θα παίρνει
την τιμή της κάθε φορά που τρέχει ο php κώδικας -->
<p class="error"><?php echo @$title_error; ?></p>
</fieldset>
<fieldset>
<legend>Εισαγωγή άρθρου</legend>
<!-- Για το πεδίο του άρθρου και του σφάλματος υσχύει ότι και για το πεδίο
του τίτλου παραπάνω. -->
<textarea name="article"><?php echo @$article; ?></textarea>
<p class="error"><?php echo @$article_error; ?></p>
</fieldset>
<fieldset>
<legend>Επέλεξε φωτό για το άρθρο σου</legend>
<!-- Έχουμε το παρακάτω div και μέσα ένα img tag για να εμφανίζουμε την επιλεγμένη εικόνα -->
<div class="image-placeholder">
<img id="uploadPreview" src="" width="100%">
</div>
<!-- Κάθε φορά που θα επιλέγουμε μια εικόνα θα τρέχει η previewImage() και θα
μας την εμφανίζει στο παραπάνω img -->
<input type="file" name="image" id="uploadImage" onchange="previewImage();" >
<p class="error file-error"><?php echo @$file_error; ?></p>
</fieldset>
<!-- Το upload button -->
<input type="submit" name="upload" value="Upload">
<!-- H $success θα τυπώνει το μύνημα επιτυχους upload -->
<p class="success"><?php echo @$success; ?></p>
<!-- Και η $error το όποιο σφαλμα προκύψει που δεν έχει σχέση με την
επικύρωση των πεδίων -->
<p class="error"><?php echo @$error; ?></p>
</form>
<!-- Και πρέπει να συμπεριλάβουμε το javascript αρχείο -->
<script src="script.js"></script>
script.js
// Θα ξεκινήσουμε να γράψουμε την συνάρτηση previewImage() που έχουμε
// δηλώσει στην html φόρμα να τρέχει κάθε φορά που θα επιλέγουμε μια εικόνα
function previewImage() {
// Χρειαζόμαστε μία αναφορά στο p.file-error για να προβάλλουμε τα όποια σφάλματα μας επιστρέφει
// η συνάρτηση
let error = document.querySelector('.file-error');
// Καθαρίζουμε το error html στοιχείο σε περίπτωση που είχαμε κάποιο σφάλμα.
error.innerHTML = '';
// Στοχέυουμε το input file στην html φόρμα, και με την files[0], πέρνουμε
// τις πληροφορίες που θέλουμε για το αρχείο που επιλέξαμε, όπως το όνομα, το μέγεθος,
// τον τύπο(jpg, png, κτλ).
// Η files μας έπιστρέφει έναν πίνακα, οπότε εμείς στοχεύουμε την πρώτη τιμή(value)
// στον πίνακα με το κλειδί(key) [0].
let file = document.getElementById("uploadImage").files[0];
// Καλούμε το αντικείμενο FileReader()
let reader = new FileReader();
// Ή μέθοδος readAsDataURL() του αντικειμένου(object) FileReader(), διαβάζει τον
// δυαδικό κώδικα του αρχείου και τον επιστρέφει ως data URL. Για να διαβαστεί από
// τον browser.
reader.readAsDataURL(file);
// Όταν διαβάσει(onload) ο browser το αρχείο, χωρίς σφάλματα ...
reader.onload = function (event) {
// ... θα στοχεύσουμε το html img tag για να εμφανίσουμε την εικόνα μας.
return document.getElementById("uploadPreview").src = event.target.result;
};
// Αν προκύψει σφάλμα από την μεριά του browser και δεν διαβαστεί σωστά το αρχείο ...
reader.onerror = function(event){
// ... θα επιστρέψουμε ένα μήνυμα στην html φόρμα μας.
return error.innerHTML = 'Σφάλμα ανάγνωσης του αρχείου';
}
// Επικύρωση(validation) του αρχείου.
// Θα ελέγξουμε το μέγεθος(size) και τον τυπο(type).
let maxSize = 1 * 1024 * 1024; // Ανώτατο επιτρεπτό όριο 1 MB
// Μέσα στον πίνακα validTypes εχουμε τους έγκυρους τύπους των αρχείων.
let validTypes = ["image/jpg", "image/jpeg", "image/png", "image/gif"];
// Ελέγχουμε το μέγεθος του αρχείου.
if(file.size > maxSize){
// Μη αποδεκτό μέγεθος.
error.innerHTML = `Το αρχείο υπερβαίνει το ${maxSize / 1024 / 1024}MB`;
// απενεργοποιούμε το submit button.
document.querySelector('input[type=submit]').disabled = true;
return false;
}else{
// ενεργοποιούμε το submit button
document.querySelector('input[type=submit]').disabled = false;
}
// Ελέγχουμε τον τύπο του αρχείου.
// Η arr.includes() θα τρέξει όλα τα στοιχεία του πίνακα validTypes[]
// και θα συγκρίνει τον τύπο του αρχείου που επιλέξαμε με τους τύπους
// που έχουμε δηλώσει μέσα στον πίνακα.
if(!validTypes.includes(file.type)){
// Μύνημα σφάλματος.
error.innerHTML = "Αποδεκτά φορμάτ [.jpg .jpeg .png .gif]";
// απενεργοποιούμε το submit button.
document.querySelector('input[type=submit]').disabled = true;
return false;
}else{
// το αρχείο είναι εγκυρο ...
// ενεργοποιούμε το submit button
document.querySelector('input[type=submit]').disabled = false;
}
}
/*Πρίν η φόρμα υποβληθεί θα ελέγξουμε τα πεδία με την javascript. Αυτό το κάνουμε για να μην έχουμε
καθυστέρηση κατά την επικύρωση των πεδίων, γιατί η javascript τρέχει στον browser έτσι εαν υπάρχει
κάποιο σφάλμα θα εμφανιστεί στήν οθόνη σχεδόν ακαριαία, και ένας λόγος παραπάνω είναι ότι έχουμε
και αρχείο να ανεβάσουμε, που για να μας στείλει ο server τις απαντήσεις θα πρέπει να ανέβει και
το αρχείο, και αυτό είναι χρονοβόρο ειδικά αν το αρχείο έιναι αρκετά ΜΒ σε μέγεθος.*/
// Με τον addEventListener() θα πιάνουμε την φόρμα κάθε φορά που πατάμε το submit button, και θα
// έχουμε πρόσβαση στα πεδία.
document.querySelector('form').addEventListener('submit', function(e){
// Θα ελέγξουμε το πεδίο title αν είναι κενό, Αν ναι θα τυπώσουμε το σφάλμα στην οθόνη, και
// θα αποτρέψουμε την φόρμα να υποβληθεί με την preventDefault(). Kai θα σταματήσουμε την
// συνάρτηση με το return false.
// To ίδιο ισχύει και για το πεδίο article
if(e.target.title.value == ''){
document.querySelector('#title-error').innerHTML = 'JS > Πρέπει να δώσεις έναν τίτλο στο άρθρο σου';
e.preventDefault();
return false;
}else{
document.querySelector('#title-error').innerHTML = '';
}
if(e.target.article.value == ''){
document.querySelector('#article-error').innerHTML = 'JS > Πρέπει να εισάγεις το άρθρο σου';
e.preventDefault();
return false;
}else{
document.querySelector('#article-error').innerHTML = '';
}
// Εδώ θα ελέγξουμε εαν έχει επιλεγεί κάποιο αρχείο εαν όχι θα τυπώσουμε
// και εδώ το σφάλμα στην οθόνη και θα αποτρέψουμε την φόρμα να υποβληθεί
// τερματίζοντας και την συνάρτηση.
// Για να δούμε αν έχει επιλεγεί κάποιο αρχείο θα τσεκάρουμε την files
// πάνω στο choose file button.
// Η files μας επιστρέφει μια συλλογή εαν το μήκος της είναι 0 αυτό
// σημαίνει ότι δεν έχει επιλεγεί κανένα αρχείο.
if(document.getElementById("uploadImage").files.length == 0){
document.querySelector('#file-error').innerHTML = 'JS > Πρέπει να επιλέξεις μια φωτό';
e.preventDefault();
return false;
}else{
document.querySelector('#file-error').innerHTML = '';
}
});
Για περισότερες πληροφορίες πάνω στίς συναρτήσεις που χρησιμοποιήσαμε θα βρείτε στα παρακάτω links.
script.php
// Πρώτα απ όλα πρέπει να ελέγξουμε με την isset() αν η φόρμα έχει υποβληθεί.
if(isset($_POST['upload'])){
// εφόσον η φόρμα έχει υποβληθεί θα ελέγξουμε με την empty() αν το πεδίο title είναι κενό.
if(!empty($_POST['title'])){
/* άφού έχουμε τιμή στο πεδίο title πρέπει να ελέγξουμε και να αφαιρέσουμε τοιχόν HTML tags
που θα μπορούσαν να μας κάνουν ζημιά. Αυτό θα γίνει με την filter_var(), και την
παράμετρο FILTER_SANITIZE_STRING.*/
$title = filter_var($_POST['title'], FILTER_SANITIZE_STRING);
/* μετά απο το πεδίο title θα περάσουμε στο πεδίο article, θα ελέγξουμε και αυτό
με την empty(), και αν δεν είναι κενό θα το περάσουμε και αυτό απο την filter_var()*/
if(!empty($_POST['article'])){
$article = filter_var($_POST['article'], FILTER_SANITIZE_STRING);
/* έχουμε τελειώσει με τα δύο πεδία και θα πιαστούμε με την image.
Η image μας έρχεται σε array με την $_FILES.
Θα ελέγξουμε με την isset() αν υπάρχουν δεδομένα, και με την UPLOAD_ERR_OK που
είναι μια από τις πολλές σταθερές που έχει η ['image']['error'], θα τσεκάρουμε
αν το upload έγινε χωρίς σφάλμα.*/
if(isset($_FILES['image']) && $_FILES['image']['error'] == UPLOAD_ERR_OK){
/* το αρχείο ανέβηκε χωρίς σφάλματα και τώρα θα πάρουμε τις τιμές και θα τις
ορίσουμε σε μεταβλητές για να μπορέσουμε, να τις διαχειριστούμε πιο άνετα */
/* για την filter_var() έχουμε πεί παραπάνω σε τι χρησιμεύει.
η trim() αφαιρεί τους κενούς χαρακτήρες(white space) δεξια και αριστερά απο ένα string */
$file_name = filter_var(trim($_FILES['image']['name']), FILTER_SANITIZE_STRING);
$file_type = $_FILES['image']['type'];
$file_temp = $_FILES['image']['tmp_name'];
$file_size = $_FILES['image']['size'];
$upload_error = $_FILES['image']['error'];
/*Το επόμενο βήμα είναι να ελέγξουμε τον τύπο(το format) του αρχείου.
Θα γράψουμε έναν πίνακα με τους τύπους των αρχείων που θέλουμε να
επιτρέψουμε να περάσουνε τον έλεγχο*/
$valid_types = array("image/jpg", "image/jpeg", "image/png", "image/gif");
// τώρα θα ελέγξουμε εάν ο τύπος που έχει η $file_type είναι μέσα στον πίνακα
if(in_array($file_type, $valid_types)){
/*εφόσον ο τύπος είναι έγκυρος θα ελέγξουμε το μέγεθος του αρχείου
και θα καθορίσουμε το όριο σε 2ΜΒ*/
$max_file_size = 2 * 1024 * 1024;
// εαν η $file_size είναι μικρότερη η ίση με το όριο που έχουμε θέσει ...
if($file_size <= $max_file_size){
/*... τότε προχωράμε με την μετακίνηση του αρχείου στον φάκελο που
θέλουμε*/
$upload_folder = "uploads/";
// θα ελέγξουμε αν το αρχείο υπάρχει ήδη στον φάκελο uploads
if(!file_exists($upload_folder.$file_name)){
/*τώρα πρέπει να μετακινήσουμε το αρχείο από τον προσωρινό φάκελο που
το έχει αποθηκεύσει η php στον φάκελο μας*/
if(move_uploaded_file($file_temp, $upload_folder.$file_name)){
/*το αρχείο έχει μετακινηθεί στον φάκελο μας και επόμενο βήμα είναι
να συνδεθούμε με την βάση δεδομένων mysql*/
// η σύνδεση θα γίνει με την mysqli_connect('host','username','password','db name')
$conn = mysqli_connect('host','username','password','db name');
// τσεκάρουμε αν η σύνδεση είναι επιτυχής
if(!$conn){
/*εαν η σύνδεση δεν είναι εφικτή θα τερματίσουμε το script και θα
τυπώσουμε το σφάλμα με την mysqli_connect_error(); */
die('Δεν υπάρχει σύνδεση με την mysql - '. mysqli_connect_error());
}else{
// στην βάση έχουμε έναν πίνακα articles με 3 πεδία (title, article, image).
$sql = "INSERT INTO articles(title,article,image) VALUES('$title', '$article', '$file_name')";
// θα εκτελέσουμε την mysqli_query() και θα εισάγουμε τις τιμές στον πίνακα articles
if(mysqli_query($conn, $sql)){
// εαν η εγγραφή είναι επιτυχής θα τυπώσουμε το μήνυμα
$success = "Tο άρθρο ανέβηκε επιτυχώς";
// θα καθαρίσουμε τα πεδία title και article στην φόρμα
$title = "";
$article = "";
// και θα κλήσουμε την σύνδεση
mysqli_close($conn);
}else{
// εαν η εγγραφή δεν είναι επιτυχής θα τυπώσουμε το μήνυμα σφάλματος.
$error = "Παρουσιάστηκε σφάλμα στήν βάση - ". mysqli_error($conn);
// και θα διαγράψουμε το αρχείο απο τον φάκελο.
if(!unlink($upload_folder.$file_name)){
$error = "H φωτό δεν διαγράφηκε από την βάση";
}
}
}
}else{
// Μήνυμα ανεπιτυχείς μετακίνησης του αρχείου.
$file_error = "Παρουσιάστηκε σφάλμα στον server";
}
}else{
$file_error = "Το αρχείο υπάρχει ίδη στον server";
}
}else{
$file_error = "To αρχείο είναι μεγαλύτερο απο 2MB";
}
}else{
$file_error = "Αποδεκτά φορμάτ [.jpg .jpeg .png .igif]";
}
}else{
$file_error = 'Πρέπει να επιλέξεις μια φωτό';
}
}else{
$article_error = 'Πρέπει να εισάγεις το άρθρο σου';
}
}else{
$title_error = 'Πρέπει να δώσεις έναν τίτλο στο άρθρο σου';
}
}
Για περισότερες πληροφορίες πάνω στίς συναρτήσεις που χρησιμοποιήσαμε θα βρείτε στα παρακάτω links.
Σχόλια και ερωτήσεις μέσω facebook