Controle d'une boucle

Le
Phil Pavans
Bonjour,


J'utilise cette boucle pour lire un certain dossier des fichiers images afin
que :
1- le fichier s'inscrive dans une base de données
2- se crée une vignette avec le suffixe "_th"

voici la boucle :


while ($filext = readdir($dir)) {
$filea = str_replace(".jpg", "", $filext);
$file = str_replace(".JPG", "", $filea);
if (($filext!=".")&&($filext!="..")){
// Affichage du nom du fichier (ou sous-répertoire)
echo "$file<br>";
$thumb = $file.'_th.jpg';
echo "$thumb<br>";
$sql = "INSERT INTO photos ( ID , fichier , commentaire , keywords ,
annee ) VALUES ('', '$file' , '$comment' , '$keyw' , '$an')";
$req = mysql_query($sql);
$filin = $homedir.'/'.$filext;
$thumbout = $homedir.'/'.$thumb;
redimensionneImage($filin,$thumbout,100,67);
}
}


Je m'attendais à ce que la boucle relise à l'infini les fichiers de vignette
qu'elle crée mais en fait cela fonctionnait assez bien comme ça tant que je
n'èxécutais cette boucle que sur un petit nombre de fichier (environ 30).
Lorsque j'ai fait l'expérience sur un dossier de 100 images c'est la cata !
ça crée des _th_th_th_th_th à l'infini jusqu'à expiration du temps
serveur.
Je souhaitais donc mettre une condition en if à ajouter à

if (($filext!=".")&&($filext!=".."))

quelque chose comme :
if (($filext!=".")&&($filext!="..")&&($filext != "%_th%"))

qui intégre le suffixe _th comme condition de non-inscription dans la base
et de non-création de vignette

mais cette condition ne fonctionne pas

pourriez vous m'aider à formuler cela ?


Merci.

phil pavans
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Guillaume Bouchard
Le #768169
Phil Pavans wrote:
Bonjour,


Bonjour.

J'utilise cette boucle pour lire un certain dossier des fichiers images afin
que :
1- le fichier s'inscrive dans une base de données
2- se crée une vignette avec le suffixe "_th"


name_th.ext ou name.ext_th ?
Je te conseille la première solution car il vaut mieux que l'extension
colle à ce qui est dedans.

while ($filext = readdir($dir)) {


D'apres la doc php il ne faudrait pas procéder de cette façon, mais
plutôt comme ceci :

while ( false !== ($filext = readdir($dir))){


$filea = str_replace(".jpg", "", $filext);
$file = str_replace(".JPG", "", $filea);
if (($filext!=".")&&($filext!="..")){


J'aime aussi

if(!in_array($fileext,array('.','..'))){
$thumb = $file.'_th.jpg';


Ce qui repond à ma première question.

$sql = "INSERT INTO photos ( ID , fichier , commentaire , keywords ,
annee ) VALUES ('', '$file' , '$comment' , '$keyw' , '$an')";


Je suppose que tu as bien protégé ta requete SQL de la façon adéquat.

$req = mysql_query($sql);


Il faut toujours tester le retour des requetes SQL :

$req = mysql_query($sql) or die(mysql_error().$sql);


Je m'attendais à ce que la boucle relise à l'infini les fichiers de vignette
qu'elle crée mais en fait cela fonctionnait assez bien comme ça tant que je
n'èxécutais cette boucle que sur un petit nombre de fichier (environ 30).
Lorsque j'ai fait l'expérience sur un dossier de 100 images c'est la cata !
ça crée des _th_th_th_th_th ... à l'infini jusqu'à expiration du temps
serveur.


Cela semble logique, je ne connais pas comment php implemente cela, mais
cela doit surement être un peu prés comme cela:

Lecture du repertoire, si nombre de fichier petit -> On stocke toutes la
liste en memoire (c'est plus rapide pour la boucle)
Si nombre de fichier grand, il doit relir le repertoire AMHA. Plus
d'acces disques, mais pas de surcharge de la mémoire.

Si quelqu'un pouvais confirmer mon hypothese, sinon j'irais esseyer de
trouver moi même dans le code source, avec mon niveau en C qui tend vers
zero.

Je souhaitais donc mettre une condition en if... à ajouter à

if (($filext!=".")&&($filext!=".."))

quelque chose comme :
if (($filext!=".")&&($filext!="..")&&($filext != "%_th%"))


Normal, tu utilises des % qui n'existent pas pour la comparaison basique
de chaines en php. Il va te faloir utiliser une fonction de gestion de
chaine :

http://fr3.php.net/manual/fr/ref.strings.php

jete on oeil du coté de strpos AMHA. (Je ne me souviens jamais du nom de
chaques fonctions ainsi que de l'ordre des arguments, et j'ai pas le
courage de chercher ;o)

--
Guillaume.

bruno modulix
Le #768170
Phil Pavans wrote:
Bonjour,


J'utilise cette boucle pour lire un certain dossier des fichiers images afin
que :
1- le fichier s'inscrive dans une base de données
2- se crée une vignette avec le suffixe "_th"

voici la boucle :

while ($filext = readdir($dir)) {
$filea = str_replace(".jpg", "", $filext);
$file = str_replace(".JPG", "", $filea);


Pourquoi passer par autant de variables intermédiaires ?


if (($filext!=".")&&($filext!="..")){


Ce test devrait être avant les deux lignes précédentes... Ca ne sert à
rien de faire des str_replace() si le résultat n'est pas utilisé.

// Affichage du nom du fichier (ou sous-répertoire)
echo "$file<br>";
$thumb = $file.'_th.jpg';


Et s'il y a un fichier .txt ou .machin ou .bidule ??? Et si c'est un
sous-répertoire ? Et si c'est n'importe quoi d'autre qu'un fichier
régulier ?

echo "$thumb<br>";
$sql = "INSERT INTO photos ( ID , fichier , commentaire , keywords ,
annee ) VALUES ('', '$file' , '$comment' , '$keyw' , '$an')";


D'une part, PAQJS, l'interpolation ne fonctionne pas dans les chaines à
guillemets simples.

D'autre part, forcer l'interpolation pour des variables qui sont déjà
des chaînes est généralement inutile.

Enfin, les id auto, c'est bien, mais ça empêche d'utiliser la clé
primaire comme mécanisme empêchant la duplication d'informations (en
l'occurrence, pour ce que je vois, rien n'empêche d'avoir 400 fois le
même fichier référencé dans la base)

$req = mysql_query($sql);


Et si la requête échoue ?

$filin = $homedir.'/'.$filext;
$thumbout = $homedir.'/'.$thumb;
redimensionneImage($filin,$thumbout,100,67);


Et si redimensionneImage() échoue ?

}
}


Je m'attendais à ce que la boucle relise à l'infini les fichiers de vignette
qu'elle crée mais en fait cela fonctionnait assez bien comme ça tant que je
n'èxécutais cette boucle que sur un petit nombre de fichier (environ 30).
Lorsque j'ai fait l'expérience sur un dossier de 100 images c'est la cata !


Eh oui... C'est ça le problème avec la programmation accidentelle...

["programmation accidentelle" :
le programme 'tombe en marche', mais on ne sait pas pourquoi. Ce qui est
certain, c'est qu'un jour il tombera en panne, et on ne saura toujours
pas pourquoi, puisqu'on ne savait pas pourquoi il semblait fonctionner.
]

ça crée des _th_th_th_th_th ... à l'infini jusqu'à expiration du temps
serveur.


De toutes façons, modifier durant l'itération la séquence sur laquelle
on itère est généralement un bon moyen de se tirer une balle dans le pied...

Je souhaitais donc mettre une condition en if... à ajouter à

if (($filext!=".")&&($filext!=".."))

quelque chose comme :
if (($filext!=".")&&($filext!="..")&&($filext != "%_th%"))

qui intégre le suffixe _th comme condition de non-inscription dans la base
et de non-création de vignette

mais cette condition ne fonctionne pas


Si si, elle 'fonctionne'. Elle teste si le fichier s'appelle %_th%. Si
un fichier s'appelle %_th%, il ne sera pas traité.

pourriez vous m'aider à formuler cela ?


regarde du côté de:
substr()
fnmatch()
glob()
is_file()

etc...

Par ailleurs, un moyen simple d'éviter pas mal de problèmes est de
d'abord lister les fichiers à traiter (dans un tableau par exemple), et
seulement ensuite de faire le traitement.

--
bruno desthuilliers
ruby -e "print ''.split('@').collect{|p|
p.split('.').collect{|w| w.reverse}.join('.')}.join('@')"

John GALLET
Le #767901
Bonjour,

1- le fichier s'inscrive dans une base de données
2- se crée une vignette avec le suffixe "_th"
Ok. Combien de fois par fichier ? Une seule ça devrait suffire non ? Parce

que là si tu appelles 10 fois ton script, même avec 1 seule photo, tu vas
avoir 10 fois cette photo dans la table.

while ($filext = readdir($dir)) {
Je n'ai pas joué avec readdir depuis au moins deux ans. Donc bêtement, je

décroche le maneul et je lis :

http://fr2.php.net/readdir
Please note the fashion in which readdir()'s return value is checked in
the examples below.


Example 1. List all files in a directory
<?php
// Note that !== did not exist until 4.0.0-RC2

if ($handle = opendir('/path/to/files')) {
echo "Directory handle: $handlen";
echo "Files:n";
/* This is the correct way to loop over the directory. */
while (false !== ($file = readdir($handle))) {
echo "$filen";

/* This is the WRONG way to loop over the directory. */
while ($file = readdir($handle)) {
echo "$filen";
}
closedir($handle);
}
?>


$sql = "INSERT INTO photos ( ID , fichier , commentaire , keywords ,
annee ) VALUES ('', '$file' , '$comment' , '$keyw' ,'$an')";

Ah, les autoincrement ont encore frappé. Si tu déterminais une vraie clef
primaire sur cette table (au hasard : le nom du fichier, son MD5...) tu
pourrais tenter l'insert, et si la base de renvoie "duplicate key", ça
veut dire que tu as déjà cet enregistrement. Donc que tu n'as rien à
faire. Sinon, il faut peut-être générer le thumb associé. Trois solutions
: la première, d'embarquer le nom du thumb en clef unique (oui je suis
fainéant),la deuxième, avant de tenter cet insert, il faut savoir si on
est déjà en train de traiter le fichier ou son thumb (donc conventions de
nommage), la troisième de mettre les thumb dans un autre répertoire.


Je m'attendais à ce que la boucle relise à l'infini les fichiers de
vignette qu'elle crée


Ca dépend de beaucoup de facteurs, et en particulier du cache interne
d'accès au stat du filesystem. Comme tu crées alors que tu lis le
répertoire, si on a fait un snapshot du répertoire en début et qu'on lit
le snap, on ne voit pas les nouvaeux fichiers. Si on va régulièrement
relire le répertoire, et qu'on relit les nouveaux fichiers, boucle
infinie. C'est donc cohérent avec le fait que sur peu de fichiers, totu
soit en mémoire donc aps de boucle infinie, sur beaucoup, on ne bufferise
pas tout le contenu du réperoire donc on boucle.

Je conseille d'ailleurs toujours un petit appel explicite à
clearstatcache() avant le opendir().

a++;
JG

Phil Pavans
Le #767893
Merci à tous.

Bruno m'a démasqué facilement : je ne suis qu'un bricoleur de code, mais je
progresse grâce à vous tous.

A bientôt sans doute ! ;-)
Publicité
Poster une réponse
Anonyme