Søger du en specifik kategori?

 



Oprettet søn. d. 08. marts 2009 kl. 03:14

pacroon
pacroon (38.059 point)
Guidens karaktér
1
2
3
4
5

Fileupload og dirlisting i PHP - en primer

En forholdsvis basal gennemgang af en af PHP's pseudoklasser, dir-objektet, samt hvordan du benytter det i forbindelse med upload af filer. Målgruppe: Alle der har interesse - dog vil denne artikel næppe overraske de garvede PHP-guruer. ;)
I adskillige tilfælde er jeg faldet over spørgsmål i PHP-kategorien, hvor folk har haft brug for et "upload script",
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:

<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>


Når filen er uploadet, bliver følgende globale variabler tilgængelige:

$userfile
- 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:

$archive_dir="/dir/htdocs/";
$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:

$archive_dir="/dir/htdocs/";
$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:

<?php
//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:

if(isset($WINDIR)) { $userfile = str_replace("\\\\","\\", $userfile); }


Hvis størrelsen er 0, dvs. der er blevet submittet uden at angive en fil:

if($userfile_size <= 0) die ("$filename is empty");


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 = dir("/dir/htdocs/");


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:

<?php
$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:

<?php
$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

Skrevet fre. d. 16. april 2004 kl. 18:15| #1


Skrevet lør. d. 17. april 2004 kl. 00:52| #2

vis_dk (16.605 point)
Det var lige det jeg ledte efter! Den ramte plet. ;)

Skrevet lør. d. 17. april 2004 kl. 12:29| #3

the_email (23.977 point)
God og meget forklarende artikkel. Man er ikke i tvivl om hvad det er scriptet gør.

Skrevet søn. d. 25. april 2004 kl. 20:46| #4

human (17.863 point)
Utrolig god artikel. Og nem at forstå

Skrevet søn. d. 25. april 2004 kl. 22:32| #5

flash-man (18.370 point)
Rigtig go artikel, du har løst mange af mine problemer :)

Skrevet ons. d. 28. april 2004 kl. 01:01| #6

larsholmgaard_dk (37.144 point)
Supergod artikel, som jeg bestemt sagtens kan bruge og lære noget af. Skrevet i et meget letforståeligt sprog og med præcis den mængde forklaring der skal til - virkelig godt! /larsholmgaard.dk

Skrevet tor. d. 29. april 2004 kl. 20:42| #7


Skrevet ons. d. 26. maj 2004 kl. 17:11| #8

refuge (14.303 point)
okay .. virker som den skal

Skrevet tor. d. 03. juni 2004 kl. 22:49| #9

vipez (17.312 point)
Jeg får en fejl?
Notice: Undefined variable: action in j:apachehtdocstestuploadsindex.php on line: 40 (if($action == 'upload') {)

Skrevet søn. d. 20. juni 2004 kl. 21:53| #10


Skrevet tor. d. 21. oktober 2004 kl. 17:45| #11


Skrevet søn. d. 12. december 2004 kl. 17:46| #12


Skrevet ons. d. 15. december 2004 kl. 10:53| #13

morteeart (14.598 point)
god artikel, "bakarden" tror det er dig som er n00b, hvis du ikke kan få så simpel kode her til at virke.
Folk mangler genneralt at lære at debugge.

Skrevet man. d. 24. januar 2005 kl. 10:35| #14

doodoo (23.691 point)
God artikel - jeg fik det hjælp jeg skulle bruge =)

Skrevet søn. d. 24. april 2005 kl. 22:15| #15


Skrevet tir. d. 28. juni 2005 kl. 18:05| #16

arkanoid (14.810 point)
Glimrende artikel om PHP's filupload. bakarden - hvis du ikke selv var n00b ville du se det brugbare i dette

Skrevet tor. d. 21. juli 2005 kl. 21:23| #17


Skrevet ons. d. 27. juli 2005 kl. 13:16| #18

stevenizzle (11.625 point)
god artikel!

Skrevet søn. d. 14. august 2005 kl. 18:52| #19

h0lte (12.375 point)
Stilet pacroon (:

Skrevet man. d. 14. november 2005 kl. 19:00| #20

crazybee (18.520 point)
Whuhuw! :D Fin artikel! Du burde skreve flere, Kasp0r!
Og til vipez: Det er ikke en fejl. Hvis du kunne Engelsk ville du vide at "Notice" betyder notifikation og ikke fejl. PHP fortæller dig bare at du ikke har defineret $action, før din if sætning. Jeg mener ikke du burde se notices som standard. Det er alt sammen et spørgsmål om konfigurering af din php.ini fil. Så tal pænt en anden gang :)

Skrevet ons. d. 11. januar 2006 kl. 18:01| #21

duuink (10.705 point)
Über nice artikel..
den løste alle de problemer jeg havde. :-) genialt
viel dank

Skrevet man. d. 14. august 2006 kl. 16:44| #22


Skrevet tor. d. 12. oktober 2006 kl. 08:45| #23


Skrevet man. d. 12. maj 2008 kl. 19:10| #24

bigtime (7.245 point)
det virker som en fin artikel men jeg kan ikke få den til at virke den skriver bare cant copy billedenavn to billedenavn.

Skrevet man. d. 25. oktober 2010 kl. 20:12| #25

Jeg er helt grøn i det her, og har savnet et script som dette. Men jeg kan ikke få det til at virke, måske fordi jeg "mangler" php.ini, har en idé om at den skal indeholde dette

$userfile
- stien til den uploadede fil på serveren

Men er bestemt ikke sikker, og i så fald det ikke er korrekt, har jeg ingen idé om hvad der skal stå i php.ini

Skriv en kommentar



Mest populære guides

Guidens karakter
!!!Karaktér: 3
12 stemmer
31/01 - 2011
Af: heinzdmx

Dropbox - gratis online lagerplads

Jeg vil i denne guide forklare lidt om hvad Dropbox er og også hvordan du får mest mulig plads på Dropbox. Dropbox er kort sagt en service hvor du har dine data lagt til backup på både nettet og din egen computer.
Guidens karakter
!!!Karaktér: 4
33 stemmer
02/02 - 2009
Af: jkrons

Dato- og tidsberegninger i Excel

En introduktion til simple beregninger med dato og tid i Excel. Opdateret med afsnit om beregning af tillæg.
Excel  |  Læs »
Guidens karakter
!!!Karaktér: 4
21 stemmer
06/11 - 2011
Af: fromsej

Sådan fjerner du virus og malware

Udviklingen går stærkt på "skidt"fronten, så vi har sammensat en ny og effektiv programpakke til fjernelse af det.
Virus  |  Læs »

Log ind

   

   

Seneste guides

Installer win 7
Den gode bruger


   




Tips & Tricks fra PC World

Teaser billede

Gør dig selv en tjeneste: Køb et ordentligt SD-kort

Der kan være meget stor hastighedsforskel på to umiddelbare ens SD-kort. Se her hvad du skal være opmærksom på, når du køber ekstra hukommelse til din mobil, tablet eller kamera.


Anmeldelser fra PC World

Teaser billede

Test: Denne super-tablet er iPads hårdeste konkurrent

Eee Pad Transformer Prime er frygtindgydende med sin quadcore processor og evne til at trylle sig om til bærbar. Apple bør kigge i bagspejlet, for Asus' tablet-pc kommer buldrende - og gør det...


Seneste blogindlæg

Teaser billede

Tvangslukke spørgsmål: Hvad er den bedste løsning?

Hej Vi har mange åbne spørgsmål på Eksperten. Vi ville gerne tvangslukke dem - så et spørgsmål efter f.eks. 6 måneder lukkes. Men der er et par uklarheder som ville være gode at få lidt input til:...


Nyheder fra PC World

Teaser billede

Gratis flysimulator fra Microsoft

Den legendariske Flight Simulator fra Microsoft genopstår den 29. februar - og denne gang er spillet gratis.


Nyheder fra Computerworld

Teaser billede

Bank: Derfor er login uden NemID helt i orden

Der er ikke hold i påstanden om sikkerhedsproblemer i forbindelse med bankkunders login uden brug af NemID, lyder det fra Nykredit Bank.


Kurser
Samarbejdspartnere

Udgiver · © 2012 IDG Danmark A/S · Hørkær 18 · 2730 Herlev · Tlf.: 77 300 300 · Fax: 77 300 301 · Brug af personoplysninger