Advertisement
  1. Code
  2. PHP

Online-Dateispeicherung mit PHP

Scroll to top
Read Time: 15 min

() translation by (you can also view the original English article)

In diesem Tutorial werde ich Ihnen zeigen, wie einfach es ist, ein Online-Dateispeichersystem mit PHP zu erstellen. Sie lernen, wie Sie Dateien mit PHP hochladen und auflisten, indem Sie den Ordner "Uploads" scannen.

Einführung

Haben Sie sich jemals gewünscht, dass Sie unterwegs Dateien hochladen könnten? Was ist, wenn Sie ein öffentliches Terminal oder den Computer einer anderen Person verwenden und keine Software von Drittanbietern für die Dateiübertragung installieren können?
Wäre es nicht schön, einfach eine Seite in einem Browser zu öffnen und Ihre Datei mit einem Klick auf eine Schaltfläche hochzuladen?

Es gibt bereits viele Datei-Hosting-Sites, aber in diesem Tutorial werde ich Ihnen zeigen, wie Sie Ihre eigenen erstellen können. Folgendes werden wir erstellen:

Schritt 1 - Grundlegendes HTML

Lassen Sie uns anfangen. Das erste, was wir brauchen, ist ein leeres HTML-Dokument. Ich verwende XHTML 1.0 Transitional mit ISO-8859-1 Zeichensatz. Wenn Sie es vorziehen und keine Sonderzeichen benötigen, können Sie diese durch einen UTF-8-Zeichensatz ersetzen.

1
2
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
<html xmlns="http://www.w3.org/1999/xhtml">
4
<head>
5
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
6
<title>Online file storage</title>
7
</head>
8
<body>
9
10
</body>
11
</html>

Schritt 2 - Hinzufügen des Datei-Upload-Formulars

Ok, jetzt, wo wir eine einfache HTML-Datei haben, haben wir im Grunde nichts :) Also fügen wir etwas Inhalt hinzu. Ich werde den gesamten Inhalt in ein DIV-Element einschließen, um die Seite mit CSS zu gestalten. Die Tags "Fieldset" und "Legend" sind vielleicht etwas selten, aber sie sind das eindeutige Markup für die Organisation von Inhalten in Gruppen.

Ich habe ein Passwortfeld hinzugefügt, mit dem wir unerwünschte Uploader verscheuchen, da wir nicht möchten, dass Fremde unser Dateikontingent mit zufälligem Müll füllen.

Beachten Sie, dass im Gegensatz zum alltäglichen Standardformular für dieses Element der Enctype auf Multipart/Formulardaten festgelegt ist.
Dies wird für POST-Dateien benötigt und muss hier sein. Ich habe den Aktionsmodifikator so eingestellt, dass er auf dieselbe Datei verweist.
Dies bedeutet, dass nach dem Absenden des Formulars die Formulardaten auf dieselbe Seite zurückgesendet werden.

Das versteckte Feld MAX_FILE_SIZE ist für PHP und definiert die maximale Größe (in Bytes), die wir senden können. Dies überschreibt jedoch nicht die Einstellung MAX_FILE_SIZE in der Datei php.ini, sodass immer die maximale Größe bestimmt wird.

1
2
<div id="container">
3
	<h1>Online File Storage</h1>
4
	
5
	<fieldset>
6
		<legend>Add a new file to the storage</legend>
7
		<form method="post" action="index.php" enctype="multipart/form-data">
8
		<input type="hidden" name="MAX_FILE_SIZE" value="100000" />
9
		<p><label for="name">Select file</label><br />
10
		<input type="file" name="file" /></p>
11
		<p><label for="password">Password for upload</label><br />
12
		<input type="password" name="password" /></p>
13
		<p><input type="submit" name="submit" value="Start upload" /></p>
14
		</form>	
15
	</fieldset>
16
</div>

Wenn wir die Datei in einem Browser öffnen, haben wir jetzt ein langweiliges und einfaches HTML-Formular. Es wird Inhalte an sich selbst senden, weiß aber nicht, was es damit anfangen soll.

Wir benötigen einen Platz zum Anzeigen der Dateien, die wir bereits hochgeladen haben. Fügen Sie daher das folgende HTML in den Container div unter dem ersten Feldsatz ein.

1
2
<fieldset>
3
	<legend>Previousely uploaded files</legend>
4
	<ul id="menu">
5
		<li><a href="">All files</a></li>
6
		<li><a href="">Documents</a></li>
7
		<li><a href="">Images</a></li>
8
		<li><a href="">Applications</a></li>
9
	</ul>
10
	
11
	<ul id="files">
12
	</ul>
13
</fieldset>

Beachten Sie, dass die ungeordnete Liste mit der ID "Dateien" leer ist. Machen Sie sich jetzt keine Sorgen, da wir diesen Abschnitt mit den Dateien auf dem Server füllen werden.

Schritt 3 - Fügen Sie CSS und JS hinzu

Ich habe jQuery verwendet, um die Möglichkeit zu schaffen, die Sichtbarkeit bestimmter Dateitypen umzuschalten, ohne die Seite aktualisieren zu müssen.
Das ist rein optional und das Entfernen des JS beschleunigt das Laden der Seite etwas. Fügen wir also die folgenden Zeilen zum HEAD der HTML-Datei hinzu.

1
2
<style type="text/css" media="all"> 
3
	@import url("style/style.css");
4
</style>
5
<script src="http://code.jquery.com/jquery-latest.js"></script>

Ich lade die jQuery zur Laufzeit von einer externen Quelle. Wenn Sie möchten, können Sie dies erneut ändern, sodass die Datei mit dieser Zeile aus einer lokalen Quelle geladen wird.

1
2
<script type="text/javascript" src="js/jquery-1.3.2.min.js"></script>

Durch das Laden der Datei direkt von code.jquery.com wird sichergestellt, dass wir die neueste Version verwenden, und unsere Bandbreite wird bei jedem Laden der Seite gespart. Sollte der Server code.jquery.com jedoch ausfallen oder überfüllt sein, wird die Datei möglicherweise nicht abgerufen wenn wir es brauchen.

Erstellen Sie einen neuen Ordner mit dem Namen style und erstellen Sie darin eine neue CSS-Datei mit dem Namen style.css. Das ist die Datei, die dem Browser mitteilt, wie die Seite aussehen soll. Es gibt hier ziemlich viel CSS, aber es ist einfach genug, dass jeder folgen kann.

Jetzt sollte die Seite ungefähr so ​​aussehen.

1
2
@CHARSET "ISO-8859-1";
3
4
body
5
{
6
	background-color: #cddcec;
7
	font-family: "Arial";
8
	font-size: 11px;
9
}
10
11
div#container
12
{
13
	width: 600px;
14
	margin: 0px auto;
15
	border: 1px solid #e6eef6;
16
	background-color: #ffffff;
17
}
18
19
div#container h1
20
{
21
	background-color: #4b75b3;
22
	margin: 0px;
23
	padding: 8px;
24
	font-family: "Arial";
25
	font-weight: normal;
26
	border: 1px solid #3564a9;
27
}
28
29
div#container fieldset
30
{
31
	margin: 20px;
32
	border: 1px solid #98b9d0;
33
}
34
35
ul#menu
36
{
37
	list-style-type: none;
38
	margin: 4px;
39
	padding: 0px;
40
}
41
42
ul#menu li
43
{
44
	float: left;
45
	margin: 4px;
46
}
47
48
ul#menu li.active
49
{
50
	background-color: #98b9d0;
51
	border-left: 1px solid #3564a9;
52
	border-top: 1px solid #3564a9;
53
	border-bottom: 1px solid #e6eef6;
54
	border-right: 1px solid #e6eef6;
55
}
56
57
ul#menu li a
58
{
59
	text-decoration: none;
60
	font-size: 10px;
61
	padding: 2px;
62
	color: #3564a9;
63
}
64
65
ul#files
66
{
67
	list-style-type: none;
68
	margin: 40px 0px 0px 0px;
69
	padding: 0px;
70
}
71
72
ul#files li
73
{
74
	background-color: #fff7c0;
75
	border-bottom: 1px solid #efefef;
76
	padding: 2px;
77
	margin-bottom: 1px;
78
}

Was wir jetzt haben sollten, ist im folgenden Bild dargestellt.

Schritt 4 - Behandeln von Dateieingaben mit PHP

Beginnen wir die PHP-Seite des Tutorials, indem wir eine Settings-Klasse erstellen. In dieser Klasse können wir das Upload-Passwort sowie den Dateipfad für den Upload-Ordner speichern.
Wir können die Klasse dann in unsere Seite aufnehmen und ihre Werte bei Bedarf verwenden.
Sie können PHP-Dateien mit fast denselben Tools schreiben, die Sie zum Schreiben von HTML und CSS verwenden. Denken Sie jedoch daran, die Datei mit dem Suffix .php zu speichern.

1
2
<?php
3
/**

4
 * Class Settings holds the upload settings

5
 *

6
 */
7
class Settings
8
{
9
	static $password = "mypassword";
10
	static $uploadFolder = "uploads/";
11
}
12
?>

Ohne näher auf die objektorientierte Programmierung (OOP) einzugehen, erstellt der Code eine neue Klasse mit den Werten, auf die zugegriffen werden kann, ohne die Klasse zu instanziieren.
Wir können jetzt einfach auf die Werte zugreifen, indem wir Settings ::$password aufrufen. und Einstellungen ::$uploadFolder; Hier können Sie auch das Passwort jederzeit ändern.
Die <?php und?> Markieren den Anfang und das Ende eines PHP-Codesegments. Diese Segmente können in normale HTML-Seiten geschrieben werden, und der Server interpretiert sie, wenn die Seite angefordert wird.

Ok, jetzt kommen wir zur Sache. Fügen wir in der HTML-Datei, mit der wir gearbeitet haben, Folgendes ganz oben in die Datei ein. Ja, vor dem <head>-Tag.

1
2
<?php 
3
//Load the settings

4
require_once("settings.php");
5
6
$message = "";

Zuerst weisen wir den PHP-Interpreter an, unsere Einstellungsdatei einzuschließen. Ich habe auch eine neue Variable $message eingerichtet. Später werde ich Prozessinformationen in diese Variable schreiben und sie dem Benutzer anzeigen.

1
2
//Has the user uploaded something?

3
if(isset($_FILES['file']))
4
{

Wenn das Formular mit einer Datei gesendet wurde, sollte das Array $_FILE einen Wert mit dem Schlüssel haben, den wir als Namen des Dateieingabefelds verwendet haben.

1
2
	$target_path = Settings::$uploadFolder;
3
	$target_path = $target_path . time() . '_' . basename( $_FILES['file']['name']);

Hier erhalten wir den Pfad zu dem Upload-Ordner, den wir in den Einstellungen angegeben haben. In Zeile 2 fügen wir den Namen der hochgeladenen Datei zum Zielpfad hinzu (verketten ihn).
Beachten Sie auch, dass ich den aktuellen Server-Zeitstempel am Anfang des Dateinamens hinzugefügt habe. Dafür gibt es zwei Gründe.
Erstens wird es zum Speichern des Datums verwendet und zweitens wird sichergestellt, dass alle Dateien unterschiedliche Namen haben.
Sollten wir eine Datenbank hinter dieser Anwendung verwenden, wäre der Zeitpunkt des Hinzufügens da, und wir könnten die Dateinamen serialisieren und den ursprünglichen Namen nur in der Datenbanktabelle speichern.
Da es jedoch keine Datenbank gibt, können wir diese Problemumgehung verwenden.

1
2
	//Check the password to verify legal upload

3
	if($_POST['password'] != Settings::$password)
4
	{
5
		$message = "Invalid Password!";
6
	}
7
	else
8
	{

Wenn die Übermittlung ohne Angabe eines Passworts erfolgte oder wenn das angegebene Passwort etwas anderes als das in den Einstellungen definierte war, werden wir die Datei nicht verarbeiten und nur eine Nachricht zurückgeben, die ein falsches Passwort angibt.

1
2
		//Try to move the uploaded file into the designated folder

3
		if(move_uploaded_file($_FILES['file']['tmp_name'], $target_path)) {
4
		    $message = "The file ".  basename( $_FILES['file']['name']). 
5
		    " has been uploaded";
6
		} else{
7
		    $message = "There was an error uploading the file, please try again!";
8
		}
9
	}
10
}

Ok, das Passwort war also richtig, was nun? Jetzt "speichern" wir die Datei. Ich sage in Klammern speichern, da sich die Datei tatsächlich bereits auf dem Server befindet. Es ist nur im temporären Ordner.
Um die Datei zugänglich zu machen und sicherzustellen, dass der Server sie nicht löscht, wenn die Temperatur gelöscht wird, müssen wir sie an einen sicheren Ort verschieben. Ich habe die Funktion move_uploaded_file verwendet.
Die Funktion akzeptiert zwei Argumente. Der erste ist der temporäre Name der Datei, die vom Server automatisch zugewiesen wird, und der andere ist der zuvor zugewiesene Zielpfad.
Die Funktion gibt einen Booleschen Wert zurück, der eine erfolgreiche Operation anzeigt. Wieder setzen wir den Nachrichtenwert, um den Benutzer darüber zu informieren, was passiert ist.

1
2
if(strlen($message) > 0)
3
{
4
	$message = '<p class="error">' . $message . '</p>';
5
}

Und so einfach ist es, Dateien mit PHP auf den Server hochzuladen! Hier habe ich gerade überprüft, ob etwas in die Nachrichtenvariable geschrieben wurde (Länge größer als 0) und es formatiert, damit wir es mit CSS formatieren können.

Schritt 5 - Listen Sie die hochgeladenen Dateien auf

1
2
/** LIST UPLOADED FILES **/
3
$uploaded_files = "";
4
5
//Open directory for reading

6
$dh = opendir(Settings::$uploadFolder);

Als erstes müssen Sie ein Ordnerhandle erstellen. Alles was es braucht ist ein Befehl. In der Variablen uploaded_files schreiben wir die Ordner-Dateinamen im HTML-Format.

1
2
//LOOP through the files

3
while (($file = readdir($dh)) !== false) 
4
{

Hier durchlaufen wir die Dateien im Ordner. Solange wir die nächste Datei im Ordner in die Dateivariable einlesen können, tun wir dies und fahren fort. Sobald wir alle Dateien durchlaufen haben, gibt die Funktion false zurück und beendet die Schleife.

1
2
	if($file != '.' && $file != '..')
3
	{

Das '.' und '..' werden ebenfalls von dieser Funktion zurückgegeben, daher müssen wir sicherstellen, dass wir nicht versuchen, etwas damit zu tun.

1
2
		$filename = Settings::$uploadFolder . $file;
3
		$parts = explode("_", $file);

Wir fügen den Namen der Datei in den Pfad des Upload-Ordners ein und speichern ihn als Dateinamenvariable. Dann explodieren wir den Namen der Datei am Zeichen '_'.
Diese Funktion gibt ein Array von Zeichenfolgen zurück, die die ursprüngliche Zeichenfolge jedes Mal aufteilen, wenn ein '_' angezeigt wird.
Da es eines dieser Zeichen gibt, erhalten wir ein Array mit dem Zeitstempelteil als Zelle 1 und dem ursprünglichen Dateinamen als Zelle 2.

1
2
		$size = formatBytes(filesize($filename));
3
		$added = date("m/d/Y", $parts[0]);
4
		$origName = $parts[1];

Nachdem wir den Zeitstempelwert als eigene Zeichenfolge haben, können wir ihn in ein Datum formatieren und den ursprünglichen Dateinamen als eigene Variable speichern.
Die von PHP bereitgestellte Dateigrößenfunktion gibt die Größe der Datei nur in Bytes zurück, sodass wir sie mit der Funktion formatBytes, die in Kürze behandelt wird, in eine besser lesbare Form formatieren.

1
2
		$filetype = getFileType(substr($file, strlen($file) - 3));
3
        $uploaded_files .= "<li class=\"$filetype\"><a href=\"$filename\">$origName</a> $size - $added</li>\n";

Beim Hochladen einer Datei auf den Server stellt PHP uns die Dateitypinformationen zur Verfügung. Da wir diese Informationen jedoch nicht speichern können, müssen wir versuchen, den Dateityp mit einer benutzerdefinierten Funktion abzurufen.
Ich gebe der getFileType-Funktion (später gezeigt) die drei letzten Zeichen des Dateinamens als Parameter. Ich verwende die Dateitypvariable, um die verschiedenen Dateien mit CSS zu formatieren.
Jetzt müssen Sie nur noch eine HTML-Zeichenfolge generieren, diese in die Variable uploaded_files einfügen und das Ordnerhandle schließen.

1
2
	}
3
}
4
closedir($dh);
1
2
if(strlen($uploaded_files) == 0)
3
{
4
	$uploaded_files = "<li><em>No files found</em></li>";
5
}

Wenn keine Dateien gefunden wurden, setzen Sie die Variable uploaded_files so, dass eine Nachricht angezeigt wird.

Wir müssen auch die Zeichenfolge uploaded_files irgendwo anzeigen. Fügen Sie diese Zeile in das <ul> mit der ID 'files' ein.

1
2
<?php echo $uploaded_files; ?>

Schritt 6 - Hilfsfunktion

Die Funktion getFileType versucht zu erraten, um welchen Typ es sich bei der Datei handelt, indem sie die letzten Zeichen ihres Namens liest. Das funktioniert nicht mit Erweiterungen wie .jpeg und .tiff.
Um es universeller zu gestalten, müssten wir einen Teilstring lesen, der am Punkt beginnt und bis zum Ende des Dateinamens reicht.
Aber wenn der Name so etwas wie my.new.car.pic ist, bekommen wir new.car.pic als Erweiterung.
Damit das wirklich funktioniert, müssten wir den letzten Punkt im Namen finden und von da an einen Teilstring nehmen.
Für den Umfang dieses Tutorials ist dies jedoch nah genug.

1
2
function getFileType($extension)
3
{
4
	$images = array('jpg', 'gif', 'png', 'bmp');
5
	$docs 	= array('txt', 'rtf', 'doc');
6
	$apps 	= array('zip', 'rar', 'exe');
7
	
8
	if(in_array($extension, $images)) return "Images";
9
	if(in_array($extension, $docs)) return "Documents";
10
	if(in_array($extension, $apps)) return "Applications";
11
	return "";
12
}

Diese nächste Funktion formatiert die Bytes in ein besser lesbares Format. Nur einfache Mathematik - nichts weiter. Die Funktion selbst stammt aus den PHP.net-Funktionskommentaren.

1
2
function formatBytes($bytes, $precision = 2) { 
3
    $units = array('B', 'KB', 'MB', 'GB', 'TB'); 
4
   
5
    $bytes = max($bytes, 0); 
6
    $pow = floor(($bytes ? log($bytes) : 0) / log(1024)); 
7
    $pow = min($pow, count($units) - 1); 
8
   
9
    $bytes /= pow(1024, $pow); 
10
   
11
    return round($bytes, $precision) . ' ' . $units[$pow]; 
12
} 
13
?>

Und das war's für den PHP-Teil. Nur noch ein paar JS und CSS und wir sind alle fertig.

Schritt 7 - Ein Hauch von CSS für mehr Lesbarkeit

Wie wir bisher haben, sollte aussehen:

Um die Funktion getFileType und den zurückgegebenen Klassennamen gut nutzen zu können, habe ich die nächsten Zeilen von CSS in die Datei style.css eingefügt.

1
2
ul#files li a
3
{
4
	text-decoration: none;
5
	color: #3564a9;
6
	padding: 2px 25px;
7
	background-position: left;
8
	background-repeat: no-repeat;
9
}
10
11
ul#files li.Documents a
12
{
13
	background-image: url('../images/text.jpg');
14
}
15
16
ul#files li.Images a
17
{
18
	background-image: url('../images/picture.jpg');
19
}
20
21
ul#files li.Applications a
22
{
23
	background-image: url('../images/zip.jpg');
24
}
25
26
p.error
27
{
28
	background-color: #fff7c0;
29
	border-bottom: 1px solid #efefef;
30
	font-weight: bold;
31
	color: #ff0000;
32
	padding: 6px;
33
}

Ich weise jedem Dateityp ein Symbol zu. Die Symbole, die ich verwendet habe, stammen aus der großartigen Sammlung unter http://www.famfamfam.com.
Was wir jetzt haben sollten, ist so etwas.

Ah, viel besser.

Schritt 8 - Umschalten der Dateisichtbarkeit mit jQuery

Lassen Sie uns abschließend einige zusätzliche Funktionen mit JavaScript hinzufügen. Erstellen Sie einen neuen Ordner mit dem Namen "js" und erstellen Sie in diesem Ordner eine neue Datei, filestorage.js.
Fügen Sie dann die folgende Zeile am Ende der HTML-Seite direkt vor dem </body>-Tag hinzu.

1
2
<script src="js/filestorage.js" />

Es wird empfohlen, diese Art von JS-Dateien ganz am Ende der Seite einzufügen, damit das Document Object Model (DOM) zuerst geladen werden kann.

1
2
function HideFiles(selector)
3
{
4
	//show all files

5
	if(selector === "All files")
6
	{
7
		$("#files > li").show();
8
		return true;
9
	}
10
	else
11
	{
12
		//show only the selected filetype

13
		$("#files > li").hide();
14
		$("#files > li." + selector).show();
15
		return true;
16
	}	
17
}

Die HideFiles-Funktion macht zwei Dinge. Wenn der Parameter-Selektor gleich 'Alle Dateien' ist, durchläuft die Funktion alle <li>-Elemente in den Dateien <ul> und macht sie sichtbar.
Wenn jedoch ein anderer Parameter angegeben wurde, verbirgt die Funktion alles und zeigt dann nur diejenigen mit demselben Klassennamen wie der Parameter an.

1
2
function prepareMenu()
3
{ 
4
	$("#menu li").click( 
5
		function () {            
6
			$("#menu li").each(
7
				function(){
8
					$(this).removeClass("active");
9
				}
10
			);
11
			$(this).addClass("active");
12
			HideFiles($(this).children().html());
13
	    return false;
14
	});
15
16
	//Select the first as default

17
	$("#menu li:first").click();
18
}

Die Funktion prepareMenu fügt dem Ereignis onClick im Menü <li> eine Funktion hinzu.
Entfernen Sie bei einem Klick die Klasse 'active' aus allen und fügen Sie sie dann zu der angeklickten hinzu. Rufen Sie die HideFiles-Funktion mit dem Text innerhalb des Elements innerhalb des angeklickten <li> auf.
Schließlich rufen wir das Ereignis onClick für das erste Menüelement auf, um sicherzustellen, dass es beim Laden der Seite als Standard ausgewählt ist.

1
2
$(document).ready(function()
3
{
4
	prepareMenu();
5
});

Vergessen Sie nicht, die Funktion prepareMenu aufzurufen, wenn die Seite geladen wird. Dies kann einfach erfolgen, indem Sie es wie oben gezeigt im Ready-Ereignis des Dokuments aufrufen.
Jetzt sollte das Menü "Schaltflächen" funktionieren und beim Klicken sollte sich die Liste der Dateien ändern.

Schritt 9 - Gratulieren Sie sich zu einem gut gemachten Job!

Das ist es! Sie sollten jetzt einen funktionierenden Online-Dateispeicher haben.
Denken Sie daran, einen "uploadFolder" zu erstellen und dessen CHMOD zu ändern, um Änderungen zu ermöglichen. Anweisungen hierzu finden Sie im gesamten Web und direkt bei Ihrem Hosting-Anbieter.

Das war ein Tutorial für die Anfänger. Hoffentlich war es tief genug, ohne zu erklärend zu sein.

Vielen Dank für das Lesen und bitte hinterlassen Sie einen Kommentar, wenn Sie Fragen haben.

  • Folgen Sie uns auf Twitter oder abonnieren Sie den NETTUTS RSS-Feed, um weitere tägliche Tipps und Artikel zur Webentwicklung zu erhalten.


Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.