Ich schreib das mal hier rein, da ich denke, dass ich ein ähnliches Problem habe.
Vorweg möchte ich erwähnen, dass ich php gerade erst lerne und ich ein Script mit verschiedenen Tutorials und dem php-Manual geschrieben habe.
Aufgabe des Scripts ist es, eine ziemlich große Menge (zwischen 800 und 1500) von Bildern zu verkleinern, verschieben und anschließend eine Zip-Datei zu erstellen.
Ich poste das Script erst mal und gehe dann genauer darauf ein:
PHP-Code:
<?php
error_reporting(E_ALL);
ini_set('display_errors','On');
if (function_exists('ini_get') && ini_get('date.timezone') == '') {
ini_set('date.timezone', 'Europe/Berlin');
}
$script_start = time();
if( !ini_get('safe_mode') ){
set_time_limit(3600);
}
echo '<br />';
// Pfade
$absPath = $_SERVER['DOCUMENT_ROOT'];
$watchPath = $absPath . '/flo/'; // Pfad zum Watchfolder
$watchDir = $watchPath . '_watchFolder/'; // Ordnername (_watchFolder)
//####################################
// Mail-Variablen #
//####################################
$absender = "email@domain.de";
$empfaenger = $absender;
$mailbetreff = "aktualisierte Produktbilder";
$mailnachricht = "\nDatum/Zeit: ";
$mailnachricht .= date("d.m.Y H:i:s")."\n\n";
$mailnachricht .= "Folgende Bilder wurden aktualisiert: \n\n";
//####################################
// BCC-Liste auslesen #
//####################################
$csv = fopen($watchPath . "Mailverteiler.csv", "r");
$bcc = '';
while ($array = fgetcsv($csv, 1024, ";")){
$bcc .= 'Bcc: ' . $array[2] . "\r\n"; //Mailadresse steht in der dritten Spalte der CSV-Datei
}
fclose ($csv);
//####################################
// Bildnamen ins $filaeArray #
//####################################
$fileArray = array();
$handle = opendir($watchDir);
$i=0;
while($file = readdir($handle)) {
if($file == "." || $file == "..") continue;
$fileArray[$i] = $file; // Bildnamen ins $fileArray schreiben
$mailnachricht .= $file . "\n"; //Dateien in den Mail-Text anhängen
$i++;
}
closedir($handle);
//####################################
// Backup vom Watchfolder #
//####################################
if (count($fileArray != 0)){
$timestamp = time();
$datum = date("Ymd",$timestamp);
$ordnername = $datum . '_watchFolder';
if (!is_dir($watchPath . $ordnername)){
if (!mkdir($ordnername, 0700)) echo 'Keinen Ordner erstellt! <br />';
for ( $i = 0; $i < count($fileArray); $i++){
copy($watchDir . $fileArray[$i], $watchPath . $ordnername . '/' . $fileArray[$i]);
}
} else {
echo 'Der Ordner ' . $ordnername . ' existiert bereits. <br />';
}
}
//####################################
// Daten-Array anlegen und fuellen #
//####################################
if($i!=0) {
$allArray = array();
// 1000 x 1000 - Info bereich
$allArray[0]['h'] = 1000;
$allArray[0]['w'] = 1000;
$allArray[0]['typ'] = 'jpg';
$allArray[0]['name'] = $allArray[0]['h'] . 'x' . $allArray[0]['w'] . '-' . $allArray[0]['typ'];
//600 x 600 - Store Categories - popup_images
$allArray[1]['h'] = 600;
$allArray[1]['w'] = 600;
$allArray[1]['typ'] = 'jpg';
$allArray[1]['name'] = $allArray[1]['h'] . 'x' . $allArray[1]['w'] . '-' . $allArray[1]['typ'];
// 370 x 370 - Store Categories - info_images
$allArray[2]['h'] = 370;
$allArray[2]['w'] = 370;
$allArray[2]['typ'] = 'jpg';
$allArray[2]['name'] = $allArray[2]['h'] . 'x' . $allArray[2]['w'] . '-' . $allArray[2]['typ'];
// 144 x 144 - Store Categories - thumbnail_images
$allArray[3]['h'] = 144;
$allArray[3]['w'] = 144;
$allArray[3]['typ'] = 'jpg';
$allArray[3]['name'] = $allArray[3]['h'] . 'x' . $allArray[3]['w'] . '-' . $allArray[3]['typ'];
// 370 x 370 - Store Products - info_images
$allArray[4]['h'] = 370;
$allArray[4]['w'] = 370;
$allArray[4]['typ'] = 'gif';
$allArray[4]['name'] = $allArray[4]['h'] . 'x' . $allArray[4]['w'] . '-' . $allArray[4]['typ'];
// 144 x 144 - Store Products - thumbnail_images
$allArray[5]['h'] = 144;
$allArray[5]['w'] = 144;
$allArray[5]['typ'] = 'gif';
$allArray[5]['name'] = $allArray[5]['h'] . 'x' . $allArray[5]['w'] . '-' . $allArray[5]['typ'];
//####################################
// Unterverzeichnisse anlegen #
//####################################
for ($i = 0; $i < count($allArray); $i++){
if (!is_dir($watchPath . $allArray[$i]['name'])){
if (!mkdir($watchPath . $allArray[$i]['name'], 0700)) echo 'Der Ordner: ' . $allArray[$i]['name'] . ' konnte nicht erstellt werden! <br />';
}
}
//####################################
// Bilder editieren und speichern #
//####################################
//require_once 'ProgressBar.class.php5'; // ProgressBar by David Bongard
//$bar = new ProgressBar();
//$elements = count($allArray) * count($fileArray); // Anzahl der Schleifendurchläufe
//$bar->initialize($elements); // Initialisieren und leeren Fortschrittsbalken anzeigen
for ($i = 0; $i < count($allArray); $i++){
for( $j = 0; $j < count($fileArray); $j++ ){
//echo '<div id="bar">Durchlauf: ' . $i . ' | Bild: ' . $j . '</div>';
$size = getimagesize($watchDir . $fileArray[$j]);
$w = $size[0]; // Width des Originalbildes
$h = $size[1]; // Height des Originalbildes
// Seitenverhaltnisse + Verkleinerung
if ($h >= $w) {
$wn = round($w/($h/$allArray[$i]['h']));
$hn = $allArray[$i]['h'];
} else {
$wn = $allArray[$i]['w'];
$hn = round($h/($w/$allArray[$i]['w']));
}
// Bilderstellung mit neuen Seitenverhaltnissen
$dst_img = ImageCreateTrueColor($wn,$hn);
$dst_body = imagecolorallocate( $dst_img, 255, 255, 255 );
imagefill( $dst_img,0,0,$dst_body );
$src_img = ImageCreateFromJpeg($watchDir . $fileArray[$j]);
ImageCopyResized($dst_img, $src_img, 0, 0, 0, 0, $wn, $hn ,$w ,$h); // ImageCopyResampled
// gif oder jpg schreiben
if ($allArray[$i]['typ'] == 'jpg'){
if($allArray[$i]['h'] == 1000){
imagejpeg($dst_img, $watchPath . $allArray[$i]['name'] . '/' . substr($fileArray[$j], 0, -4) . '.jpg');
} else {
imagejpeg($dst_img, $watchPath . $allArray[$i]['name'] . '/' . substr($fileArray[$j], 0, -8) . '.jpg');
}
} else {
imagegif($dst_img, $watchPath . $allArray[$i]['name'] . '/' . substr($fileArray[$j], 0, -4) . '.gif');
}
ImageDestroy($src_img);
ImageDestroy($dst_img);
//$bar->increase(); // Frotschrittsbalken
}
}
//####################################
// Watchfolder leeren #
//####################################
echo '<br />';
for ($i = 0; $i < count($fileArray); $i++){
if(!unlink($watchDir . $fileArray[$i])) {
echo 'Beim Loeschen der Datei '. $fileArray[$i] . ' trat ein Fehler auf! <br />';
}
}
//####################################
// Zip-Datei erstellen #
//####################################
$zip = $datum . 'Aktualisierungen.zip';
ob_start();
require('./zip.lib.php');
$zipfile = new zipfile($zip);
$zipfile->addDirContent('1000x1000-jpg/');
file_put_contents($zip, $zipfile->file());
//####################################
// Mail erstellen #
//####################################
$mailnachricht .= 'Sie koennen die Bilder direkt unter: http://www.domain.de/flo/' . $zip . ' als zip-Archiv herunterladen.' . "\n";
mail($empfaenger, $mailbetreff, $mailnachricht, $bcc . "From: ".$absender); // Mail generieren
} else {
echo 'Der Ordner <i>"'. $watchDir .'"</i> ist leer! Ich tu hier gar nichts<br />!';
mail($empfaenger, 'Cronejob - Done', 'Cronejob ausgeführt, keine neuen Bilder', "From: ".$absender); // Mail generieren
}
$end_time = time();
echo '<b>Erstellt in '.($end_time - $script_start).' Sekunden</b><br />';
?>
Da bei uns auf dem Server kein Safe-Mode aktiviert ist, habe ich die Laufzeit des Scripts einfach mal auf eine Stunde gestellt, um auszuschließen, dass es in einen timeout läuft.
PHP-Code:
$watchDir = $watchPath . '_watchFolder/'; // Ordnername (_watchFolder)
Dieser Ordner (_watchFolder) soll mit den Bildern befüllt werden (die Größe der Bilder ist in dem Ordner 1000x1000 px) und wenn keine Bilder drin sind, wird auch nichts weiter gemacht. Das Script soll täglich via Cronejob angestoßen werden.
Das wirkliche Problem tritt dann aber erst in den zwei for-Schleifen auf:
PHP-Code:
for ($i = 0; $i < count($allArray); $i++){
for( $j = 0; $j < count($fileArray); $j++ ){
//echo '<div id="bar">Durchlauf: ' . $i . ' | Bild: ' . $j . '</div>';
$size = getimagesize($watchDir . $fileArray[$j]);
$w = $size[0]; // Width des Originalbildes
$h = $size[1]; // Height des Originalbildes
// Seitenverhaltnisse + Verkleinerung
if ($h >= $w) {
$wn = round($w/($h/$allArray[$i]['h']));
$hn = $allArray[$i]['h'];
} else {
$wn = $allArray[$i]['w'];
$hn = round($h/($w/$allArray[$i]['w']));
}
// Bilderstellung mit neuen Seitenverhaltnissen
$dst_img = ImageCreateTrueColor($wn,$hn);
$dst_body = imagecolorallocate( $dst_img, 255, 255, 255 );
imagefill( $dst_img,0,0,$dst_body );
$src_img = ImageCreateFromJpeg($watchDir . $fileArray[$j]);
ImageCopyResized($dst_img, $src_img, 0, 0, 0, 0, $wn, $hn ,$w ,$h); // ImageCopyResampled
// gif oder jpg schreiben
if ($allArray[$i]['typ'] == 'jpg'){
if($allArray[$i]['h'] == 1000){
imagejpeg($dst_img, $watchPath . $allArray[$i]['name'] . '/' . substr($fileArray[$j], 0, -4) . '.jpg');
} else {
imagejpeg($dst_img, $watchPath . $allArray[$i]['name'] . '/' . substr($fileArray[$j], 0, -8) . '.jpg');
}
} else {
imagegif($dst_img, $watchPath . $allArray[$i]['name'] . '/' . substr($fileArray[$j], 0, -4) . '.gif');
}
ImageDestroy($src_img);
ImageDestroy($dst_img);
//$bar->increase(); // Frotschrittsbalken
}
}
Im XAMPP habe ich das Teil mit einer recht große Menge an Bildern getestet und es rennt problemlos durch, allerdings bekomme ich auf dem Webserver ab einer bestimmten Anzahl von Bildern (ab ca. 25 Bildern) eine "Error 500 - Internal server error" Fehlermeldung. Wenn ich statt ImageCopyResized ImageCopyResampled (was qualitativ eher mein Favorit wäre) nehme geschieht dies auch schon bei weniger Bildern.
Jetzt habe ich mich bei 1&1 erkundigt, die mir sagten, dass folgende Einstllungen zu berücksichtigen sind:
- Prozesse dürfen max. 10 Sekunden Rechenzeit beanspruchen
- Prozesse dürfen max. 32 MB Speicher belegen. Bei Verwendung von PHP5 40 MB Speicher.
- Es dürfen max. 12 Prozesse gleichzeitig laufen.
Also vermute ich, dass ich diese Beschrenkungen offensichtlich nicht einhalten kann und habe wieder nach diesem Problem gegoogled und öfter mal gelesen, dass man das besser programmieren muss um Resourcen zu sparen. Irgend was mit Script sich selbst aufrufen lassen und sich merken, wo man war etc. allerdings weiß ich absolut nicht, wie ich das bei mir umsetzen soll. Mein erster Versuch einfach alle Variablen als $_Session-Variablen anzulegen ist kläglich gescheitert.
Vielleicht kann mir hier noch jemand einen Hinweis geben, wie ich dieses Script so umschreiben kann, dass es nicht mittendrin einfach abbricht.
Für jeden weiteren Hinweis auf Tutorials und Tips wäre ich echt dankbar.
Gruß
Flo