Forum und email

Χειρίζοντας upload αρχείων

Table of Contents

Upload με την POST μέθοδο

Η PHP είναι ικανή για να λαμβάνει upload αρχείων από οποιοδήποτε RFC-1867 συμβατό browser (αυτό συμπεριλαμβάνει τους Netscape Navigator 3 ή μεγαλύτερο, Microsoft Internet Explorer 3 με ένα patch από τη Microsoft, ή μεγαλύτερο χωρίς κάποιο patch). Αυτό το χαρακτηριστικό επιτρέπει στους ανθρώπους να κάνουν upload τόσο κειμένου, όσο και binary αρχεία. Με τις συναρτήσεις αναγνώρισης και χειρισμού αρχείων της PHP, έχετε πλήρη έλεγχο στο ποιός επιτρέπεται να κάνει upload και τι θα γίνει με το αρχείο από τη στιγμή που έχει γίνει upload και μετά.

Note: Σχετικές Σημειώσεις Ρυθμίσεων Δείτε επίσης τα file_uploads, upload_max_filesize, upload_tmp_dir, και post_max_size directives στο php.ini

Σημειώστε πως η PHP επίσης υποστηρίζει upload αρχείων με την PUT μέθοδο όπως χρησιμοποιούνται αυτά από τους Netscape Composer και W3C's Amaya clients. Δείτε το κεφάλαιο Υποστήριξη της PUT Μεθόδου για περισσότερες πληροφορίες.

Μια οθόνη για upload αρχείου μπορεί να φτιαχτεί δημιουργώντας μια ειδική φόρμα η οποία μοιάζει κάπως έτσι:

Example#1 Φόρμα για Upload Αρχείου

<form enctype="multipart/form-data" action="_URL_" method="post">
<input type="hidden" name="MAX_FILE_SIZE" value="30000">
Send this file: <input name="userfile" type="file">
<input type="submit" value="Send File">
</form>
Το _URL_ πρέπει να δείχνει σε κάποιο PHP αρχείο. Το MAX_FILE_SIZE κρυφό πεδίο (hidden) πρέπει να προηγείται του input πεδίου για το αρχείο και η τιμή του είναι το μέγιστο μέγεθος αρχείου που επιτρέπεται. Η τιμή είναι σε byte.
Warning

Το MAX_FILE_SIZE είναι ενημερωτικό για τον browser. Είναι εύκολο να παρακαμφθεί αυτή η μέγιστη τιμή. Έτσι μην στηρίζεστε ότι ο browser υπακούει την επιθυμία σας! Οι PHP-ρυθμίσεις όμως, για το μέγιστο μέγεθος (maximum-size), δεν μπορούν να ξεγελαστούν. Καλύτερα να προσθέτετε το MAX_FILE_SIZE ούτως ή άλλως γιατί προστατεύει τους χρήστες από τον κόπο να περιμένουν για ένα μεγάλο αρχείο να μεταφερθεί μόνο και μόνο για να μάθουν πως ήταν πολύ μεγάλο μετά.

Οι μεταβλητές που ορίζονται για αρχεία που έχουν γίνει upload αλλάζουν ανάλογα με την έκδοση της PHP και τις ρυθμίσεις. Η autoglobal μεταβλητή $_FILES υπάρχει από την PHP 4.1.0. Το $HTTP_POST_FILES array υπάρχει από την PHP 4.0.0. Αυτοί οι πίνακες θα περιέχουν όλες τις πληροφορίες των αρχείων που έχουν γίνει upload. Η χρήση της $_FILES προτιμάται. Αν το PHP directive register_globals είναι ενεργοποιημένο, τα σχετικά ονόματα των μεταβλητών θα υπάρχουν επίσης. Το register_globals έχει ως προεπιλογή να είναι απενεργοποιημένο από την PHP » 4.2.0.

Τα περιεχόμενα της $_FILES από το παράδειγμα μας είναι ως ακολούθως. Σημειώστε πως αυτό υποθέτει τη χρήση του ονόματος αρχείου να είναι userfile, όπως χρησιμοποιείται στο παράδειγμα παραπάνω.

$_FILES['userfile']['name']

Το αρχικό όνομα του αρχείου στο μηχάνημα του client.

$_FILES['userfile']['type']

Το mime type του αρχείου, αν ο browser έχει δώσει αυτή τη πληροφορία. Ένα παράδειγμα θα ήταν "image/gif".

$_FILES['userfile']['size']

Το μέγεθος, σε byte, του αρχείου που έχει γίνει upload.

$_FILES['userfile']['tmp_name']

Το προσωρινό όνομα του αρχείου στο οποίο έχει αποθηκευτεί το αρχείο που έχει γίνει upload στον server.

$_FILES['userfile']['error']

Ο κωδικός σφάλματος που σχετίζεται με αυτό το upload αρχείου. Το ['error'] έχει προστεθεί στην PHP 4.2.0

Note: Στις εκδόσεις της PHP πριν την 4.1.0 αυτό έχει όνομα $HTTP_POST_FILES και δεν είναι μια autoglobal μεταβλητή όπως είναι η $_FILES. Η PHP 3 δεν έχει υποστήριξη για την $HTTP_POST_FILES.

Όταν το register_globals είναι ενεργοποιημένο στο php.ini, επιπλέον μεταβλητές είναι διαθέσιμες. Για παράδειγμα, η $userfile_name θα ισούται με την $_FILES['userfile']['name'], η $userfile_type θα ισούται με την $_FILES['userfile']['type'], κλπ. Έχετε υπ' όψιν σας πως από την PHP 4.2.0, το register_globals είναι προεπιλεγμένα απενεργοποιημένο. Προτιμάται να μην στηρίζεστε σε αυτό το directive.

Τα αρχεία προεπιλεγμένα θα αποθηκεύονται στον προσωρινό κατάλογο του server, εκτός και αν κάποια άλλη τοποθεσία δοθεί με το upload_tmp_dir directive στο php.ini. Ο προεπιλεγμένος κατάλογος μπορεί να αλλαχθεί ορίζοντας την μεταβλητή περιβάλλοντος TMPDIR στο περιβάλλον στο οποίο εκτελείται η PHP. Ορίζοντας το με την putenv() μέσα από ένα PHP script δεν θα δουλέψει. Αυτή η μεταβλητή περιβάλλοντος μπορεί επιπλέον να χρησιμοποιηθεί για να σιγουρευτείτε πως και άλλες ενέργειες επιτελούνται στα αρχεία που έχουν γίνει upload, επιπλεόν.

Example#2 Επικύρωση upload αρχείων

Δείτε επίσης τις καταχωρήσεις συναρτήσεων για τις is_uploaded_file() και move_uploaded_file() για περισσότερες πληροφορίες. Το παρακάτω παράδειγμα θα επεξεργαστεί ένα upload αρχείου που προέρχεται από μια φόρμα.

<?php
// In PHP earlier then 4.1.0, $HTTP_POST_FILES should be used instead of $_FILES.
// In PHP earlier then 4.0.3, use copy() and is_uploaded_file() instead of move_uploaded_file

$uploaddir '/var/www/uploads/';

print 
"<pre>";
if (
move_uploaded_file($_FILES['userfile']['tmp_name'], $uploaddir $_FILES['userfile']['name'])) {
    print 
"File is valid, and was successfully uploaded.  Here's some more debugging info:\n";
    
print_r($_FILES);
} else {
    print 
"Possible file upload attack!  Here's some debugging info:\n";
    
print_r($_FILES);
}

?>

Το PHP script το οποίο λαμβάνει το αρχείο πρέπει να εκτελέσει οποιαδήποτε λογική είναι απαραίτητη για να αποφασίσει τι θα γίνει με τα αρχεία. Μπορείτε για παράδειγμα να χρησιμοποιήσετε τηνχρησιμοποι $_FILES['userfile']['size'] μεταβλητή για να πετάξετε οποιαδήποτε αρχεία είναι είτε πολύ μικρά είτε πολύ μεγάλα. Μπορείτε να χρησιμοποιήσετε την $_FILES['userfile']['type'] μεταβλητή για να πετάξετε οποιαδήποτε αρχεία δεν ταιριάζουν σε ορισμένα κριτήρια του τύπου του αρχείου. Από την PHP 4.2.0, μπορείτε να χρησιμοποιείτε την $_FILES['userfile']['error'] και να προγραμματίζετε τη λογική σας σύμφωνα με τους κωδικούς σφαλμάτων. Οποιαδήποτε η λογική, θα πρέπει είτε να διαγράψετε το αρχείο από τον προσωρινό κατάλογο ή να το μετακινήσετε κάπου αλλού.

Το αρχείο θα διαγραφεί από τον προσωρινό κατάλογο στο τέλος του request αν δεν έχει μετακινηθεί ή διαγραφεί.