PHP Developer Forum Hier habt ihr die Möglichkeit, eure Skriptprobleme mit anderen Anwendern zu diskutieren. Seid so fair und beantwortet auch Fragen von anderen Anwendern. Dieses Forum ist sowohl für ANFÄNGER als auch für PHP-Profis! Fragen zu Laravel, YII oder anderen PHP-Frameworks. |
 |
|

09-11-2008, 22:02
|
jmc
PHP Junior
|
|
Registriert seit: Mar 2006
Beiträge: 868
|
|
PHP-Kompression mit vielen Dateien
Ich habe mir da in einer Gallerie ziemlich viele Bilder geladen werden müssen eine Datei geschrieben, die die Bilder komprimieren sollte.
Dies funktioniert bei 1-10 Bildern auch ganz gut, aber wenn es dann so 50 Bilder sind oder sogar mehr werden scheinbar nur zufällig einige Bilder geladen und andere nicht.
Es scheint an der Kompression zu liegen, denn wenn die Bilder nicht kompirimiert werden funktioniert alles super.
Gibt es einen Weg diesen Fehler zu umgehen?
meine Datei für die Bilder-komprimierung:
PHP-Code:
<?
error_reporting(E_ALL);
ob_start("ob_gzhandler");
if(isset($_GET['i']) && preg_match("/^[a-z0-9_-]+\.[a-z0-9]{3}$/i", $_GET['i']) && file_exists("./img/" . $_GET['i'])){
$ext = strtolower(substr($_GET['i'], -3));
switch($ext){
case "jpg":
$im = imagecreatefromjpeg("./img/" . $_GET['i']);
header("Content-type:image/jpeg");
imagejpeg($im, NULL, 96);
imagedestroy($im);
break;
case "gif":
$im = imagecreatefromgif("./img/" . $_GET['i']);
header("Content-type:image/gif");
imagegif($im);
imagedestroy($im);
break;
case "png":
$im = imagecreatefrompng("./img/" . $_GET['i']);
header("Content-type: image/png");
imagepng($im);
imagedestroy($im);
break;
}
}
header("Content-Length:" . ob_get_length());
?>
|

09-11-2008, 23:57
|
 |
onemorenerd
 Moderator
|
|
Registriert seit: Mar 2005
Ort: Berlin
Beiträge: 9.471
|
|
Was soll das bringen? JPG, GIF und PNG sind allesamt komprimierte Formate.
|

11-11-2008, 14:49
|
jmc
PHP Junior
|
|
Registriert seit: Mar 2006
Beiträge: 868
|
|
Und trotzdem können sie noch weiter komprimiert werden.
Dadurch werden durchschnittlich 15- 20% weniger Daten übertragen.
|

11-11-2008, 14:52
|
pekka
PHP Master
|
|
Registriert seit: Jun 2001
Ort: Köln
Beiträge: 6.608
|
|
Zitat:
Original geschrieben von jmc
Und trotzdem können sie noch weiter komprimiert werden.
Dadurch werden durchschnittlich 15- 20% weniger Daten übertragen.
|
Das mag zum Teil stimmen - meine Erfahrung mit JPG, MP3 und Konsorten sagt eher das Gegenteil -, aber der dafür nötige Prozessoraufwand steht in keinem Verhältnis zum Ergebnis.
|

11-11-2008, 15:36
|
 |
onemorenerd
 Moderator
|
|
Registriert seit: Mar 2005
Ort: Berlin
Beiträge: 9.471
|
|
@jmc: Wenn das Messwerte sind, dann hast du schlecht optimierte Grafiken. Wenn es Schätzungen sind, dann miss mal.
|

12-11-2008, 21:06
|
jmc
PHP Junior
|
|
Registriert seit: Mar 2006
Beiträge: 868
|
|
Es sind Messwerte und ich bin nicht derjenige, der die Bilder Dateigrösse der Bilder optimiert. (Der Server gehört ist gemietet.. da kann mir egal sein wie stark der CPU belastet wird  )
|

12-11-2008, 21:58
|
 |
onemorenerd
 Moderator
|
|
Registriert seit: Mar 2005
Ort: Berlin
Beiträge: 9.471
|
|
Das kann ich kaum glauben. Deshalb habe ich es selbst probiert und meine Messungen widersprechen dir völlig. Ich habe so gut wie gar keine Abweichungen zwischen unbehandelten und gzip-ten Bildern.
Zum Nachvollziehen: Ich habe 5 zufällige Wörter gegoogelt, jeweils einen beliebigen Treffer geöffnet, Datei > Seite speichern unter, Webseite komplett.
Dann das Verzeichnis geöffnet, alles gelöscht, was nich GIF, PNG oder JPEG ist.
Und so siehts aus:
$ du -hs pics*
476K pics1
2,8M pics2
308K pics3
504K pics4
188K pics5
$ gzip -r pics*
$ du -hs pics*
472K pics1
2,3M pics2
304K pics3
496K pics4
140K pics5
Der Effekt von gzip über den Daumen gepeilt:
pics1 1%
pics2 18%
pics3 1%
pics4 1,5%
pics5 20%
Das macht im Schnitt nur 8,3% weniger Datenmenge durch GZip-Kompression. Die Spitzenwerte von 1% zeigen, dass man die Bilder in sich schon so optimal komprimiert speichern kann, dass erneutes Komprimieren fast keinen Effekt hat.
|

12-11-2008, 22:21
|
ghostgambler
Master 
|
|
Registriert seit: Jul 2004
Ort: DE - NRW
Beiträge: 4.620
|
|
Wie gut, dass hier alle an der Lösung des Problems interessiert sind...
|

12-11-2008, 22:46
|
pekka
PHP Master
|
|
Registriert seit: Jun 2001
Ort: Köln
Beiträge: 6.608
|
|
Zitat:
Original geschrieben von jmc
(Der Server gehört ist gemietet.. da kann mir egal sein wie stark der CPU belastet wird )
|
Öh... Schon mal darüber nachgedacht, daß die CPU-Belastung unmittelbar damit zu tun haben könnte, daß er die Bilder nicht ausgeliefert kriegt?
Zitat:
Wie gut, dass hier alle an der Lösung des Problems interessiert sind...
|
Sind wir. Kompression ausschalten, Problem gelöst.
|

12-11-2008, 23:13
|
jmc
PHP Junior
|
|
Registriert seit: Mar 2006
Beiträge: 868
|
|
Ich weiss wirklich nicht genau woran es liegt, aber es liegt klar an der Enzahl der Dateien, nicht an der Grösse der Dateien. Deswegen vermute ich auch, dass trotz einer grossen Belastung für den CCPU nicht das das Problem ist.
Ausserdem wären es bei dir eher 14.2% von der Datenmenge her
(3767kb : 4343kb). Bei meinen Messungen auf der Seite mit auch mehr oder weniger zufällig hochgeladenen Bildern (da nicht von mir sondern von Benutzern hochgeladen) sind momentan bei 19.3% weniger Daten bei der komprimierten Übertragung.
|

13-11-2008, 02:58
|
 |
onemorenerd
 Moderator
|
|
Registriert seit: Mar 2005
Ort: Berlin
Beiträge: 9.471
|
|
Versuche es mal so ...
PHP-Code:
function fail() { header('HTTP/1.0 404 Not Found'); exit; }
@($fn = $_GET['i']) or fail();
if ($pos = strrpos($fn, '.') && file_exists($fn)) {
$ext = strtolower(substr($fn, $pos+1));
header('Content-type: image/' . $ext);
$img = file_get_contents($fn);
$img_comp = ob_gzhandler($img, PHP_OUTPUT_HANDLER_START | PHP_OUTPUT_HANDLER_END);
if ($img_comp !== FALSE) {
header('Content-Length: ' . strlen($img_comp));
echo $img_comp;
} else {
header('Content-Length: ' . strlen($img));
echo $img;
}
}
Geändert von onemorenerd (13-11-2008 um 03:01 Uhr)
|

13-11-2008, 19:26
|
jmc
PHP Junior
|
|
Registriert seit: Mar 2006
Beiträge: 868
|
|
Vielen Dank!!!
Jetzt noch einen 304-header senden und es klappt prima.
Ich habe 2 Tests gemacht. 122 Bilder an 8.4 MB in 7.1 Sekunden ohne Fehler 84 Bilder an 158.2MB in 119.2 Sekunden ohne Fehler.
Der Prozessor scheint also wirklich nicht das Problem gewesen zu sein. Mich macht das nun wirklich neugierig woran es denn sonst liegen könnte. Liegt das an der GD-Lib? Meine Art die Bilder zu öffnen und auszugeben ist tatsächlich ziemlich *** muss ich im Nachhinein eingestehen.
|

13-11-2008, 19:32
|
 |
onemorenerd
 Moderator
|
|
Registriert seit: Mar 2005
Ort: Berlin
Beiträge: 9.471
|
|
Ich weiß auch nicht, ob es an den image-Funktionen lag. Die verbrauchen jedenfalls eine Menge Speicher, was in deinem Fall völlig überflüssig war, da du die Bilder gar nicht manipulierst. Bei großen Bildern erreicht man schnell das memory_limit.
Du solltest dir übrigens noch ein paar Gedanken über die Sicherheit dieser Methode machen.
|

14-11-2008, 10:11
|
jmc
PHP Junior
|
|
Registriert seit: Mar 2006
Beiträge: 868
|
|
Da ich nicht genau deine Version nehme sondern wiederum alle Zeichen ausser [a-z0-9_-]+\.(?:jpeg|jpg|gif|png) nicht zulasse sollte es meines Erachtens relativ sicher sein, aber du kannst mir gerne erklären, was da das Problem ist.
Zuerst wollte ich mit dieser Datei die Bilder auch noch temporär verkleinern lassen (deswegen sind die imagecreatefrom da hängen geblieben), aber ich habe dann ziemlich schnell eingesehen, dass dies zu aufwendig ist  .
Ich benutze ausserdem statt file_get_contents fread, das wenn man schon auf die performance achtet noch einiges besser ist.
|

14-11-2008, 11:40
|
 |
onemorenerd
 Moderator
|
|
Registriert seit: Mar 2005
Ort: Berlin
Beiträge: 9.471
|
|
Zitat:
Original geschrieben von jmc
Da ich nicht genau deine Version nehme sondern wiederum alle Zeichen ausser [a-z0-9_-]+\.(?:jpeg|jpg|gif|png) nicht zulasse sollte es meines Erachtens relativ sicher sein, aber du kannst mir gerne erklären, was da das Problem ist.
|
Passt schon.
Zitat:
Ich benutze ausserdem statt file_get_contents fread, das wenn man schon auf die performance achtet noch einiges besser ist.
|
http://benchmark.nophia.de/benchmarks-dateioperationen-k-3-inhalt-einer-datei-einlesen-grosse-datei-72kb-b-14.html#auswertung
|
Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
|
|
Themen-Optionen |
|
Thema bewerten |
|
Forumregeln
|
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.
HTML-Code ist aus.
|
|
|
|
PHP News
|