hvorefter de lynhurtigt er blevet kastet et eller andet gratis-script i hovedet der ret ofte ikke var særlig anvendeligt
eller ikke pænt kodet.
I stedet for at folk henter en af disse, tænker jeg, at der måske fandtes nogen som ville spare tid og samtidig lære noget
(hvis man er interesseret) - ved selv at kode scriptet.
Det er forholdsvist simpelt og kan gøres meget hurtigt, og jeg vil derfor gennemgå hvordan PHP kaster filer fra en browser
til en webserver og hvordan du bagefter kan få alting vist i en pæn filoversigt bagefter, samtidig med at der tages nogle
få redundancy-forbehold! ;-)
Upload scriptet:
Jeg lader PHP modtage informationerne om filen der skal uploades vha. htmls <input>-tag der bruges under <form>, af typen 'file'.
<form>-taggets ENCTYPE attribut skal sættes til multipart/form-data.
Her er en sample-uploadform:
<input type="hidden" name="action" value="upload">
Upload file!
<input type="file" name="userfile">
<input type="submit" name="submit" value="Upload">
</form>
Når filen er uploadet, bliver følgende globale variabler tilgængelige:
- stien til den uploadede fil på serveren
$userfile_name
- den originale sti og filnavnet på den uploadede fil
$userfile_size
- størrelsen på den uploadede fil
$userfile_type
- typen af filen (hvis browseren vedlægger denne information)
Hvis vi går ud fra at en bruger lige har uploadet en 20.000-byte zipfil, f.eks. c:\filer\fil.zip, vha. denne form, vil
disse variabler nu indeholde følgende:
$userfile - stien til det midlertidige biblotek (det biblotek, PHP smider alt der uploades op i, før den føres videre til
destinationen, som anført i php.ini), plus det midlertidige filnavn i formatet "php-xxx" (hvor xxx er et automatisk
genereret nummer), f.eks. "/tmp/php-512"
$userfile_name - "c:\filer\fil.zip"
$userfile_size - "20000"
$userfile_type - "application/x-zip-compressed"
Denne fil er uploadet til det midlertidige biblotek defineret i php.ini, og fjernet igen når requestet er gennemført.
Derfor må filen kopieres derfra:
$filename = basename($userfile_name);
if(!copy($userfile, "$archive_dir/$filename")) die ("Can't copy $userfile_name to $filename.");
For at forhindre folk i at uploade filer på enorme størrelser, er det nok meget godt at indsætte et lille sikkerhedscheck:
$max_filesize = 20000;
$filename = basename($userfile_name);
if($userfile_size > $max_filesize) die ("$filename is too big! Only $max_filesize bytes allowed!");
if(!copy($userfile, "$archive_dir/$filename")) die ("Can't copy $userfile_name to $filename.");
Det komplette script ser sådan ud:
//upload.php
function upload_form() {
global $PHP_SELF;
?>
<form method="post" enctype="multipart/form-data" action="<?php echo $PHP_SELF; ?>">
<input type="hidden" name="action" value="upload">
Upload file!
<input type="file" name="userfile">
<input type="submit" name="submit" value="Upload">
</form>
<?php
}
function upload_file() {
global $userfile, $userfile_name, $userfile_size, $userfile_type, $archive_dir, $max_filesize, $WINDIR;
$archive_dir="/dir/htdocs/";
if(isset($WINDIR)) { $userfile = str_replace("\\\\","\\", $userfile); }
$filename = basename($userfile_name);
$max_filesize = 20000;
if($userfile_size <= 0) die ("$filename is empty");
if($userfile_size > $max_filesize) die ("$filename is too big! Only $max_filesize bytes allowed!");
if(!@copy($userfile, "$archive_dir/$filename")) die ("Can't copy $userfile_name to $filename.");
if(isset($WINDIR) && !@unlink($userfile)) die ("Can't delete the file $userfile_name.");
echo "<img src=\"$filename\"><br>";
echo "$filename has been successfully uploaded.<br>";
echo "Filesize: " . number_format($userfile_size) . "<br>";
echo "Filetype: $userfile_type<br>";
}
?>
<html>
<head><title>File upload</title></head>
<body>
<?php
if($action == 'upload') {
upload_file();
} else {
upload_form();
}
?>
Hvordan det virker:
Når en bruger uploader en fil, tjekker scriptet først hvilken platform scriptet er kørt under.
Hvis det er en Windows platform (gud forbyde det), skal alle tilfælde af dobbelte slashes reduceres til enkelte:
Hvis størrelsen er 0, dvs. der er blevet submittet uden at angive en fil:
Hvis alt ser ud til at være a-ok, kopierer scriptet filen til et biblotek og tester om sciptet kører på Windows. Hvis
ikke, burde der ikke være noget i vejen for, at unlink() sletter den midlertidige fil, i PHP-s temp dir.
PHP dir-listing
Hvis det ønskes, at de uploadede filer skal vises et sted, kan man benytte sig af PHPs dir-objekt.
PHP tilbyder denne alternative objekt-orienterede mekanisme til arbejde med bibloteker. For at benytte sig af denne
metode, skal der først instansieres et objekt ved at kalde dir() constructoren med navnet på det biblotek der skal
benyttes på følgende måde:
dir objektet tilbyder to indstillinger: handle og path. Disse henviser til biblotekets handle og
path, sjovt nok. ;)
Man kan benytte handle indstillingen med andre php-dir funktioner som f.eks. readdir() og dir objektet
understøtter også metoder, som read() og close()- som her er interessante.
Du kan rent faktisk skrive et dir-listing script så let som på denne måde, vha. dir:
$default_dir = "/dir/dir/dir/";
$dir = dir($default_dir);
while ($file = $dir->read()) if ($file != '.' && $file != '..')
echo $file . "<br>";
$dir->close;
?>
Det vil dog skrive dem usorteret og lidt rodet, så derfor har jeg lavet et lidt længere script her:
$default_dir = "/dir/dir/dir";
$dir = dir($default_dir);
while($file = $dir->read()) {
$filenames[] = $file;
}
$dir->close();
sort($filenames);
for($i=0; $i < count($filenames); $i++)
if($filenames[$i] != '.' && $filenames[$i] != '..' && $filenames[$i] != 'denne_fil.php' ) {
echo "<a href=\"$filenames[$i]\">$filenames[$i]</a><br>\n";
}
?>
- der i forbindelse med uploadscriptet, outputter filerne som links, idet der som regel uploades billeder i en eller
anden art, og de derfor ikke vil være interessante at vise, hvis ikke man kunne se billederne!
Skulle du støde på funktioner du ikke kender, kan alle funktioner findes i php.net's dokumentation.
Givet at funktionen hedder 'funktionnavn()', kan du søge mere information om den på:
http://www.php.net/ (...)
Bemærk til sidst, at alle sti-angivelser er fiktive, og der skal angives den fulde sti til filen, hvor den ligger på webserveren. ;)
Jeg håber den har været lærerig, og i vil læse den med åbent sind - dette var i hvert fald sjovt at skrive, som min præmiereartikel!
- Pacroon


