Message d'erreur et d'attente pendant exécution d'un script

Résolu/Fermé
emrh Messages postés 427 Date d'inscription mardi 9 décembre 2014 Statut Membre Dernière intervention 9 avril 2024 - 16 janv. 2023 à 09:04
emrh Messages postés 427 Date d'inscription mardi 9 décembre 2014 Statut Membre Dernière intervention 9 avril 2024 - 16 janv. 2023 à 12:36

Bonjour à tous,

Dans le cadre d'un album photo familial, j'affiche des photos miniatures d'un répertoire pour pouvoir cliquer dessus et les agrandir (fancybox). Le script que j'ai écrit vérifie que chaque agrandissement dispose de sa miniature pour l'afficher, si ce n'est pas le cas il créé la miniature. Tout fonctionne parfaitement quand j'ajoute une vingtaine de photos (14 secondes de traitement qd même) mais quand je tombe sur un répertoire de 200 photos (oui, certains mois je prenais plus de photos que d'autres ! :-) j'ai ce message : 

Fatal error: Maximum execution time of 30 seconds exceeded in /var/www/html/PHOTOS/2010/2/index.php on line 118

(Si je relance 5 fois la page j'obtiens à la fin la numérisation des 200 photos qd même).

J'ai donc deux questions : 

1. Comment éviter ce message ? 
2. Comment avertir l'utilisateur (si ce n'est pas moi) que le site n'est pas planté ? (Message d'attente) 

Merci d'avance pour vos suggestions !

<?php

// Récupération du nom du répertoire courant : 
$courant = basename(dirname($_SERVER['SCRIPT_NAME']));
$an = basename(dirname(__DIR__, 1));
// Création d'un array mois : 
$mois = array('1'=>'JANVIER','2'=>'FEVRIER','3'=>'MARS','4'=>'AVRIL','5'=>'MAI','6'=>'JUIN','7'=>'JUILLET','8'=>'AOUT','9'=>'SEPTEMBRE','10'=>'OCTOBRE','11'=>'NOVEMBRE','12'=>'DECEMBRE');


// Générateur de miniatures : 
const IMAGE_HANDLERS = [
    IMAGETYPE_JPEG => [
        'load' => 'imagecreatefromjpeg',
        'save' => 'imagejpeg',
        'quality' => 100
    ],
    IMAGETYPE_PNG => [
        'load' => 'imagecreatefrompng',
        'save' => 'imagepng',
        'quality' => 0
    ],
    IMAGETYPE_GIF => [
        'load' => 'imagecreatefromgif',
        'save' => 'imagegif'
    ]
];

function createThumbnail($src, $dest, $targetWidth, $targetHeight = null) {

    // 1. Load the image from the given $src
    // - see if the file actually exists
    // - check if it's of a valid image type
    // - load the image resource

    // get the type of the image
    // we need the type to determine the correct loader
    $type = exif_imagetype($src);

    // if no valid type or no handler found -> exit
    if (!$type || !IMAGE_HANDLERS[$type]) {
        return null;
    }

    // load the image with the correct loader
    $image = call_user_func(IMAGE_HANDLERS[$type]['load'], $src);

    // no image found at supplied location -> exit
    if (!$image) {
        return null;
    }


    // 2. Create a thumbnail and resize the loaded $image
    // - get the image dimensions
    // - define the output size appropriately
    // - create a thumbnail based on that size
    // - set alpha transparency for GIFs and PNGs
    // - draw the final thumbnail

    // get original image width and height
    $width = imagesx($image);
    $height = imagesy($image);

    // maintain aspect ratio when no height set
    if ($targetHeight == null) {

        // get width to height ratio
        $ratio = $width / $height;

        // if is portrait
        // use ratio to scale height to fit in square
        if ($width > $height) {
            $targetHeight = floor($targetWidth / $ratio);
        }
        // if is landscape
        // use ratio to scale width to fit in square
        else {
            $targetHeight = $targetWidth;
            $targetWidth = floor($targetWidth * $ratio);
        }
    }

    // create duplicate image based on calculated target size
    $thumbnail = imagecreatetruecolor($targetWidth, $targetHeight);

    // set transparency options for GIFs and PNGs
    if ($type == IMAGETYPE_GIF || $type == IMAGETYPE_PNG) {

        // make image transparent
        imagecolortransparent(
            $thumbnail,
            imagecolorallocate($thumbnail, 0, 0, 0)
        );

        // additional settings for PNGs
        if ($type == IMAGETYPE_PNG) {
            imagealphablending($thumbnail, false);
            imagesavealpha($thumbnail, true);
        }
    }

    // copy entire source image to duplicate image and resize
    imagecopyresampled(
        $thumbnail,
        $image,
        0, 0, 0, 0,
        $targetWidth, $targetHeight,
        $width, $height
    );


    // 3. Save the $thumbnail to disk
    // - call the correct save method
    // - set the correct quality level

    // save the duplicate version of the image to disk
    return call_user_func(
        IMAGE_HANDLERS[$type]['save'],
        $thumbnail,
        $dest,
        IMAGE_HANDLERS[$type]['quality']
    );
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    
    
    <link rel="icon" href="img/favicon.ico" type="image/x-icon" />
    <link rel="shortcut icon" href="img/favicon.ico" type="image/x-icon" />

    <link rel="stylesheet" type="text/css" href="../../resources/style.css" />
    <script type="text/javascript" src="../../js/jquery-1.2.3.pack.js"></script>
    <script type="text/javascript" src="../../js/jquery.fancybox-1.0.0.js"></script>
    
    <script type="text/javascript">
       
      $(function(){
          
         $(".photo-link").fancybox({ 'zoomSpeedIn': 500, 'zoomSpeedOut': 500, 'overlayShow': true }); 
         
     });
      
 </script>
 
 
 <title>PHOTOS</title>
 
</head>
<body>

	<div id="page-wrap">
		<h1><?php echo '<a href="../index.php">' . $an . '</a> / '  . $mois[$courant] . ' ' . $an;?></h1>

       <?php
       /* Réglages */
       $photos = array();
       $miniatures = array();
       $count = 0;
       $nbre_photos = 0;		
		$image_dir = getcwd(); // Répertoire courant 
		$per_column = 6;
		
		// Lecture du répertoire courant + création d'un array du contenu : 
		if ($handle = opendir($image_dir)) {
			while (false !== ($file = readdir($handle))){
                // On ne prend que les jpg et les png :
				if(strtolower(pathinfo($file, PATHINFO_EXTENSION))=='jpg' OR strtolower(pathinfo($file, PATHINFO_EXTENSION))=='png'){
                    // Le fichier est-il une photo ?				
					if(!strstr($file,'-thumb')){					
						$photos[] = $file;
                        $nbre_photos = $nbre_photos + 1;
                    }
                    // Le fichier est une miniature : 
                    elseif(strstr($file,'-thumb')){
                        $miniatures[] = $file;
                    }
                }
            }
            closedir($handle);
            if(isset($photos)){
                sort($photos);                
                /*echo '<pre>';print_r($photos);echo '</pre>';
                echo $nbre_photos . '<br>';*/
            }
            if(isset($miniatures)){
                sort($miniatures);
                /*echo '<pre>';print_r($miniatures);echo '</pre>';  */      
            }
            
            // Étape 3 : Boucle de création de la gallerie :
            for ($i=0; $i < $nbre_photos; $i++) {
                // Vérification de l'existance de la miniature :
                if(!in_array(pathinfo($photos[$i], PATHINFO_FILENAME) . '-thumb.jpg',$miniatures)){
                    // Appel de la fonction pour créer la miniature manquante :
                    createThumbnail($photos[$i], pathinfo($photos[$i], PATHINFO_FILENAME) . '-thumb.jpg', 160);
                    // Ajout de la nouvelle miniature dans l'array $miniatures : 
                    array_push($miniatures,pathinfo($photos[$i], PATHINFO_FILENAME) . '-thumb.jpg');
                }
                echo '<a class="photo-link" rel="one-big-group" href="' . $photos[$i] . '"><img src="' . $miniatures[$i] . '" width="100" height="100" /></a>';
                $count++;
                if($count % $per_column == 0) { echo '<div class="clear"></div>'; }
            }
        }
        else
        {
            echo '<p>Il n\'y a pas de photos dans ce répertoire.</p>';
        }
        ?>	
    </div>
    

</body>

</html>


Linux / Chrome 109.0.0.0

A voir également:

2 réponses

jordane45 Messages postés 38346 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 16 décembre 2024 4 717
16 janv. 2023 à 09:11

Bonjour,

Alors, si .. le site ( du moins le script ) est planté ....  car il dépasse le délai maximum d'exécution défini sur ton serveur.

Heureusement pour toi, tu peux le modifier.

https://www.google.com/search?q=php+Maximum+execution+time


0
emrh Messages postés 427 Date d'inscription mardi 9 décembre 2014 Statut Membre Dernière intervention 9 avril 2024 20
16 janv. 2023 à 11:49

Génial Jordane, tu réponds à ma question n°1.
Grâce à : 

ini_set('max_execution_time', '300'); //300 seconds = 5 minutes

j'ai pu traiter un répertoire de 200 photos en une seule fois !

Que me conseilles tu pour montrer que la page n'est pas plantée ?
Par exemple une barre de progression ? Si oui, comment la faire apparaître à l'écran alors même que la page est en train de traiter les photos ? Devrais-je m'orienter plutôt vers un traitement JavaScript, ce qui permettrait au PHP de se charger en entier ?


 

0
jordane45 Messages postés 38346 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 16 décembre 2024 4 717
16 janv. 2023 à 12:20

Bonjour,

Une simple loader en gif  que tu affiches au début du script et que tu fermes lorsque le traitement est terminé devrait suffir.

1
emrh Messages postés 427 Date d'inscription mardi 9 décembre 2014 Statut Membre Dernière intervention 9 avril 2024 20 > jordane45 Messages postés 38346 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 16 décembre 2024
16 janv. 2023 à 12:36

Je vais regarder ça,
Merci beaucoup et bonne journée !

0