Trick # 613 | Dieser Beitrag beinhaltet 0 Wörter. – Geschätzte Lesezeit: ca. 0 Minuten.
Ab und an ist ein Dateianhang einfach zu gross, um ihn per Mail zu versenden. Die meisten Provider machen bei höchstens 10 Megabyte Schluss; viele greifen dann auf einen Filetransfer-Dienst wie etwa WeTransfer zurück, laden die Dateien dort hoch und verschicken bloss den Downloadlink. Das ist praktisch – was aber mit den Dateien bei diesen Diensten geschieht, ist recht unklar. Darum bauen wir heute den eigenen, ganz privaten Filetransferdienst, der das besser kann.
Wir entwickeln ein eigenständiges Dateitransfer-System, das vollständig unabhängig von externen Diensten (z.B. WeTransfer o.ä,) arbeitet. Der entscheidende Vorteil: Sie behalten die Kontrolle über die maximale Dateigrösse und gewährleisten gleichzeitig, dass ausschliesslich autorisierte Nutzer Zugriff haben.
Die zentralen Funktionen im Überblick:
- Zugangskontrolle: Nur Nutzer mit gültigen Login-Daten erhalten die Möglichkeit, Dateien hochzuladen.
- Schutz vor Spam: Ein einfaches CAPTCHA sorgt dafür, dass automatisierte Bots ausgesperrt bleiben.
- Optimierung der Dateinamen: Hochgeladene Dateien werden automatisch so angepasst, dass Sonderzeichen entfernt werden und die Namen klar und standardisiert sind.
- Vermeidung von Duplikaten: Das System überprüft, ob eine Datei mit demselben Namen bereits vorhanden ist. Sollte dies der Fall sein, wird der Dateiname durch einen Zähler ergänzt, um ein unbeabsichtigtes Überschreiben zu verhindern.
Okay! Die folgenden Schritte müssen Sie als erstes tun:
- Subdomain erstellen: Richten Sie über das Administrations-Tool Ihres Hosting-Anbieters eine Subdomain ein. Wenn Ihre Hauptdomain beispielsweise «die-schoenste-website.ch» lautet, könnten Sie die Subdomain «transfer.die-schoenste-website.ch» nennen. Die Subdomain-Einrichtung ist in der Regel kostenlos.
>>> Die Erstellung der Subdomain kann einige Minuten dauern. Warten Sie daher, bevor Sie mit den nächsten Schritten fortfahren. - FTP-Zugang anlegen: Legen Sie für die Subdomain einen neuen FTP-Benutzer an. Auch dies lässt sich über das Administrations-Tool Ihres Hosting-Anbieters erledigen.
>>> Achten Sie darauf, ein sicheres Passwort zu verwenden. - Benötigte Dateien erstellen: Innerhalb der Subdomain müssen Sie zwei Dateien anlegen: «index.php» und «styles.css». Dies können Sie entweder direkt im Administrations-Tool des Hosters oder mithilfe eines FTP-Programms wie FileZilla tun.
>>> Wenn Sie ein FTP-Programm nutzen, benötigen Sie die Login-Daten des zuvor angelegten FTP-Benutzers.
Sobald diese Vorbereitungen abgeschlossen sind. Kopieren Sie den nachfolgenden Code in die Datei «index.php». Dies können Sie entweder über das Tool Ihres Hosting-Providers oder mit dem FTP-Programm vornehmen:
Code für die Datei index.php
<?php
session_start();// Zugangsdaten
define('USERNAME', 'HIER_IHR_BENUTZERNAME');
define('PASSWORD', 'HIER_IHR_PASSWORT');// CAPTCHA generieren
if (!isset($_SESSION['captcha'])) {
$_SESSION['captcha'] = [
'num1' => rand(1, 9),
'num2' => rand(1, 9),
'result' => 0
];
$_SESSION['captcha']['result'] = $_SESSION['captcha']['num1'] + $_SESSION['captcha']['num2'];
}// Funktion zur Dateinamensanpassung
function sanitizeFileName($fileName) {
// Mapping für häufige Ersetzungen (Umlaute, Akzente, Sonderzeichen)
$replaceMap = [
'ä' => 'ae', 'ö' => 'oe', 'ü' => 'ue', 'Ä' => 'Ae', 'Ö' => 'Oe', 'Ü' => 'Ue',
'ß' => 'ss',
'é' => 'e', 'è' => 'e', 'ê' => 'e', 'ë' => 'e',
'á' => 'a', 'à' => 'a', 'â' => 'a', 'ã' => 'a', 'å' => 'a', 'ä' => 'a',
'í' => 'i', 'ì' => 'i', 'î' => 'i', 'ï' => 'i',
'ó' => 'o', 'ò' => 'o', 'ô' => 'o', 'õ' => 'o', 'ö' => 'o', 'ø' => 'o',
'ú' => 'u', 'ù' => 'u', 'û' => 'u', 'ü' => 'u',
'ç' => 'c',
'ñ' => 'n',
'ý' => 'y', 'ÿ' => 'y',
'Æ' => 'Ae', 'æ' => 'ae', 'Ø' => 'Oe', 'œ' => 'oe'
];// Ersetzungen basierend auf Mapping
$fileName = strtr($fileName, $replaceMap);// Transliteration: Entfernt verbleibende Akzente und nicht-ASCII-Zeichen
$fileName = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $fileName);// Kleinbuchstaben und Ersetzen von Leerzeichen durch Unterstriche
$fileName = strtolower($fileName);
$fileName = preg_replace('/\s+/', '_', $fileName);// Entfernen von unerlaubten Zeichen, nur alphanumerische Zeichen, Unterstrich, Punkt und Bindestrich zulassen
$fileName = preg_replace('/[^a-z0-9\-_\.]/', '', $fileName);return $fileName;
}// Funktion, um Dateinamen zu erweitern
function getUniqueFileName($directory, $fileName) {
$pathInfo = pathinfo($fileName);
$baseName = $pathInfo['filename'];
$extension = isset($pathInfo['extension']) ? '.' . $pathInfo['extension'] : '';
$counter = 1;$newFileName = $fileName;
while (file_exists($directory . '/' . $newFileName)) {
$newFileName = $baseName . '-' . $counter . $extension;
$counter++;
}return $newFileName;
}// Anmeldung
if (!isset($_SESSION['logged_in'])) {
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if ($_POST['username'] === USERNAME && $_POST['password'] === PASSWORD) {
$_SESSION['logged_in'] = true;
header('Location: index.php');
exit;
} else {
$error = 'Ungültige Zugangsdaten!';
}
}
?>
<!DOCTYPE html>
<html lang="de">
<body>
<form method="POST" action="">
<h1>Login</h1>
<link rel="stylesheet" href="styles.css">
<?php if (isset($error)) echo '<p style="color: #e75667;">' . $error . '</p>'; ?>
<input type="text" name="username" placeholder="Benutzername" required>
<input type="password" name="password" placeholder="Passwort" required>
<button type="submit">Anmelden</button>
</form>
</body>
</html>
<?php
exit;
}// Nachricht-Variable initialisieren
$message = '';// Datei-Upload
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['file'])) {
$user_captcha = isset($_POST['captcha']) ? intval($_POST['captcha']) : null;
if ($user_captcha !== $_SESSION['captcha']['result']) {
$message = '<p style="color: #e75667;">Falsches CAPTCHA, bitte erneut versuchen</p>';
} else {
$file = $_FILES['file'];
$upload_dir = 'transfers';
if (!is_dir($upload_dir)) {
mkdir($upload_dir, 0777, true);
}// Dateiname anpassen
$sanitizedFileName = sanitizeFileName($file['name']);
$uniqueFileName = getUniqueFileName($upload_dir, $sanitizedFileName);
$target_path = $upload_dir . '/' . $uniqueFileName;if (move_uploaded_file($file['tmp_name'], $target_path)) {
$file_url = 'https://' . $_SERVER['HTTP_HOST'] . '/' . $target_path;
$message = '<h1>Datei erfolgreich hochgeladen</h1>';
$message .= '<p style="text-align: center;">Die Datei hat die URL<br /><b>' . $file_url . '</b></p>';
$message .= '<p><button onclick="copyToClipboard(\'' . $file_url . '\')">URL in die Zwischenablage kopieren</button>';
$message .= '<span id="confirmationMessage" style="display: none; margin-left: 10px; color: #538f38;">URL wurde in die Zwischenablage kopiert.</span></p>';
} else {
$message = '<p style="color: #e75667;">Fehler beim Hochladen der Datei</p>';
}
$_SESSION['captcha'] = [
'num1' => rand(1, 9),
'num2' => rand(1, 9),
'result' => 0
];
$_SESSION['captcha']['result'] = $_SESSION['captcha']['num1'] + $_SESSION['captcha']['num2'];
}
}
?><!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Datei-Transfer</title>
<link rel="stylesheet" href="styles.css">
<meta name="robots" content="noindex, nofollow">
<script>
function copyToClipboard(text) {
navigator.clipboard.writeText(text).then(() => {
const confirmationMessage = document.getElementById('confirmationMessage');
confirmationMessage.style.display = 'inline';
});
}function displayFileName(input) {
const fileNameDisplay = document.getElementById('fileNameDisplay');
if (input.files && input.files[0]) {
const file = input.files[0];
const fileSize = (file.size / 1024 / 1024).toFixed(2); // Dateigröße in MB, auf 2 Dezimalstellen gerundet
fileNameDisplay.textContent = `Ausgewählte Datei: ${file.name} (${fileSize} MB)`;
} else {
fileNameDisplay.textContent = '';
}
}
</script>
</head>
<body><?php if ($message) echo $message; ?><form method="POST" enctype="multipart/form-data">
<h1>File-Transfer-Upload</h1>
<label for="file-upload" class="custom-file-upload">
Datei auswählen
</label>
<input id="file-upload" type="file" name="file" onchange="displayFileName(this)" required>
<p id="fileNameDisplay" style="margin-top: 10px;"></p> <!-- Platz für den Dateinamen -->
<p>Was ergibt <?= $_SESSION['captcha']['num1'] ?> + <?= $_SESSION['captcha']['num2'] ?>?</p>
<input type="text" name="captcha" required>
<button type="submit">Hochladen</button>
</form>
</body>
</html>Besondere Aufmerksamkeit sollten Sie den Zeilen 5 und 6 widmen: In Zeile 5 legen Sie den Benutzernamen fest, den Sie später für den Zugang zur Transfer-Seite verwenden möchten. In Zeile 6 tragen Sie ein Passwort ein – achten Sie darauf, ein starkes und sicheres Passwort zu wählen.
Der folgende Codeabschnitt ist optional, wird jedoch empfohlen: Er enthält ein CSS-Stylesheet, mit dem Sie das Design Ihrer neuen Upload-Seite individuell anpassen können.
Diesen Code fügen Sie in die eingangs erstellte Datei «styles.css» ein. Sie können die Datei entweder direkt über das Admin-Tool Ihres Hosting-Anbieters oder mithilfe eines FTP-Programms (etwa FileZilla) bearbeiten:
Code für die Datei styles.css
body {
font-family: Verdana, Arial, sans-serif;
margin: 0;
padding: 20px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100vh;
}h1 {
color: #538f38;
}form {
margin-top: 50px;
background: #fff;
border: 1px solid #ccc;
padding: 20px;
}form label {
display: block;
margin: 10px 0 5px;
}form input[type="text"],
form input[type="password"],
form input[type="file"] {
padding: 8px;
margin-bottom: 15px;
border: 1px solid #ccc;
}form button, button, .custom-file-upload {
background: #e75667;
color: #fff;
border: 1px solid #e75667;
padding: 10px 15px;
cursor: pointer;
font-size: 14px;
}form button:hover, button:hover, .custom-file-upload:hover {
background: #e4e4e4;
color: #1f431e;
}
input[type="file"] {
display: none; /* Versteckt das Standard-Uploadfeld */
}.custom-file-upload {
display: inline-block;
}Das Stylesheet können Sie selbstverständlich ganz nach Ihren Wünschen anpassen. Hier gilt: Probieren geht über Studieren!
Testen Sie jetzt Ihr Upload-Tool:
- Öffnen Sie die zuvor eingerichtete Subdomain in Ihrem Webbrowser.
- Melden Sie sich mit den Zugangsdaten an, die Sie im index.php-Skript definiert haben.
- Nach dem Login sehen Sie die Upload-Oberfläche. Beim Hochladen werden beliebige Dateien automatisch in den Ordner «transfers» gespeichert. Ein Beispiel für eine typische URL könnte so aussehen:
https://upload.die-schoenste-website.ch/transfers/eine-besonders-detaillierte-anleitung.pdf
>>> Während des Upload-Prozesses wird der Dateiname optimiert: Grossbuchstaben, Umlaute und Akzente werden entfernt, sodass am Ende ein sauberer, webfreundlicher Name entsteht. - Ein besonderes Highlight: Nach Abschluss des Uploads erhalten Sie sowohl einen Direktlink zur Datei als auch einen Button, mit dem die URL direkt in die Zwischenablage kopiert werden kann.
>>> Das macht die Weiterverwendung, beispielsweise in Ihrem Mailprogramm, besonders einfach.
Fazit:
Mit diesem Skript schaffen Sie eine flexible und unabhängige Lösung für den Transfer grosser Dateien. Sie sind nicht mehr auf Dienste wie etwa WeTransfer angewiesen und behalten volle Kontrolle über die Sicherheit und Dateiverwaltung.
Eine praktische Lösung für alle, die den Datenschutz hochhalten. Von heiklen Daten sollten Sie allerdings absehen: Die Files sind von allen einsehbar, welche über einen entsprechenden Link verfügen.
Option: Automatische Löschung von alten Dateiuploads
Aus unserer Sicht empfehlenswert ist das regelmässige Löschen von älteren Files im Ordner «transfers». Wir haben dies mittels einer weiteren PHP-Datei und einem Cronjob gelöst, der einmal wöchentlich ausgeführt wird und dann Files, welche älter als 30 Tage sind, vom Server löscht. Das hat sich bewährt – ansonsten droht der Server irgendwann vollzulaufen.
Falls Sie dies umsetzen wollen, erstellen Sie (wie in den ersten Schritten ganz oben) eine weitere Datei in Ihrer Subdomain. Nennen Sie sie beispielsweise «file-delete.php». Bearbeiten Sie die soeben erstellte Datei und fügen den folgenden Block ein:
Code für die Datei file-delete.php
<?php
$directory = 'transfers';
$max_age = 30 * 24 * 60 * 60; // 30 Tage in Sekundenif (is_dir($directory)) {
$files = scandir($directory);
foreach ($files as $file) {
$file_path = $directory . '/' . $file;// Sicherstellen, dass .htaccess nicht gelöscht wird
if ($file === '.htaccess') {
continue; // Überspringe .htaccess
}if (is_file($file_path)) {
$file_age = time() - filemtime($file_path);
if ($file_age > $max_age) {
unlink($file_path); // Datei löschen
}
}
}
}
?>Ampassen können Sie die Zeile 3. Dort wird im Beispiel definiert, dass ein File nicht gelöscht wird, bevor es mindestens 30 Tage alt ist. Diesen Wert können Sie natürlich anpassen.
Das ganze speichern und in einen Cronjob-Dienst wechseln – die meisten Webhosting-Provider liefern sowas frei Haus.
Im Cronjob-Dienst können Sie nun einen neuen Vronjob erstellen. Es ist recht sinnlos, einen solchen jede Minute aufzurufen. Wir beispielsweis führen unseren Lösch-Cronjob jeden Montag um Mitternacht aus. Als Befehlszeile verwenden Sie den Wget-Befehl – der ist am simpelsten und macht, was er soll. Etwa so:
wget -O /dev/null -o /dev/null https://IHRE.Transfers-Domain.ch/file-delete.phpNun werden ältere Transfer-Uploads automatisch vom Serrver gelöscht, wenn sie mindestens 30 Tage alt sind.
Ein einfaches Housekeeping.
Werbung


