Page 1 sur 2
Fichiers et boucles imbriquées
Posté : 28 nov. 2008, 17:00
par teknomaniak
Bonjour à tous,
Un petit probleme se pose, j'ai besoin de faire plusieurs fichiers texte se repartissant les villes de france (les villes venant d'une base de données) . Chaque fichier commencerait par 3 lettres. exemple : par.txt contiendrait "Parigné-le-pôlin","Parnay","Parassy"... et ainsi de suite pour les 3 premiere lettres de chaque ville. Faire 3 boucles foreach imbriquées serait la solution mais j'ai beaucoup^de mal à démarrer. Merci pour votre aide
Posté : 28 nov. 2008, 17:06
par jojolapine
Une question avant tout, pourquoi faire tout ces fichiers?
Posté : 28 nov. 2008, 17:07
par teknomaniak
Pour une autocompletion. Pour eviter trop d'interrogations à la bdd
Posté : 28 nov. 2008, 17:12
par Berzemus
C'est vrai qu'une bd c'est pas fait pour lire des données..
Posté : 28 nov. 2008, 17:17
par teknomaniak
La liste des villes fait environ 2mo. Si il y a 2000 connectés simultanés qui execute cette requete, haï le serveur. voici l'explication que j'ai eu.
Cette technique a été imposée, ce n'est pas un choix personnel.
Posté : 28 nov. 2008, 17:27
par jojolapine
Bon ben si on te dit "programme et tais-toi!" alors je te suggère pour ton problème un truc comme ça:
<?php
$sql="requête qui prend tout ORDER BY ville";
$debutTemp=null;
foreach($donnees as $entry){
$debut=substr($entry['ville'],0,3);
if($debutTemp!==$debut){//juste pour économiser un peu de ressources, on ferme que si on change de fichier
fclose($res);
unset($res);//là je suis plus bien sur si $res est toujours déclaré ou pas après...
}
if(!isset($res))
$res=fopen($debut.'.txt','a');
fwrite($res,'ceque tu veux');
$debutTemp=$debut;
}
?>
Après je pense que t'as interet à augmenter le time limit de php....

Posté : 28 nov. 2008, 17:28
par caroube
C'est sûr que si tu n'as pas le choix, c'est un peu galère.
Cela dit, 2000 connectés simultanément, ça veut dire 2000 interrogations à la base de données pendant les mêmes quelques dixième de seconde : le temps d'ouvrir la connexion, de faire le select, de récupérer le résultat et de le renvoyer au PHP.
C'est quoi comme site ? Les pages jaunes ? Parce que 2000 connexions en simultané, ça fait des centaines de milliers de pages vues par minute. A mon avis, ce n'est pas la base de données qui va se casser la gueule la première.
Bon, le problème est déplacé : il va y avoir 2000 connexions en simultané au système de fichiers.
Est-ce que tu peux aller en parler à celui qui t'a imposé ce choix
Bon, sinon pourquoi tu veux faire 3 boucles imbriquées. Pour faire tes fichiers, tu lis ta liste de villes, tu en extrait les 3 premières lettres (en tenant compte des accents) et tu les ajoutes au fichier XYZ.txt. Il n'y a qu'une seule boucle.
Posté : 28 nov. 2008, 18:06
par sadeq
Tu peux mettre toutes les villes dans un même fichier et chercher les valeurs pour l'auto-completion par une expression régulière selon le mot tapé.
Style :
preg_match_all("#^{$entry}[^\n]*\\n#im", $source, $matches);
où :
"#^{$entry}[^\n]*\\n# : est l'expression régulière qui cherche les textes commençant par la valeur d'une variable $entry et se terminant par retour chariot
Les paramètres:
i (pour ignorer la casse) et
m (pour explorer la source dans toutes les lignes)
$source : fichier contenant les noms des villes ligne par ligne
$matches : tableau obtenu contenant les résultats de la recherche.
Posté : 28 nov. 2008, 18:13
par AB
Cela dit, 2000 connectés simultanément, ça veut dire 2000 interrogations à la base de données pendant les mêmes quelques dixième de seconde : le temps d'ouvrir la connexion, de faire le select, de récupérer le résultat et de le renvoyer au PHP.
C'est quoi comme site ? Les pages jaunes ? Parce que 2000 connexions en simultané, ça fait des centaines de milliers de pages vues par minute. A mon avis, ce n'est pas la base de données qui va se casser la gueule la première.
++

Posté : 28 nov. 2008, 18:48
par teknomanik
le site est un site de petite annonces... bcp de monde... quand j'ai dis 2000 c'était juste..
Encore merci pour votre aide
Posté : 28 nov. 2008, 19:04
par caroube
OK, il y a beaucoup de monde. Il peut y avoir des milliers de personnes qui consultent le site simultanément. Ce n'est pas pour cela qu'elles sont connectées simultanément à la base. On n'est pas dans un système client-serveur classique où chaque utilisateur ouvre une session le matin, bosse sur cette session toute la journée et ferme la session à 18h.
Là, on a une connexion à la base uniquement le temps de récupérer l'info. Après, c'est terminé. En gros, les 2000 connexions simultanées, c'est si 2000 personnes cliquent sur le bouton "rechercher" dans le même dixième de secondes. Ce qui veut dire que statistiquement, tu as environ 20.000 visiteurs par seconde sur ton site. Je veux bien que ce soit un "gros" site, mais renseigne toi sur les stats de consultation. D'autre part, il me semble étonnant, pour un site aussi gros de ne pas mettre les moyens en base de données nécessaires.
Et d'autre part, comme je le signalais, aller lire environ 15.000 fichiers (26x26x26), s'il y a réellement 2000 requêtes simultanées, ce n'est pas sûr que le disque dur soit capable de suivre le ryhtme. Il va falloir que ta machine arrive à gérer simultanément 2000 handlers de fichiers, que ton contrôleur de disque suive et que les têtes de lectures pédalent à fond la caisse pour arriver à servir tout le monde. A mon avis, en période de pointe, c'est une solution encore pire que la base de données. J'espère que vous êtes en RAID, parce qu'il y a de la mort de disque dans l'air ...
Bon, cela dit, je ne suis ni à ta place, ni à celle de ton admin. Je fais juste remarquer que le problème demande un peu plus de réflexion et que sauter sur la première solution proposée n'est pas forcément un bon plan.
Idée : Cela vaut peut-être le coup de monter une deuxième base de données à côté uniquement pour l'autocomplétion. Après tout, les noms de ville, ça ne change pas tous les jours.
Posté : 01 déc. 2008, 11:07
par Invité
Bon ben si on te dit "programme et tais-toi!" alors je te suggère pour ton problème un truc comme ça:
<?php
$sql="requête qui prend tout ORDER BY ville";
$debutTemp=null;
foreach($donnees as $entry){
$debut=substr($entry['ville'],0,3);
if($debutTemp!==$debut){//juste pour économiser un peu de ressources, on ferme que si on change de fichier
fclose($res);
unset($res);//là je suis plus bien sur si $res est toujours déclaré ou pas après...
}
if(!isset($res))
$res=fopen($debut.'.txt','a');
fwrite($res,'ceque tu veux');
$debutTemp=$debut;
}
?>
Après je pense que t'as interet à augmenter le time limit de php....

Bonjour,
Ton script ne fonctionne pas comme j'aimerais. C'est à dire qu'il me crée un seul fichier avec les 3 premières lettres de la première ville. Dans ce fichier il y a la liste de toutes les villes. Voici mon code modifié:
$sql="select * from city ORDER BY cit_name";
$resultat=@mysql_query($sql);
$debutTemp=null;
while ($list=@mysql_fetch_array ($resultat, MYSQL_ASSOC))
{
$debut=substr($list['cit_name'],0,3);
if(!isset($res))
$res=fopen($debut.'.txt','a');
fwrite($res,$list['cit_name'].'\n');
$debutTemp=$debut;
if($debutTemp!==$debut){//juste pour économiser un peu de ressources, on ferme que si on change de fichier
fclose($res);
unset($res);//là je suis plus bien sur si $res est toujours déclaré ou pas après...
}
}
Posté : 01 déc. 2008, 11:08
par teknomaniak
Bon ben si on te dit "programme et tais-toi!" alors je te suggère pour ton problème un truc comme ça:
<?php
$sql="requête qui prend tout ORDER BY ville";
$debutTemp=null;
foreach($donnees as $entry){
$debut=substr($entry['ville'],0,3);
if($debutTemp!==$debut){//juste pour économiser un peu de ressources, on ferme que si on change de fichier
fclose($res);
unset($res);//là je suis plus bien sur si $res est toujours déclaré ou pas après...
}
if(!isset($res))
$res=fopen($debut.'.txt','a');
fwrite($res,'ceque tu veux');
$debutTemp=$debut;
}
?>
Après je pense que t'as interet à augmenter le time limit de php....

Bonjour,
Ton script ne fonctionne pas comme j'aimerais. C'est à dire qu'il me crée un seul fichier avec les 3 premières lettres de la première ville. Dans ce fichier il y a la liste de toutes les villes. Voici mon code modifié:
$sql="select * from city ORDER BY cit_name";
$resultat=@mysql_query($sql);
$debutTemp=null;
while ($list=@mysql_fetch_array ($resultat, MYSQL_ASSOC))
{
$debut=substr($list['cit_name'],0,3);
if(!isset($res))
$res=fopen($debut.'.txt','a');
fwrite($res,$list['cit_name'].'\n');
$debutTemp=$debut;
if($debutTemp!==$debut){//juste pour économiser un peu de ressources, on ferme que si on change de fichier
fclose($res);
unset($res);//là je suis plus bien sur si $res est toujours déclaré ou pas après...
}
}
Posté : 01 déc. 2008, 12:19
par jojolapine
Et où sont les différences?
Tu peux me le dire?
[Note : ce message a été posté de manière anonyme avant d'être réattribué à son auteur]
Posté : 01 déc. 2008, 13:00
par teknomaniak
Pas de différence.. simplement cela ne fonctionne pas...