echo $begrüßung;
Einiges im Code könnte man sicher eleganter lösen, aber gibt es grundsätzliche Fehler?
Du solltest prüfen, ob der Upload erfolgreich war. Das steht in $_FILES['userfile']['error']. Für Datei-Upload-Fehlercodes und deren Bedeutung gibt es ein eigenes Unterkapitel im Handbuchkapitel Handling file uploads. Es gibt einige Fallstricke, die durch verschiedene PHP-Konfigurationen bei zu großen Dateien zuschlagen können, beschrieben unter Common Pitfalls.
if (isset($_POST['submit']) && $_POST['submit']=="Senden") // Wurde was abgeschickt?
Das Formular wurde also abgeschickt. Ob aber eine Datei dabei war, prüfst du nicht. Die Post-Prüfung führst du im Script noch einige weitere Male aus. Jedoch führst du einige Verarbeitungsschritte unabhängig vom Erfolg des abgeschickten Formulars beziehungsweise des Uploads aus. Im Grunde genommen brauchst du die Post-Prüfung nur einmal und solltest es um den kompletten Teil der Eingabeüberprüfung und Verarbeitung legen (Teile E und V des EVA-Prinzips). Die den Upload betreffenden Teile solltest du nochmal extra vom Fehlerstatus abhängig machen.
$oname = $_FILES['datei']['name'];
Dieses Umkopieren ist überflüssig. Du kannst
$replacearray = array("ä" => "ae", "ö" => "oe", "ü" => "ue", "ß" => "ss", "$" => "s", "ÄE" => "A", "Ö" => "OE", "Ü" => "UE", "&" => "and");
$oname = strtr($oname, $replacearray);
das $_FILES… gleich direkt an der Stelle notieren:
$oname = strtr($_FILES['datei']['name'], $replacearray);
und das strtolower() gleich mit einbauen:
$oname = strtolower(strtr($_FILES['datei']['name'], $replacearray));
Deine Ä-Ersetzung hat übrigens einen Tippfehler. Ich persönlich würde die Dateinamensveränderung komplett weglassen und stattdessen nur eine Prüfung auf nicht erlaubte Zeichen im extrahierten Dateinamen (siehe nachfolgend) vornehmen, wenn dann noch welche übrig sind. Voraussetzung ist, dass es keine weiteren Probleme beim Ablegen der Datei mit UTF-8-kodierten Dateinamen gibt.
$dateiname = substr($oname, 0, strripos($oname, '.')); //Alles nach dem letzten Punkt wird weggeschnitten
$dateiendung = substr($oname, strlen($dateiname)); // Der Dateiname wird weggeschnitten indem die Länge des Strings aus der vorigen Operation genutzt wird --> nur noch Endung mit Punkt
$endung_ohne_punkt = substr($oname, strlen($dateiname) +1); //Die Dateiendung ohne den Punkt für einfacheren array
Mit der Funktion pathinfo() (und/oder der dort unter See also aufgeführten) kannst du dir hier Arbeit sparen.
Du prüfst nicht, ob jemand einen Pfad (../../relativ/woandershin) mit dem Dateinamen mitschickt und fügst das dann ungeprüft zusammen: "data/$fullname". Du könntest beim Auftauchen von / oder \ die Verarbeitung wegen Betrugsversuchs abbrechen oder stillschweigend vom pathinfo()-Ergebnis nur die pfadlosen Teile weiterverarbeiten.
$erlaubte_endungen = array("jpg", "jpeg", "gif", "png", "bmp", "psd", "txt", "rar", "zip", "7z", "mp3", "wav", "ogg"); // bei Bedarf zu ergänzen, hauptsache kein .php und co
Normalerweise ist eine Prüfung nach Dateiendung oder -namen gleichzusetzen mit dem Versuch anhand des Namens einer Person auf dessen Charakter zu schließen. Für den internen Gebrauch mag diese "Prüfung" ausreichend sein. Wenn du das jedoch später mal in ein anderes, öffentliches Projekt übernehmen willst, reicht das nicht mehr. Eine Prüfung nach Inhalt wäre angebrachter. Leider ist die fileinfo-Extension derzeit nur als PECL erhältlich und erst in der demnächst erscheinenden Version 5.3 als "ordentliche" Extension erhältlich. Derzeit gibt es nur die Mimetype-Extension, die aber zugunsten von fileinfo deprecated ist.
Diese Inhaltsprüfung will und kann jedoch keine absolute Sicherheit bieten. Sie prüft lediglich auf markante Teile innerhalb der Datei. Ob das Öffnen und Verarbeiten mit irgendeinem beliebigen Programm fehlerfrei gelingt oder nicht kann damit keinesfalls garantiert werden.
// Zufallszahl durch Unix-Zeitstempel. Bei Bedarf könnte man das Upload-Datum der Datei zuverlässig feststellen.
$zufall = "_". time() ."";
Das Anhängen eines Nichts ist nicht erforderlich. Wenn du übrigens einen besseren Zufallsnamengenerator haben möchtest, nimm uniqid().
<input type="hidden" name="max_file_size" value="10000000">
Das kannst du komplett streichen. Dieses PHP-Feature hat keinen Einfluss auf Browser und die Größe der von denen gesendeten Dateien. PHP prüft zwar beim Bearbeiten des Uploads diesen Wert und die Dateigröße, jedoch ist der vom Client beliebig manipulierbar. Verlas dich lieber auf die von dir durchgeführte Prüfung oder die in der php.ini eingestellten Begrenzungswerte. Außerdem ist MAX_FILE_SIZE im Handbuch immer groß geschrieben. Vielleicht hat das auch noch einen Einfluss auf diese Funktionalität. Weiterhin würde ich das Formular mit an den anfänglichen HTML-Teil angliedern. So mittendrin und bedingungslos ausgegeben ist es zu nichts nütze als zur Verwirrung des Lesers, der sich fragt, warum das an der Stelle steht. Es erfolgt ja auch keine weitere Ausgabe vorher.
Ansonsten habe ich nichts weiter gefunden, außer dass du einen real existierenden Domainnamen für Beispielzwecke missbrauchst. Dafür gibt es doch extra reservierte Domain-Namen, die nicht mit anderen kollidieren.
echo "$verabschiedung $name";