TUTORIAL: 404 Sur la base Thumbnail Generator

  • joebert
  • Sledgehammer
  • Genius
  • No Avatar
  • Inscription: Fév 10, 2004
  • Messages: 13458
  • Loc: Florida
  • Status: Offline

Message Avril 20th, 2009, 9:47 pm

Introduction


Une erreur majeure certaines personnes font lors de la création d'un générateur automatique est aperçu qu'ils pointent leur vignette <img> éléments directement à leur script vignette. Cela fonctionne, mais elle oblige chaque demande vignette unique à passer par là [acronyme = Hypertext préprocesseur: 31d5ywk1] PHP [/acronym] script qui fait les frais généraux inutiles.

Une solution plus efficace consiste à créer un vrai "thumbnails" du dossier et configurer un gestionnaire d'erreur 404 qui tentera de générer des vignettes et cache à la volée avant de l'envoyer en fait un code d'état 404. De cette façon, les demandes très prochaine et l'avenir sera tout simplement contourner tous les scripts et retrouver l'image comme si son toujours été là.

Le code pour cela est en fait très simple. Le générateur miniature et le code pour la fixation d'un gestionnaire d'erreur 404 dans htaccess est inférieur à un
Code: [ Select ]
/backgrounds/cat-one/181ab7662fd27121c232eefeb319d4a9.jpg
/backgrounds/cat-two/181ab7662fd27121c232eefeb319d4a9.jpg
/thumbnails/
/thumbnails/.htaccess
/thumbnails/thumbnail.php
  1. /backgrounds/cat-one/181ab7662fd27121c232eefeb319d4a9.jpg
  2. /backgrounds/cat-two/181ab7662fd27121c232eefeb319d4a9.jpg
  3. /thumbnails/
  4. /thumbnails/.htaccess
  5. /thumbnails/thumbnail.php


Heres le contenu de htaccess dans le / thumbnails / répertoire.

APACHE Code: [ Select ]
RewriteEngine off
 
ErrorDocument 404 /thumbnails/thumbnail.php
  1. RewriteEngine off
  2.  
  3. ErrorDocument 404 /thumbnails/thumbnail.php


Et voici le sigle [= Hypertext préprocesseur: 31d5ywk1] PHP [/acronym] au sein de / thumbnails / miniatures. php

PHP Code: [ Select ]
<?php
if(preg_match('#^/?thumbnails/([a-z0-9-]+)/([a-f0-9]{32})\.jpg$#i', $_SERVER['REQUEST_URI'], $img))
{
    $cat        = $img[1];
    $img        = $img[2];
    $img_path   = "../backgrounds/$cat/$img.jpg";
   
    if(file_exists($img_path))
    {
        if(!is_dir($cat))
        {
            mkdir($cat);
        }
        $thumb_path = "$cat/$img.jpg";
       
        $image    = imagecreatefromjpeg($img_path);
        $new_image  = imagecreatetruecolor(167, 250);
        imagecopyresampled($new_image, $image, 0, 0, 0, 0, 167, 250, 320, 480);
        imagedestroy($image);
       
        imagejpeg($new_image, $thumb_path);
 
        header('HTTP/1.1 200'); // override the 404 response
        header('Content-Type: image/jpeg');
        flush(); @ob_flush();
        imagejpeg($new_image);
        flush(); @ob_flush();
        imagedestroy($new_image);
        exit;
    }
}
?>
  1. <?php
  2. if(preg_match('#^/?thumbnails/([a-z0-9-]+)/([a-f0-9]{32})\.jpg$#i', $_SERVER['REQUEST_URI'], $img))
  3. {
  4.     $cat        = $img[1];
  5.     $img        = $img[2];
  6.     $img_path   = "../backgrounds/$cat/$img.jpg";
  7.    
  8.     if(file_exists($img_path))
  9.     {
  10.         if(!is_dir($cat))
  11.         {
  12.             mkdir($cat);
  13.         }
  14.         $thumb_path = "$cat/$img.jpg";
  15.        
  16.         $image    = imagecreatefromjpeg($img_path);
  17.         $new_image  = imagecreatetruecolor(167, 250);
  18.         imagecopyresampled($new_image, $image, 0, 0, 0, 0, 167, 250, 320, 480);
  19.         imagedestroy($image);
  20.        
  21.         imagejpeg($new_image, $thumb_path);
  22.  
  23.         header('HTTP/1.1 200'); // override the 404 response
  24.         header('Content-Type: image/jpeg');
  25.         flush(); @ob_flush();
  26.         imagejpeg($new_image);
  27.         flush(); @ob_flush();
  28.         imagedestroy($new_image);
  29.         exit;
  30.     }
  31. }
  32. ?>



La partie htaccess


La partie htaccess est pretty straight forward.

APACHE Code: [ Select ]
RewriteEngine off
ErrorDocument 404 /thumbnails/thumbnail.php
  1. RewriteEngine off
  2. ErrorDocument 404 /thumbnails/thumbnail.php


Fondamentalement la première ligne désactive le mod_rewrite dans ce répertoire parce que son non nécessaires dans ce répertoire. Ce n'est pas quelque chose qui devoir être fait, mais si vous l'utilisez dans votre DocumentRoot, et sauf si vous comptez utiliser mod_rewrite ici plus tard, c'est une bonne idée de désactiver comme vous le feriez une lumière dans la chambre est une personne po

La deuxième ligne indique à Apache où aller si on ne peut pas trouver un fichier de n'importe où dans la / thumbnails / répertoire ou un sous-répertoires. Dans ce cas, le générateur de sa vignette.


La partie sécurité


Le script est enveloppé dans une instruction if qui vérifie la syntaxe de l'adresse demandée image.

PHP Code: [ Select ]
if(preg_match('#^/?thumbnails/([a-z0-9-]+)/([a-f0-9]{32})\.jpg$#i', $_SERVER['REQUEST_URI'], $img))
{
    //...
}
  1. if(preg_match('#^/?thumbnails/([a-z0-9-]+)/([a-f0-9]{32})\.jpg$#i', $_SERVER['REQUEST_URI'], $img))
  2. {
  3.     //...
  4. }


Dans mon cas, Im en utilisant un format très strictes pour mes images si Im en mesure d'utiliser un schéma très sécurisé avec preg_match pour s'assurer que le script n'est pas vulernable à tout type de [acronyme = Uniform Resource Indicator: 31d5ywk1] URI [/acronym] exploits d'injection. Cette partie du script, vous devrez modifier pour adapter votre schéma de nommage des fichiers.



Le fichier existe-t-elle


preg_match, en cas de succès, va me fournir avec l'apport propre je peux utiliser pour voir dans l'image Im créer une vignette pour l'existence même.

PHP Code: [ Select ]
    $cat        = $img[1];
    $img        = $img[2];
    $img_path   = "../backgrounds/$cat/$img.jpg";
   
    if(file_exists($img_path))
    {
        //...
    }
  1.     $cat        = $img[1];
  2.     $img        = $img[2];
  3.     $img_path   = "../backgrounds/$cat/$img.jpg";
  4.    
  5.     if(file_exists($img_path))
  6.     {
  7.         //...
  8.     }




Un nouveau sous-répertoire


Maintenant que je sais qu'il ya une image en taille maximale pour créer une miniature pour, je peux vérifier pour voir si un sous-répertoire de ce nom existe au sein de l'/ thumbnails / dossier et la créer si elle n'existe pas. Après quoi, je peux créer un chemin relatif thumbnail image de l'apport propre.

PHP Code: [ Select ]
        if(!is_dir($cat))
        {
            mkdir($cat);
        }
        $thumb_path = "$cat/$img.jpg";
  1.         if(!is_dir($cat))
  2.         {
  3.             mkdir($cat);
  4.         }
  5.         $thumb_path = "$cat/$img.jpg";



Générer la Miniature


Une fois Im sûr que l'image en taille maximale existe, que des theres un endroit pour mettre une vignette, et j'ai un chemin / nom de fichier pour enregistrer la vignette du titre je ne peux en arriver à générer la vignette.

PHP Code: [ Select ]
        $image    = imagecreatefromjpeg($img_path);
        $new_image  = imagecreatetruecolor(167, 250);
        imagecopyresampled($new_image, $image, 0, 0, 0, 0, 167, 250, 320, 480);
        imagedestroy($image);
  1.         $image    = imagecreatefromjpeg($img_path);
  2.         $new_image  = imagecreatetruecolor(167, 250);
  3.         imagecopyresampled($new_image, $image, 0, 0, 0, 0, 167, 250, 320, 480);
  4.         imagedestroy($image);


Beaucoup de scripts aperçu semblent pour stocker les largeurs et hauteurs variables, mais pour ce petit script simple, je mets juste les nombres depuis sa pas difficile de se rappeler ce qui est quoi dans cette situation.

Si vous vous souvenez que prend imagecreatetruecolor (largeur, hauteur), vous pouvez facilement dire lorsque la largeur / hauteur en arguments imagecopyresampled aller et si vous vous souvenez que les vignettes sont généralement plus petites que les images en taille maximale que vous pouvez voir où les images originales en largeur / hauteur de l'aller.


Cache Pour Plus Tard


Im not sure techniquement que ce soit en tant que cache réellement, ou si sa production seulement du contenu statique. Je la regarde tout simplement que les scripts de création de contenu automatique, mais je suppose que vous pouvez appeler ça comme vous voulez.

PHP Code: [ Select ]
        imagejpeg($new_image, $thumb_path);


Assez facile, il enregistre seulement l'image de la vignette générée pather plus tôt.
Notez que la vignette GD n'a pas encore été détruit, juste celui fullsized a fait.
Raison d'être nous avons encore besoin d'envoyer une copie de la vignette pour le navigateur et theres aucun sens de garder l'image fullsized autour de plus longtemps.


Oh Yeah, You Were Looking For Something


Maintenant que la vignette a été généré et sauvegardé, où les navigateurs pouvez juste aller directement à elle, plus tard, son temps d'envoyer l'image vers le navigateur qui a fait la demande pour déclencher ce script, en premier lieu.

PHP Code: [ Select ]
        header('HTTP/1.1 200');
        header('Content-Type: image/jpeg');
        flush(); @ob_flush();
        imagejpeg($new_image);
        flush(); @ob_flush();
        imagedestroy($new_image);
        exit;
  1.         header('HTTP/1.1 200');
  2.         header('Content-Type: image/jpeg');
  3.         flush(); @ob_flush();
  4.         imagejpeg($new_image);
  5.         flush(); @ob_flush();
  6.         imagedestroy($new_image);
  7.         exit;


Afin d'empêcher le navigateur de puisage, nous renvoyer une réponse HTTP 200 pour la demande. (merci effim)
Puis, comme Im en utilisant le [= acronyme de Joint Photographic Experts Group: 31d5ywk1] JPEG [/acronym] vignettes-je envoyer une simple image / jpeg type de contenu.
Next-je jeter les en-têtes vers le navigateur afin que le navigateur n'a pas besoin d'attendre l'acronyme [= Hypertext préprocesseur: 31d5ywk1] PHP [/acronym] tampon à remplir avec des données d'image avant d'envoyer cet en-tête.
Puis-je utiliser imagejpeg sans argument de nom de fichier afin qu'il décharge les données d'image directement au navigateur, après quoi je rincer à nouveau, puis finir par détruire les images ci-GD représentation en mémoire.


Conclusion


Le contenu statique est toujours servi plus vite que le contenu généré dynamiquement. Chaque fois que vous pouvez servir statiques au cours de sa bonne dynamique pour le faire, à tout moment vous pouvez vous éviter d'avoir à générer que du contenu statique manuellement est juste, bien, bien.

J'inclus en fait trois lignes de plus dans les copies de ce script que j'utilise vivre cette charge et de copier un filigrane sur les vignettes, mais mal congé à trouver comment faire que de vous. :D
Strong with this one, the sudo is.
  • Anonymous
  • Bot
  • No Avatar
  • Inscription: 25 Feb 2008
  • Messages: ?
  • Loc: Ozzuland
  • Status: Online

Message Avril 20th, 2009, 9:47 pm

  • effim
  • Beginner
  • Beginner
  • Avatar de l’utilisateur
  • Inscription: Avr 21, 2009
  • Messages: 35
  • Loc: Austin, TX
  • Status: Offline

Message Mai 7th, 2009, 9:37 am

En fait, thats une très mauvaise (bien que la recommandation de bonnes intentions). Codes d'état HTTP ont été mis en place pour une raison, et chaque fois que possible, le code d'état correct doit être signalé au navigateur / client. Lorsque vous signalez un 404, moteurs de recherche les ignorent, et je wouldnt être surpris si plus de quelques navigateurs mobiles laissé tomber la réponse (pas besoin de charger une page 404 pour une image).

Au lieu de cela, ce que vous devez faire pour votre suggestion viable consiste à utiliser une règle de réécriture qui réécrit seulement pour générer le script si le fichier n'existe pas.

APACHE Code: [ Select ]
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ thumbnails/thumbnail.php [NC,L]
  1. RewriteEngine On
  2. RewriteCond %{REQUEST_FILENAME} -s [OR]
  3. RewriteCond %{REQUEST_FILENAME} -l [OR]
  4. RewriteCond %{REQUEST_FILENAME} -d
  5. RewriteRule ^.*$ - [NC,L]
  6. RewriteRule ^.*$ thumbnails/thumbnail.php [NC,L]


Pour tous ceux qui ne connaissent pas, les lignes de chaque procédez comme suit:

Condition: Demande de nom de fichier est un fichier régulier avec> 0 octets, ou
Condition: Demande de nom de fichier est un lien symbolique, ou
Condition: Demande de nom de fichier est un répertoire,
Ne pas réécrire la requête. Halte à la réécriture.
Réécrire toutes les demandes d'/ thumbnails / thumbnail.php

;)
  • joebert
  • Sledgehammer
  • Genius
  • No Avatar
  • Inscription: Fév 10, 2004
  • Messages: 13458
  • Loc: Florida
  • Status: Offline

Message Mai 10th, 2009, 6:37 am

Je suis en désaccord.

RewriteRule que sera évalué pour chaque demande d'image.

Par la capture de la 404, et, en fait, générer un fichier statique lors de la demande, le pire scénario est que la première personne à voir l'image est une réponse 404 si theyre sur un navigateur qui bails. Les chances sont theyll juste actualiser la page ou l'image.

Chaque visiteur recevra l'image statique, sans aucune transformation RewriteRule.

Ive utilise cette technique depuis des mois sans aucun problème du tout. La première audience sur Safari-iPhone/iPod.
Strong with this one, the sudo is.
  • effim
  • Beginner
  • Beginner
  • Avatar de l’utilisateur
  • Inscription: Avr 21, 2009
  • Messages: 35
  • Loc: Austin, TX
  • Status: Offline

Message Mai 10th, 2009, 6:47 am

Cette règle de réécriture est effectivement parcourue pour chaque demande de chaque site Web qui utilise le Zend Framework MVC (thats a lot). Apache est très efficace à la manipulation réécrit, et si le fichier existe une seule condition de réécriture est évaluée, et le fichier ne thats exister. Theres vraiment pas beaucoup d'un coup aux performances. En fait, plus de theres un coup aux performances d'utilisation. Htaccess au lieu de mettre les règles de réécriture dans l'httpd. conf (dans le bon endroit, bien sûr) est que de courir le règles de réécriture.

Pour moi, la sémantique est très important. Im pas un die-hard, et le mauvais usage arbitraire div ici ou là quand il aide significannotly de style, mais j'essaie de créer chaque fois que la sémantique des systèmes possibles. Envoi d'une demande de 404 à un navigateur pour un fichier qui existe est une chose que je ressens est trop brouillon et corrigé en même temps, surtout quand une solution plus élégante existe.

Bien qu'il ne présente pas de criants problèmes du monde réel, je ne vois pas pourquoi on choisirait d'utiliser le 404 au cours de la réécriture de solution quand il n'y a pas un coup aux performances.
  • joebert
  • Sledgehammer
  • Genius
  • No Avatar
  • Inscription: Fév 10, 2004
  • Messages: 13458
  • Loc: Florida
  • Status: Offline

Message Mai 10th, 2009, 7:51 am

Je pense effectivement l'aide de la réécriture est la méthode sloppy moi-même. Surtout quand quelque chose conçu pour la manutention 404 sorties d'erreurs.
Im allant de s'en tenir à l'aide d'un gestionnaire 404 pour, à la manipulation des erreurs 404.

Je vais écouter sur le code d'état si, Ive a ajouté un header () en ligne pour s'assurer que le script renvoie un code 200 d'état avec l'image. :)

PHP Code: [ Select ]
header('HTTP/1.1 200'); // override the 404 response
Strong with this one, the sudo is.

Afficher de l'information

  • Total des messages de ce sujet: 5 messages
  • Modérateur: Tutorial Writers
  • Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 2 invités
  • Vous ne pouvez pas poster de nouveaux sujets
  • Vous ne pouvez pas répondre aux sujets
  • Vous ne pouvez pas éditer vos messages
  • Vous ne pouvez pas supprimer vos messages
  • Vous ne pouvez pas joindre des fichiers
 
 

© 2011 Unmelted, LLC. Ozzu® est une marque déposée de Unmelted, LLC