PHP Bildergalerie - Foto Upload und Mehrfach Upload
Autor
Flitze
Klicks 161708
Keywords:
PHP Bildergalerie Tutorial, PHP Bildergalerie erstellen, PHP MySQL Bildergalerie, PHP Thumbnails erstellen, PHP Bilder speichern, Tutorial PHP Bildergalerie, PHP Foto Upload, PHP Fotos hochladen, PHP mehrere Bilder hochladen, PHP .zip File, PHP gezippte Bilder hochladen
Klicks 161708
Rating für PHP Bildergalerie
7.6 von 10
Bewertungen118
Stand
08.10.2014
7.6 von 10
Bewertungen118
Keywords:
PHP Bildergalerie Tutorial, PHP Bildergalerie erstellen, PHP MySQL Bildergalerie, PHP Thumbnails erstellen, PHP Bilder speichern, Tutorial PHP Bildergalerie, PHP Foto Upload, PHP Fotos hochladen, PHP mehrere Bilder hochladen, PHP .zip File, PHP gezippte Bilder hochladen
Breadcrumb:
Workshops » PHP Bildergalerie » PHP Bildergalerie - Foto Upload und Mehrfach Upload
Verschiedene Upload-Möglichkeiten für Bilder
[ADSENSE_LINE]Bei vielen Bildern ist es schnell nervig, wenn man jedes Bild einzeln hochladen muss, deswegen stelle ich hier 2 Möglichkeiten vor, wie man mehrere Bilder auf einmal uploaden kann. Die erste Möglichkeit besteht darin, mehrere Uploadfelder zu erzeugen, so dass man mehrere Dateien auswählen kann. Der Quellcode orientiert sich stark an der add.php, also dem Skript zum Hochladen eines Fotos. Überzeugt euch selbstPHP:
<?php
error_reporting(E_ALL);
echo "<p style=\"font-weight:bold;\">Bereich: <span style=\"font-weight:italic;\">Mehrere Fotos hinzufügen</span></p>\n";
if(isset($_POST['submit']) AND $_POST['submit'] == "Upload") {
$errors = array();
if(!isset($_POST['Alben_ID'], $_POST['Beschreibung']))
$errors[] = "Bitte benutzen Sie das Formular aus dem <a href=\"index.php?s=foto_upload\">Foto Upload</a>.";
else{
if($_POST['Alben_ID']=="0")
$errors[] = "Bitte wählen Sie ein Album aus, in das die Foto gespeichert werden sollen.\n";
}
if(count($errors)){
echo "<p>\n".
"Die Fotos konnten nicht gespeichert werden.<br />\n";
foreach($errors as $error)
echo $error."<br />\n";
echo "</p>\n";
}
else{
for($i=1; $i<=10; $i++){
$errors = array();
$myFILE['name'] = $_FILES['Foto']['name'][$i];
$myFILE['type'] = $_FILES['Foto']['type'][$i];
$myFILE['tmp_name'] = $_FILES['Foto']['tmp_name'][$i];
$myFILE['error'] = $_FILES['Foto']['error'][$i];
$myFILE['size'] = $_FILES['Foto']['size'][$i];
$errors = checkUpload($myFILE, $_file_extensions, $_file_mime_types, FILE_SIZE, PIC_WIDTH, PIC_HEIGHT);
if(count($errors)){
echo "<p>\n".
"Das ".$i.". Foto (<span style=\"font-weight:bold;\">".$myFILE['name']."</span>) konnte nicht gespeichert werden.<br />\n";
foreach($errors as $error)
echo $error."<br />\n";
echo "</p>\n";
}
else {
do {
$Name = renameFile($myFILE['name']);
} while(file_exists(PIC_FOLDER."PIC_".$Name));
if (move_uploaded_file($myFILE['tmp_name'], PIC_FOLDER."PIC_".$Name)) {
// Thumbnail erstellen
createThumbnail(PIC_FOLDER."PIC_".$Name, TN_FOLDER, "TN_".$Name, TN_HEIGHT, TN_QUALI);
$sql = "INSERT INTO
Fotos
SET
Alben_ID = '".$_POST['Alben_ID']."',
Name = '".mysql_real_escape_string(trim("PIC_".$Name))."',
Beschreibung = '".mysql_real_escape_string(trim($_POST['Beschreibung'][$i]))."',
Datum = NOW()
";
mysql_query($sql) OR die("<pre>".$sql."</pre>".mysql_error());
echo "<p>\n".
"Das ".$i.". Foto (<span style=\"font-weight:bold;\">".$myFILE['name']."</span>) wurde erfolgreich gespeichert.<br />\n".
"</p>\n";
}
else {
echo "<p>\n";
echo "Es trat ein Fehler auf, bitte versuche es später erneut.<br />\n";
echo "Zurück zum <a href=\"index.php?s=foto_upload\">Foto Upload</a>\n";
echo "</p>\n";
}
}
}
}
}
else{
$sql = "SELECT
ID,
Name
FROM
Alben
";
$result = mysql_query($sql) OR die("<pre>".$sql."</pre>".mysql_error());
if(!mysql_num_rows($result)){
echo "<p>\n".
"Es existieren keine Alben, in denen Sie Fotos speichern können.\n";
"</p>\n";
}
else{
echo "<form ".
"action=\"index.php?s=foto_upload&action=add_multiple\" ".
"method=\"post\" ".
"enctype=\"multipart/form-data\" ".
"accept-charset=\"ISO-8859-1\">";
echo "<div>\n";
echo "<label for=\"Album\">Album</label>\n";
echo "<select name=\"Alben_ID\" id=\"Album\">\n";
echo " <option value=\"0\">Bitte ein Album wählen</option>\n";
while($row = mysql_fetch_assoc($result)){
echo "<option value=\"".$row['ID']."\">\n".
htmlentities($row['Name'], ENT_QUOTES)."\n".
"</option>\n";
}
echo "</select>\n";
echo "<br />\n";
echo "<input type=\"hidden\" name=\"MAX_FILE_SIZE\" value=\"".FILE_SIZE."\" />\n";
for($i=1; $i<=10; $i++){
echo "<label for=\"Foto[".$i."]\">Foto ".$i."</label>\n";
echo "<input id=\"Foto[".$i."]\" name=\"Foto[".$i."]\" type=\"file\" />\n";
echo "<br />\n";
echo "<label for=\"Beschreibung[".$i."]\">Beschreibung</label>\n";
echo "<input id=\"Beschreibung[".$i."]\" name=\"Beschreibung[".$i."]\" type=\"text\" maxlength=\"255\" />\n";
echo "<br />\n";
}
echo "<input type=\"submit\" name=\"submit\" value=\"Upload\" />\n";
echo "</div></form>\n";
}
}
?>
Im Eingabeformular habe ich schlichtweg folgende Schleife eingebaut:
PHP:
<?php
for($i=1; $i<=10; $i++){
echo "<label for=\"Foto[".$i."]\">Foto ".$i."</label>\n";
echo "<input id=\"Foto[".$i."]\" name=\"Foto[".$i."]\" type=\"file\" />\n";
echo "<br />\n";
echo "<label for=\"Beschreibung[".$i."]\">Beschreibung</label>\n";
echo "<input id=\"Beschreibung[".$i."]\" name=\"Beschreibung[".$i."]\" type=\"text\" maxlength=\"255\" />\n";
echo "<br />\n";
}
?>
Damit erzeuge ich mir statt einem Eingabefeld für Dateien derer 10. Die muss ich dann beim Verarbeiten auch wieder richtig zuteilen. Dabei ist zu beachten, dass das $_FILES Array leider so aufgebaut ist:
Code:
array(1) { ["Foto"]=> array(5) { ["name"]=> array(10) { [1]=> string(0) "" [2]=> string(0) "" [3]=> string(0) "" [4]=> string(0) "" [5]=> string(0) "" [6]=> string(0) "" [7]=> string(0) "" [8]=> string(0) "" [9]=> string(0) "" [10]=> string(0) "" } ["type"]=> array(10) { …
Das ist insofern ungünstig, da wir jedes Bild einzeln Testen wollen/müssen, um eine spezifische Fehlermeldung erstellen zu können. Deshalb setzen wir uns dieses Array unseren Zwecken gemäß zusammen:
PHP:
<?php
for($i=1; $i<=10; $i++){
$errors = array();
$myFILE['name'] = $_FILES['Foto']['name'][$i];
$myFILE['type'] = $_FILES['Foto']['type'][$i];
$myFILE['tmp_name'] = $_FILES['Foto']['tmp_name'][$i];
$myFILE['error'] = $_FILES['Foto']['error'][$i];
$myFILE['size'] = $_FILES['Foto']['size'][$i];
// ...
?>
Jetzt kann ich mit $myFILE genauso arbeiten wie beim Hochladen eines Fotos. Lediglich bei der Datenbankeingabe muss ich noch darauf achten, die richtige Beschreibung des Fotos zu speichern:
PHP:
<?php
$sql = "INSERT INTO
Fotos
SET
Alben_ID = '".$_POST['Alben_ID']."',
Name = '".mysql_real_escape_string(trim("PIC_".$Name))."',
Beschreibung = '".mysql_real_escape_string(trim($_POST['Beschreibung'][$i]))."',
Datum = NOW()
";
?>
Mehrere Bilder als Zip-Archiv hochladen
Die wahrscheinlich angenehmste Methode um schnell und mit wenig Aufwand viele Bilder auf den Webserver zu laden (in Zeiten der DSLR Fotografie sind ja viele Bilder keine Seltenheit mehr ). Man muss lediglich die gewünschten Bilder zippen und das Archiv hochladen, den Rest erledigt das Skript. Hier erstmal der Code als Ganzes, die einzelne Teile erkläre ich später nach und nach.PHP:
<?php
error_reporting(E_ALL);
include("pclzip.lib.php");
echo "<p style=\"font-weight:bold;\">Bereich: <span style=\"font-weight:italic;\">Zips im Zip-Archiv hinzufügen</span></p>\n";
if(isset($_POST['submit']) AND $_POST['submit'] == "Upload") {
$errors = array();
$myFILE = $_FILES['Zip'];
$errors = checkUpload($myFILE, $_zip_extensions, $_zip_mime_types, ZIP_SIZE);
if(!isset($_POST['Alben_ID']))
$errors[] = "Bitte benutzen Sie das Formular aus dem <a href=\"index.php?s=foto_upload\">Foto Upload</a>.";
else{
if($_POST['Alben_ID']=="0")
$errors[] = "Bitte wählen Sie ein Album aus, in das die Fotos gespeichert werden sollen.\n";
}
if(count($errors)){
echo "<p>\n".
"Das Zip-Archiv konnte nicht bearbeitet werden.<br />\n";
foreach($errors as $error)
echo $error."<br />\n";
echo "</p>\n";
}
else {
// Neues PclZip Objekt erstellen
$zip = new PclZip($myFILE['tmp_name']);
// Zip entpacken
if ($zip->extract(ZIP_FOLDER) == 0)
die("Error : ".$zip->errorInfo(true));
else{
// Alle Unterordner auflösen
moveWithoutStructure(ZIP_FOLDER, ZIP_FOLDER);
// Alle Dateien auslesen
$files = readDirectory(ZIP_FOLDER);
$i=0;
foreach($files as $file){
$errors = array();
$myFILE = array();
$size = @getImageSize(ZIP_FOLDER.$file);
$myFILE['name'] = $file;
$myFILE['type'] = isset($size['mime'])?$size['mime']:'';
$myFILE['tmp_name'] = ZIP_FOLDER.$file;
$myFILE['error'] = 0;
$myFILE['size'] = filesize(ZIP_FOLDER.$file);
$errors = checkUpload($myFILE, $_file_extensions, $_file_mime_types, FILE_SIZE, PIC_WIDTH, PIC_HEIGHT);
if(count($errors)){
echo "<p>\n".
"<span style=\"font-weight:bold;\">".$myFILE['name']."</span> konnte nicht gespeichert werden.<br />\n";
foreach($errors as $error)
echo $error."<br />\n";
echo "</p>\n";
}
else {
do {
$Name = renameFile($myFILE['name']);
} while(file_exists(PIC_FOLDER."PIC_".$Name));
copy(ZIP_FOLDER.$file, PIC_FOLDER."PIC_".$Name);
unlink(ZIP_FOLDER.$file);
createThumbnail(PIC_FOLDER."PIC_".$Name, TN_FOLDER, "TN_".$Name, TN_HEIGHT, TN_QUALI);
$sql = "INSERT INTO
Fotos
SET
Alben_ID = '".$_POST['Alben_ID']."',
Name = '".mysql_real_escape_string(trim("PIC_".$Name))."',
Beschreibung = '',
Datum = NOW()
";
mysql_query($sql) OR die("<pre>".$sql."</pre>".mysql_error());
echo "<p>\n".
"<span style=\"font-weight:bold;\">".$myFILE['name']."</span> wurde erfolgreich gespeichert.<br />\n".
"</p>\n";
$i++;
}
}
echo "Von ".count($files)." Dateien wurden ".$i." gespeichert.<br />\n";
}
}
}
else{
$sql = "SELECT
ID,
Name
FROM
Alben
";
$result = mysql_query($sql) OR die("<pre>".$sql."</pre>".mysql_error());
if(!mysql_num_rows($result)){
echo "<p>\n".
"Es existieren keine Alben, in denen Sie Fotos speichern können.\n";
"</p>\n";
}
else{
echo "<form ".
"action=\"index.php?s=foto_upload&action=add_zip\" ".
"method=\"post\" ".
"enctype=\"multipart/form-data\" ".
"accept-charset=\"ISO-8859-1\">";
echo "<div>\n";
echo "<label for=\"Album\">Album</label>\n";
echo "<select name=\"Alben_ID\" id=\"Album\">\n";
echo " <option value=\"0\">Bitte ein Album wählen</option>\n";
while($row = mysql_fetch_assoc($result)){
echo "<option value=\"".$row['ID']."\">\n".
htmlentities($row['Name'], ENT_QUOTES)."\n".
"</option>\n";
}
echo "</select>\n";
echo "<br />\n";
echo "<input type=\"hidden\" name=\"MAX_FILE_SIZE\" value=\"".ZIP_SIZE."\" />\n";
echo "<label for=\"Zip\">Zip Archiv</label>\n";
echo "<input id=\"Zip\" name=\"Zip\" type=\"file\" />\n";
echo "<br />\n";
echo "<input type=\"submit\" name=\"submit\" value=\"Upload\" />\n";
echo "</div></form>\n";
}
}
?>
Ich fange mal wieder mir dem Formular an. Daran wird gegenüber den vorigen Upload-Skripten kaum etwas verändert, ich setzte lediglich die MAX_FILE_SIZE auf die Konstante ZIP_SIZE aus unserer config.php und benutze den Namen 'Zip' statt 'Foto'.
Interessanter wird es dann bei der Verarbeitung. Zu Beginn fällt erstmal auf, dass ich eine weitere Datei inkludiere
PHP:
<?php
include("pclzip.lib.php");
?>
Diese Datei ermöglicht mir das entzippen von Archiven mit PHP. Ihr könnt sie von Php Concept downloaden. Theoretisch kann man zwar auch die internen Zip-Funktionen von PHP benutzen, aber ich habe z.B. die Erfahrung gemacht, dass mein Hoster mir den Zugriff auf diese Funktionen nicht erlaubt. Mit PclZip scheint er jedoch keine Probleme zu haben und außer dem inkludieren der oben genannten Datei ist keine weitere Systemveränderung nötig.
Bevor es jedoch ans Entzippen geht, prüfe ich erstmal den Upload. Dazu verwende ich wieder meine checkUpload()-Funktion und übergebe ihr diesmal die Zip-Konstanten und –Variablen. Danach entpacke ich das Archiv folgendermaßen:
PHP:
<?php
// Neues PclZip Objekt erstellen
$zip = new PclZip($myFILE['tmp_name']);
// Zip entpacken
if ($zip->extract(ZIP_FOLDER) == 0)
die("Error : ".$zip->errorInfo(true));
?>
Dabei wird der gesamte Inhalt des Archivs in den in der config.php festgelegten Ordner entpackt. Mehr PclZip brauchen wir dann auch nicht .
Nach dem erfolgreichen Entpacken stelle ich sicher, dass sich in meinem Zip-Verzeichnis keine weiteren Unterordner befinden bzw. löse diese auf. Daraufhin lasse ich mir den Inhalt des gesamten Verzeichnisses (d.h. die Namen aller Dateien) in dem Array $files speichern. Dazu benutze ich die beiden Funktionen moveWithoutStructure() und readDirectory().
PHP:
<?php
// Alle Unterordner auflösen
moveWithoutStructure(ZIP_FOLDER, ZIP_FOLDER);
// Alle Dateien auslesen
$files = readDirectory(ZIP_FOLDER);
?>
Diese beiden selbst definierten Funktionen haben folgenden Inhalt:
PHP:
<?php
function moveWithoutStructure($source, $target)
{
// prüfen ob ein '/' am Ende des Ordnernamens steht
if(substr($source,-1)!="/")
$source .= "/";
if(substr($target,-1)!="/")
$target .= "/";
if (!is_dir($source))
return false;
// Ordnerzeiger erstellen
$ordner = dir($source);
while ($datei=$ordner->read()){
if ($datei != '.' AND $datei != '..' ){
$Entry = $source.$datei;
// Funktion rekursiv auf alle Unterordner anwenden
if (is_dir($Entry)){
moveWithoutStructure($Entry, $target);
// Ordner löschen
rmdir($Entry);
}
elseif($source != $target){
// Datei in den Zielordner kopieren
copy($Entry, $target.$datei);
// Ursprungsdatei löschen
unlink($Entry);
}
}
}
$ordner->close();
return true;
}
function readDirectory($pfad)
{
if(substr($pfad,-1)!="/")
$pfad .= "/";
if(!is_dir($pfad))
return false;
$filesArr = array();
$ordner = dir($pfad);
while($datei = $ordner->read()) {
if($datei != "." AND $datei != "..") {
if(is_file($pfad.$datei))
$filesArr[] = $datei;
}
}
$ordner->close();
return $filesArr;
}
?>
So, damit stehen in meinem Zip-Verzeichnis also nur noch Dateien und keine Ordner mehr. Sämtliche Dateinamen stehen mir in $files zur Verfügung. Im nächsten Schritt überprüfe ich jede einzelne entpackte Datei, wozu ich erstmal wieder $myFILE 'herstelle'.
PHP:
<?php
$myFILE = array();
$size = @getImageSize(ZIP_FOLDER.$file);
$myFILE['name'] = $file;
$myFILE['type'] = isset($size['mime'])?$size['mime']:'';
$myFILE['tmp_name'] = ZIP_FOLDER.$file;
$myFILE['error'] = 0;
$myFILE['size'] = filesize(ZIP_FOLDER.$file);
?>
Da man den MIME-Type einer Datei gewöhnlicher Weise nur umständlich feststellen kann (und ich nicht garantieren kann, dass es auf allen Systeme funktioniert), beschränke ich mich auf Bilddateien. getImageSize() liefert mir nämlich freundlicher weise den MIME-Type einer Bilddatei. Alle anderen Dateien bekommen einen leeren String als MIME-Type und fallen somit durch die Prüfung, aber schließlich interessieren uns eh nur Bilddateien. Die Eigentliche Überprüfung erfolgt wieder mit checkUpload, auch wenn es sich streng genommen nicht mehr um einen Upload handelt .
Der Rest ist prinzipiell gleich wie zuvor. Allerdings benutze ich statt move_uploaded_file() die Funktionen copy() und unlink(), weil es sich ja, wie eben gesagt, nicht um ein 'geuploadetes' File handelt.
Das war’s auch schon. Thumbnailerstellung und Datenbankeintrag bleiben gleich (auch wenn ich keine Beschreibung einfüge) und am Ende wird noch ausgegeben, wie viele Dateien sich im Zip-Archiv befanden und wie viele davon gespeichert wurden.
Weiter geht’s jetzt mit der Anzeige der Bilder. Bearbeiten und Löschen werden wir die einzelnen Bilder direkt im Anzeigebereich, weil das übersichtlich ist als über eine Administrationsebene.
Zurück zur vorigen Seite:
PHP Bildergalerie - Thumbnails Weiter zur nächsten Seite:
PHP Bildergalerie - Bilderausgabe