Der Upload von Bildern funktioniert nicht

Da offensichtlich immer wieder Probleme mit den Uploads in der JoomGallery auftauchen, die häufig auf zu große Upload-Dateien zurückzuführen sind, versuche ich an dieser Stelle eine kurze Erläuterung zu geben, die veranschaulichen soll, inwieweit über die Galerie-Einstellungen darauf Einfluß genommen werden kann (fast garnicht) und wieviel von den serverseitigen Einstellungen abhängt (fast alles).

Die JoomGallery ist wie fast alle Komponenten für Joomla! vorwiegend in der Scriptsprache PHP geschrieben. PHP wird serverseitig ausgeführt, d.h. alle Funktionen etc., die in den PHP-Scripten hinterlegt werden, müssen durch den Server, auf dem Eure Seiten liegen, abgearbeitet werden. Das ist anders als z.B. bei JavaScript, das clientseitig ausgeführt wird, also von dem Browser auf der Maschine zuhause.

Auf das Verhalten von JavaScript kann man ja auch Einfluß nehmen, es z.B. im Browser ausschalten. Das kann man mit PHP nicht! Einfluß auf die grundlegenden PHP-Einstellungen kann man nur direkt auf dem Server nehmen. Und zwar nur, wenn man über administrative Rechte auf dem Server verfügt.

Das hat nichts mit den Admin-Rechten unter Joomla! zu tun. Administrative Rechte oder auch Root-Rechte hat man auf dem Server nur, wenn einem der Server selbst gehört oder es sich um einen angemieteten Root-Server handelt. Alle PHP-relevanten Grundeinstellungen sind in einer Datei auf dem Server gespeichert, die php.ini heißt (wo sich diese Datei befindet, kann man unter Hilfe >> System Info >> PHP Information >> Loaded Configuration File ablesen).

Wie oben erwähnt, kommt man an diese Datei nur ran, wenn man Admin auf dem Server ist. Also in der Regel garnicht. Man kann sich aber anzeigen lassen, welche Einstellungen in der php.ini gemacht wurden. Dazu gibt es mehrere Möglichkeiten: die einfachste ist, im Backend von Joomla! unter Hilfe >> System Info >> PHP Information nachzusehen.

Man kann aber auch mit einem Editor eine Datei anlegen, die man z.B. info.php nennt und die folgenden Inhalt hat:

<?php
phpinfo();
?>

Diese Datei speichert man direkt im Joomla-Verzeichnis auf dem Server ab und ruft sie über den Browser auf. Die Ausgabe unterscheidet sich nur unwesentlich von der PHP-Info aus dem Joomla!-Backend. Auf jeden Fall kann man jetzt sehen, was vom Server-Admin bezüglich PHP alles festgelegt wurde. Und da kommen wir jetzt auf den Upload in der JoomGallery zurück.

Egal welchen Upload man in der JoomGallery wählt, alle unterliegen - da sie von PHP ausgeführt werden - mehr oder weniger diesen Einstellungen. Und davon gibt es eine Menge, die sich auch noch gegenseitig beinflussen können.

Ich werde im folgenden auf die einzelnen Einstellungen erklärend eingehen, aber vorab noch eine wichtige Bemerkung: im Configuration Manager der JoomGallery kann man unter Benutzer-Rechte Einstellungen bezüglich der Anzahl und der Dateigröße der hochzuladenden Bilder machen. Diese Einstellungen betreffen den Frontend-Upload und sind lediglich dazu gedacht, die User einzuschränken. Die Einstellungen überschreiben aber keinesfalls die oben beschriebenen PHP-Einstellungen. Man kann also dort nicht einfach eine riesige Dateigröße angeben und davon ausgehen, dass das dann auch klappen muß.

Sollte die entsprechende Einstellung in der php.ini bezüglich der Upload-Größe kleiner eingestellt sein, wird die Einstellung der JoomGallery wirkungslos.

Hier findet ihr eine Übersicht aller möglichen Einstellungen in der php.ini.
Hinweise:
In manchen Fällen ist in der Ausgabe Eurer php.ini eine Einstellung nicht aufgeführt. In diesem Fall gilt die sogenannte Standardeinstellung, die auch von der verwendeten PHP-Version abhängig ist.
Bei wenigen Providern besteht die Möglichkeit, über Ergänzungen in einer '.htaccess' Datei Einfluss auf wenige Einstellungen zu nehmen. Im Zweifelsfall fragt bitte dort nach, ob diese Option besteht. Wir können für diesen Sonderfall natürlich keinen Support geben.

Aber jetzt zu den für den Upload wichtigsten PHP-Einstellungen:

file_uploads
betroffene Uploads: Einzel, Batch, JAVA
file_uploads bestimmt, ob überhaupt Dateien über HTTP auf den Server geladen werden dürfen. Steht diese Einstellung auf OFF, geht - was den Upload betrifft - , garnichts.

upload_max_filesize
betroffene Uploads: Einzel, Batch, JAVA
upload_max_filesize bestimmt die maximale Größe, die eine hochgeladene Datei haben darf. Normalerweise wird dieser Wert in M angegeben, also in Megabyte. Bei dem Einzelbildupload und bei dem JAVA-Upload in der JoomGallery wird dieser Wert für jedes einzelne Bild herangezogen, da sie auch einzeln hochgeladen werden. Beim Batch-Upload hingegen wird die Größe des Zips betrachtet, was demnach schnell an die gesetzten Grenzen stoßen kann. Eigentlich sollte man denken, dass dieser Wert alleine für die uploadbare Größe ausschlaggebend ist. Das ist aber nicht so. Wie gesagt bedingen sich einzelne Einstellungen und wenn man größere Dateien hochladen will, so muß die folgende Einstellung auf upload_max_filesize abgestimmt sein.

post_max_size
betroffene Uploads: Einzel, Batch, JAVA
post_max_size bestimmt die maximale Größe von POST-Daten. In der Regel sind Datei-Uploads POST-Daten. Um größere Dateien hochzuladen, muss der Wert größer sein als upload_max_filesize.

memory_limit
betroffene Uploads: alle
memory_limit bestimmt den Maximalwert des Speichers, den ein Script bei der Erstellung des Detailbildes oder des Thumbnails verbrauchen darf. In der Regel wird der Wert in M (Beispiel: 32M) angegeben. Steht der Wert auf -1, ist kein Limit gesetzt. Das wird aber nur in seltenen Fällen so sein, weil dann der Server nicht mehr in der Lage ist, ein Script mit extrem hohen Speicherbedarf abzubrechen.
memory_limit ist von besonderer Bedeutung, da man nur näherungsweise absehen kann, wieviel Speicher beim Verarbeiten der Bilder wirklich benötigt wird.

Bei der Größenänderung durch die JoomGallery bzw. durch die GD-Bibliotheken kann man für die hochzuladenden Bilder den minimalen Verbrauch an virtuellem Speicher über folgende Formel errechnen:

Breite des Bildes in Pixel * Höhe des Bildes in Pixel * Bittiefe in Byte = Speicherbedarf in Byte

Es sind also die Abmessungen eines Bildes und die Bittiefe, die den Speicherbedarf bestimmen und nicht etwa die Größe des Bildes auf dem Datenträger! Nehmen wir an, wir würden ein Bild mit den Abmessungen 2272 Pixel mal 1704 Pixel und einer Bittiefe von 24 (24 Bit = 3 Byte) durch die Größenänderung jagen, dann ergäbe die Formel (2272 x 1704 x 3 = 11.614.464 Byte) einen Speicherbedarf von über 11 MB!

Recht einfach kann dieser Speicherbedarf schon lokal angezeigt werden, indem ein Bild in z.B. IrfanView geöffnet wird. Die Werte können dann in der Statusleiste abgelesen werden:

Bild-Daten Beispiel 1

Ein 8MP Bild (JPEG) belegt auf der Platte ca. 2,7 Megabyte. An Speicher werden aber über 23MB für das Bild allein benötigt.

Ein weiteres Beispiel einer 15MP Kamera:

Bild-Daten Beispiel 2


Wenn als Bildumwandler die GD2 (GDlib) benutzt wird, steigt der Speicherbedarf weiter an, da diese Bibliothek intern nicht mit 24 Bit pro Pixel (3 Byte), sondern mit 40 Bit arbeitet.

Für die beiden Beispiele heisst das:

1) 3504 x 2336 x 5 -> ca. 39 MByte
2) 3168 x 4752 x 5 -> ca. 71 MByte

Hier findet Ihr einen sehr guten Artikel, der dies genauer erklärt. Sehr interessant auch der Tipp, wenn möglich, ImageMagick als Bildbearbeiter zu verwenden. Das Programm 'convert' dieser Bibliothek wird durch die Speichergrenze in memory_limit nicht beeinflusst, da es als eigenständiges Programm nicht innerhalb von PHP arbeitet.

Bei aktivierter Option 'Generelle Einstellungen >> Bildmanipulation >> Schnellere Bildverkleinerung' steigt der Speicherbedarf für die Bildumwandlung um bis zu das Vierfache an. Wenn also Probleme mit dem Upload großer Bilder bestehen, schaltet zuerst diese Option aus.

Zusätzlich zu dem Speicherbedarf bei der Bildumwandlung müssen noch ungefähr 8-10MB für die PHP-Scripte von Joomla! und der JoomGallery hinzugerechnet werden. Steht memory_limit auf 16 MB kann keines der Beispielbilder vearbeitet werden!

Die letzten drei Einstellungen sind also wesentlich für den Dateiupload und sollten im Verhältnis memory_limit > post_max_size > upload_max_filesize stehen. Ist z.B. upload_max_filesize auf 2 M eingestellt, so darf man sich nicht wundern, wenn ein Batch-Upload mit einem zip von 4 MB Größe in die Hose geht, oder?

Aber diese drei Einstellungen sind nicht alleine verantwortlich dafür, ob der Dateiupload klappt. Es gibt eine weitere wichtige Einstellung, die trotz richtiger (großzügiger) Werte bei den drei vorangegangenen Einstellungen alles vermasseln kann:

max_execution_time
betroffene Uploads: alle
max_execution_time legt die maximale Zeit in Sekunden (bzw. Millisekunden!) fest, die ein Skript laufen darf, bevor der Server die Ausführung stoppt. Gerade beim Upload großer Batch-Dateien läuft das Script eine ganze Weile, weil das Zip erst hochgeladen und entpackt werden muss. Dann müssen noch die Kopiervorgänge und die Größenänderung durchgeführt werden.

Kommt dann noch eine langsame Internet-Verbindung hinzu, ist schnell Feierabend. Und da liegt auch der Hase im Pfeffer. Die Scripts der JoomGallery werden solange ausgeführt, bis sie an die gesetzten Grenzen der php.ini stoßen. So kommt es manchmal vor, dass einige Dateien aus einem Batch-zip verarbeitet werden und dann plötzlich Schluß ist.

Durch die schon erwähnte Option 'Generelle Einstellungen >> Bildmanipulation >> Schnellere Bildverkleinerung' kann die Bildverarbeitung beschleunigt werden. Bedenkt aber den damit zusammenhängenden Speicherbedarf.

Der Server bricht einfach die Aktion des Scripts ab. Entweder wird dann eine nichtssagende 500 Servermeldung angezeigt oder nur eine weisse Seite. Die wenigsten haben Zugriff auf die Logdateien des Servers, in der dann eine entsprechende Fehlermeldung hinterlegt wird. Darum sorgt ein solcher Fall auch für viel Verwirrung. Wir denken über Möglichkeiten nach, solche Abbrüche zu verhindern. Aber das gestaltet sich schwierig, weil die Verarbeitungszeit ncht einfach vorher berechnet werden kann.

Sonderfall 1&1
Einen Sonderfall bei den Uploadbeschränkungen stellen diverse Pakete von 1&1 dar. Die oben genannten Einstellungen in der php.ini sind in diesen Paketen absolut ausreichend gesetzt (max_execution_time 50000, max_filesize 8M, memory_limit 40M, post_max_size 8M, upload_max_filesize 20M), so dass es eigentlich nicht zu Abbrüchen kommen sollte.

Trotzdem erscheint beim Upload etwas größerer Bilder (etwa ab 400 KB) eine Fehlermeldung wie "Internal Server Error 500". Diese Fehlermeldung wird im Gegensatz zu den oben behandelten Fehlermeldungen nicht von PHP ausgegeben, sondern vom Server selbst, dem Apache. Und das heißt, dass in diesem Fall nicht die üblichen Verdächtigen, also die PHP-Einstellungen, die Ursache für den Abbruch sind, sondern die Einstellungen im Apache. Und die greifen unabhängig davon, welche PHP-Einstellungen gesetzt sind.

Laut 1&1-Support gibt es nur drei Ursachen für eine 500-Seite:

  1. das Skript startet mehr als 24 Prozesse auf dem Server
  2. die Prozessorzeit von 10 Sekunden wird überschritten oder
  3. der maximale virtuelle Speicher von 32 MB wird überschritten

zu 1: diese Ursache läßt sich ausschließen, da bei kleineren Bildern der Upload ja funktioniert und bei größeren ja nicht mehr Prozesse gestartet werden...

zu 2: bei der Prozessorzeit handelt es sich um etwas anderes als die max_execution_time! Die Prozessorzeit beschreibt die Zeit, die der Prozessor des Servers mit den Aufgaben beschäftigt ist, welche das Skript gerne von ihm abgearbeitet haben möchte. Dabei sind die 10 Sekunden relativ und beschreiben nur den Ernstfall der Vollauslastung des Prozessors. Demnach wird das Skript terminiert, wenn es den Prozessor länger als 10 Sekunden auf 100 Prozent Auslastung hält. Bei einer 10%-igen Auslastung des Servers über angenommene 2 Sekunden wäre die Prozessorzeit bei 0,2 Sekunden, bei einer 50%-tigen Auslastung über 10 Sekunden wäre die Prozessorzeit bei 5 Sekunden. Demnach ist es mit an Sicherheit grenzender Wahrscheinlichkeit unmöglich, dass dies die Ursache für den Abbruch ist. Denn solange dauert der Vorgang selbst bei großen Bildern nicht und der Upload selber beansprucht kaum Prozessorzeit.

zu 3: die JoomGallery nutzt z.Z. die GD, die GD2 und die ImageMagick-Bibliothek für die Manipulation der Bilder; zum Beispiel für die Verkleinerung auf Detail-Bildgröße oder auf Thumbnail-Bildgröße. Die GD funktioniert so leidlich. Die Qualität nimmt merklich ab, wenn man sie benutzt und außerdem benötigt sie enorme Speicher-Ressourcen. Aber sie wird auf fast allen Servern eingesetzt, da sie mittlerweile auch Bestandteil der PHP-Installation ist. Der Speicherbedarf beim Verkleinern der Bilder ist relativ groß und je größer die Bilder sind, umso mehr steigt er an. Aber dass er bei einem 400-KB-Bild über 32 Mb ansteigen soll, erscheint mir fast unmöglich und trotzdem scheint hier die Ursache des Problems zu liegen. Nach Auskunft einiger Anwender scheint diese Problem nicht mehr aufzutreten, wenn die ImageMagick als Bildbearbeiter ausgewählt ist.

Und was sagt uns das jetzt? An die Einstellungen des Apache kommt man natürlich noch weniger dran, als an die PHP-Einstellungen. Und nach meinem Kenntnisstand ist dieses Verhalten nur bei 1&1 bekannt und tritt - nach den Schilderungen diverser Benutzer in den einschlägigen Foren - auch bei Uploads anderer Galerien wie Zoom oder ICE regelmäßig auf. Es liegt also nicht an unseren Skripten, sondern vielmehr an den Vorgaben von 1&1. Die werden aber auch auf Bitte daran nix ändern. Da dieses Verhalten ausschließlich auf den 1&1-Servern auftritt, sehen wir uns auch nicht gezwungen, über unseren Code nachzudenken, nur um das 1&1-Problem zu umgehen.

Ich hoffe, dass dieser Beitrag ein wenig zum Verständnis der Vorgänge beim Upload durch die JoomGallery beiträgt. Wie Ihr seht, sind die Grenzen fast ausschließlich serverseitig gesetzt. Die Galerie hat keinen Einfluß auf die PHP-Einstellungen. Deswegen gibt es ja auch mittlerweile den FTP-Upload, der eigentlich nur noch durch max_execution_time ausgebremst werden kann und so die meisten Fallstricke bei den Einstellungen der php.ini umgeht.

Natürlich gibt es noch viele andere Faktoren, die einen Upload behindern können (wwwrun etc.). Aber darüber ein anderes Mal.

Joomla!®

Joomla! ist freie, unter der GNU/GPL-Lizenz veröffentlichte Software. Der Name Joomla! und das Logo werden unter einer limitierten Lizenz durch Open Source Matters als Rechteinhaber in den USA und anderen Staaten vergeben. Joom::Gallery ist weder Mitglied noch Teil des Joomla!-Projekts oder von Open Source Matters.