PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Datei Upload - Erkennung der Dateiendung


computexx
28.09.2006, 22:28:10
Hallo Leute!

Mein erstes Posting und gleich eine Frage, weiß nicht mehr weiter.
Hab ein DateiUploadscript geschnipselt das dazu dienen soll über ein Admininterface dateien hochzuladen die andere User dann runterladen können. Das die Datei upgeloadet wird, hab ich schon mal geschafft, jedoch hab ich jetzt das Problem, das er mir alle Datein rauflädt, es sollen aber nur gewisse Dateiendungen möglich sein (wie zB gif, jpg, doc, etc.).

Mein Code sieht wie folgt aus:
<?
if ($sendendownadd == "0" && $action == "downadd") {
?>
<form name="formdownadd" action="<?php $PHP_SELF; ?>" method="post" enctype="multipart/form-data">
<p>Bitte Datei auswählen:<br>
<input type=file name=file>
<input name="sendendownadd" type="hidden" value="1" />
<p><input name="Submit" type="submit" value="Hochladen">
</form>
<?
} elseif ($sendendownadd == "1" && $action == "downadd") {
$pfad = "../downloads";
$sizeabfrage = "yes";
$size = "40000";

if ($file_name == "") {
die("Keine Datei gewählt.");
}
if (file_exists("$pfad/$file_name")) {
die("Datei bereits vorhanden.");
}
if ($sizeabfrage == "yes") {
if ($file_size > $size) {
die("Die Datei ist zu groß !");
}
}
$extensions = array(".jpg", ".JPG", ".gif", ".pdf", ".doc", ".txt");
if(in_array($file_type, $extensions)) {
die("Nur PDF, DOC, TXT, JPG oder GIF Dateien möglich!");
}

$upload = "$file_name";
@copy($file, "$pfad/$upload") or die("Datei wurde nicht hochgeladen.");
echo "Datei hochgeladen";
}

Bin auch für Verbesserungen zu haben :) Und bitte achtet darauf, ich bin ein PHP Neuling ;) Danke für Eure Hilfe.

mwX
28.09.2006, 22:36:31
hallo,
wenn ich das auf die schnelle richtig erkenne sagst du mit:

$extensions = array(".jpg", ".JPG", ".gif", ".pdf", ".doc", ".txt");
if(in_array($file_type, $extensions)) {
die("Nur PDF, DOC, TXT, JPG oder GIF Dateien möglich!");
doch eigentlich, dass diese dateien nicht hochgeladen werden sollen, oder ?!

probier doch mal if(!in_array($file_type, $extensions))

computexx
28.09.2006, 22:43:20
Was du geschrieben hast stimmt schon mal ;) Ich sage dem Script in meinem Fall ja das er den die()-Befehl ausführen soll wenn die extensions vorhanden sind. Was so natürlich nicht richtig ist, denn dann soll er ja uploaden.

Jedoch auch wenn ich es ändere bringt es nichts, er bleibt trotzdem bei diesem Befehel hängen und schreibt mir den die() Befehl hin. Obwohl es sich um eine DOC-Datei handelt.

Komisch ...

Opendix
28.09.2006, 22:54:18
was ist den $file_type?

ich nehme an du willst hier auf:
$_FILES['file']['type'] zugreiffen!

genauso oben benutze die superglobalen Arrays! $PHP_SELF ==> $_SERVER['PHP_SELF']!!

http://de.php.net/register_globals

mwX
28.09.2006, 22:58:47
ich hab auch mal sowas gebaut und folgendes benutzt:

$dattyp = "";
$dattyp = split("\.", $datname);
$dattyp[count($dattyp)-1];
$endung = strtolower($dattyp[count($dattyp)-1]);
if($endung != "jpg" && $endung != "JPG" && $endung != "tif" && $endung != "TIF" && $endung != "pdf" && $endung != "PDF" && $endung != "gif" && $endung != "GIF") {
$hinweis .= "-->Datei enth&auml;lt kein g&uuml;ltiges Dateiformat<--";
$speichern = false;
}


der upload kann hinterher nur dann zugelassen werden, wenn $speichern=true ist !

computexx
28.09.2006, 23:09:00
@Opendix
Tja, das ist eine Preisfrage, ich muss gestehen ich weiß es selbst nicht, es war eine "schlussfolgerung" von $file_name. Aber scheint wohl dann nicht richtig zu sein. Ich hab dazu auch nicht wirklich Hilfe beim PHP Manual gefunden.

Das ich die Register Global ON Arrays benutze war mir nicht bewußt, damit hab ich mich noch nicht auseinander gesetzt, aber das du gleich den Hilfreichen Link dazu gepostet hast, dafür dank ich dir. Werde das Script natürlich gleich passend darauf umstellen.

Wie du deine Lösung meinst, weiß ich nicht wirklich, vielleicht kannst du mir das genauer erklären. (PHP Noob, nicht vergessen *g*)

@mwX
Naja, mwX, ich werd zwar aus dem Code schlau, aber ich hab keine Ahnung wie ich den jetzt mit meinem Code verbinden soll. *kratz*

Opendix
28.09.2006, 23:33:53
schau dir mal das an:
http://www.dynamicwebpages.de/php/features.file-upload.php

computexx
28.09.2006, 23:37:50
Werd ich mich drüber stürzen.
Ich sag vorerst mal danke, werd denk ich heut nicht mehr ans Script gehen.

Vielleicht bis morgen, bzw. sicher, wenns klappt post ich dann mal den Code (falls interesse besteht).

Danke
LG

Opendix
28.09.2006, 23:47:21
Werd ich mich drüber stürzen.
Ich sag vorerst mal danke, werd denk ich heut nicht mehr ans Script gehen.

Vielleicht bis morgen, bzw. sicher, wenns klappt post ich dann mal den Code (falls interesse besteht).

Danke
LG

Jo, bitte poste immer den Code der ein Problem gelöst hat. So können andere die vielleicht uach mal das Problem haben (oder ähnlich) das anschaun :)

Serp
29.09.2006, 02:28:02
Ich möchte hier nur noch auf folgendes hinweisen: Die Dateiendung hat rein gar nix mit dem Dateityp zu tun. Hier müsstest du eher auf den MIME-Typ zurückgreifen und den abfragen. Entsprechend ist $_FILE['xyz']['type'] schon der richtige Ansatz.

Weiter ist es nicht unbedingt sinnvoll, split zur Extraktion der Dateiendung zu verwenden. Mal abgesehen davon, dass das nicht unbedingt performant ist, was passiert bei einer Datei wie ich.hab.viele.punkte.jpg? Sehr lustige Dateiendung... Wenn so was gewünscht ist, würd ich also was aus substr und strrpos (man beachte die zwei r!) basteln.

meikel (†)
29.09.2006, 08:28:44
Ich möchte hier nur noch auf folgendes hinweisen: Die Dateiendung hat rein gar nix mit dem Dateityp zu tun. Hier müsstest du eher auf den MIME-Typ zurückgreifen und den abfragen.
Richtig.
Entsprechend ist $_FILE['xyz']['type'] schon der richtige Ansatz.
Falsch. Die Variable setzt der Client und jeder böse Client lügt.

http://de2.php.net/mime_content_type
oder (falls Bilder erwartet werden)
http://de2.php.net/getimagesize

Weiter ist es nicht unbedingt sinnvoll, split zur Extraktion der Dateiendung zu verwenden. Mal abgesehen davon, dass das nicht unbedingt performant ist, was passiert bei einer Datei wie ich.hab.viele.punkte.jpg? Sehr lustige Dateiendung... Wenn so was gewünscht ist, würd ich also was aus substr und strrpos (man beachte die zwei r!) basteln.
Warum einfach, wenns auch umständlich geht:
http://de2.php.net/pathinfo

Wichtig:
egal, wie - es muß verhindert werden, daß PHP Scripte ins Verzeichnis geladen werden können.

rsciw
29.09.2006, 12:15:09
hmn, mime_content_type kannt ich noch net :)

schoene hierbei ist, mit

$fname = "bild.jpg";
echo mime_content_type($fname);

gibt IExplorer "image/jpeg" aus anstatt mit

$_GET['upload']['type'], wo's dann "image/pjpeg" ausspuckt.

andererseits wird z.B. eine php seite mit mime_content_type als
text/plain angesehn, mit $_GET als "application/x-php",
oder html = text/plain mit mime, und text/html mit $_GET.

denke mal, je nach dem was man braucht nimmt man das ein oder andere?

meikel (†)
29.09.2006, 18:28:26
gibt IExplorer "image/jpeg" aus anstatt mit
$_GET['upload']['type'], wo's dann "image/pjpeg" ausspuckt.
Eben. Auf die Marotten der einzelnen Browsertypen brauchst Du gar nicht einzugehen.

Einfachste und sicherste Lösung beim Upload von Bildern ist getimagesize()

$arr = getimagesize($_FILES['formularname']['tmp_name']);
$arr = ($arr === false)
? 0
: $arr[2];
switch($arr)
{
case 1:
case 2:
case 3:
# gif, jpg, png
$flag = true;
break;
default:
# was Du nicht haben willst
$flag = false;
}

$pfad = $_SERVER['DOCUMENT_ROOT'] . '/dort_soll_es_hin/';

if ($flag === true AND move_uploaded_file($_FILES['formularname']['tmp_name'], $pfad . $_FILES['formularname']['name']))
{
# alles OK
}
Das schließt zB. PHP Scripts aus, weil getimagesize() dann false zurückgibt.

denke mal, je nach dem was man braucht nimmt man das ein oder andere?
Naja, die Anzahl der fremden User, die Dir auf Deine Kiste PHP Scripte laden dürfen, dürfte gegen Null gehen.

computexx
02.10.2006, 23:06:05
Eben. Auf die Marotten der einzelnen Browsertypen brauchst Du gar nicht einzugehen.

Einfachste und sicherste Lösung beim Upload von Bildern ist getimagesize()

$arr = getimagesize($_FILES['formularname']['tmp_name']);
$arr = ($arr === false)
? 0
: $arr[2];
switch($arr)
{
case 1:
case 2:
case 3:
# gif, jpg, png
$flag = true;
break;
default:
# was Du nicht haben willst
$flag = false;
}

$pfad = $_SERVER['DOCUMENT_ROOT'] . '/dort_soll_es_hin/';

if ($flag === true AND move_uploaded_file($_FILES['formularname']['tmp_name'], $pfad . $_FILES['formularname']['name']))
{
# alles OK
}
Das schließt zB. PHP Scripts aus, weil getimagesize() dann false zurückgibt.


Naja, die Anzahl der fremden User, die Dir auf Deine Kiste PHP Scripte laden dürfen, dürfte gegen Null gehen.

Zu den Bildern wäre ich erst später gekommen :D Aber danke gleich mal für den hilfreichen Code. Derzeit arbeite ich daran, das man über ein Admincontrolpanel Dateien uploaded (doc, txt, pdf) damit diese dann User runterladen können. Und das bekomm ich nicht ganz gebacken. Das uploaden funktioniert zwar schon, aber eben mit allen dateien, egal welche endung.

Komm noch nicht so ganz mit, wie man den mime_content_type oder den pathinfo() Befehl verwirklicht.

meikel (†)
03.10.2006, 00:00:01
Derzeit arbeite ich daran, das man über ein Admincontrolpanel Dateien uploaded (doc, txt, pdf) damit diese dann User runterladen können.
Dringender Tip:
laß die Finger von *.doc und *.xls, es sei denn, Dein Provider bietet einen Onlinevirenscanner auf seinem Server an, der bei Bedarf meckert, wenn das Zeuch Macroviren enthält.

Und das bekomm ich nicht ganz gebacken. Das uploaden funktioniert zwar schon, aber eben mit allen dateien, egal welche endung.
Noch mal: Du mußt mit mime_content_type() den Inhalt testen und mit pathinfo() die Extension ermitteln.

Komm noch nicht so ganz mit, wie man den mime_content_type oder den pathinfo() Befehl verwirklicht.
Steht eigentlich im Handbuch...

echo mime_content_type('/pfad/zu/einem/bild.jpg');

$f = pathinfo('/pfad/zu/einem/bild.jpg');
echo $f['extension'];

Und damit Du das gleich beim Upload testen kannst:
$content_type = mime_content_type($_FILES['formularname']['tmp_name']);
$f = pathinfo($_FILES['formularname']['name'];
$extension = $f['extension'];

Beim Upload eines JPG Bildes steht dann in $content_type:
'image/jpeg'
und in $extension:
'jpg'

Behandle die Variable $extension vorher mit strtolower() - PHP macht ja Unterschiede zwischen großen und kleinen Buchstaben.

Wichtig:
es ist ratsam, um Umlaute und diverse Sonderzeichen zu erlauben, den Dateinamen mit rawurlencode() zu behandeln. Dann gibt es weniger Ärger beim Speichern. Im Link kannst Du dann den Namen gleich verwenden, für die Beschreibung das:
printf ('<a href="/path/%s">%s</a>',
$dateiname
htmlentities(rawurldecode($dateiname)));

computexx
03.10.2006, 00:36:04
Danke! Genau so eine Erklärung braucht ein noob wie ich. Hab leider die schlechte Eigenschaft, learning by doing und nicht learning by book, ich kann einfach besser lernen wenns mir erklärt bzw. gezeigt wird, denn dann merk ich mir das auch wesentlich schneller als wie aus irgendwelchen Lektüren.

Hab jetzt zumindest mal auf die Global Arrays beim code geschaut, aber jetzt sollt ich ja eigentlich auch das Mime und patch verstehen.

Danke nochmals.

meikel (†)
03.10.2006, 04:36:56
Hab leider die schlechte Eigenschaft,
Die solltest Du Dir abgewöhnen.

Tip:
1. arbeite ein paar FAQs durch und teste auch die Scriptbeispiele.
2. lege Dir das Handbuch daneben - entweder im Browser oder Du saugst Dir von www.php.net 'ne *.chm Datei - und gucke bei jeder Anweisung/Funktion nach, was die überhaupt bewirkt.