Fichiers et boucles imbriquées

teknomaniak
Invité n'ayant pas de compte PHPfrance

28 nov. 2008, 17:00

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

ViPHP
ViPHP | 3607 Messages

28 nov. 2008, 17:06

Une question avant tout, pourquoi faire tout ces fichiers?

teknomaniak
Invité n'ayant pas de compte PHPfrance

28 nov. 2008, 17:07

Pour une autocompletion. Pour eviter trop d'interrogations à la bdd

ViPHP
ViPHP | 4039 Messages

28 nov. 2008, 17:12

C'est vrai qu'une bd c'est pas fait pour lire des données..
Mais qu'importe. (je suis ici - dernier petit projet)
Berze going social.

teknomaniak
Invité n'ayant pas de compte PHPfrance

28 nov. 2008, 17:17

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.

ViPHP
ViPHP | 3607 Messages

28 nov. 2008, 17:27

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.... :roll:
Modifié en dernier par jojolapine le 28 nov. 2008, 17:31, modifié 1 fois.

Eléphant du PHP | 422 Messages

28 nov. 2008, 17:28

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.

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

28 nov. 2008, 18:06

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.
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

ViPHP
AB
ViPHP | 5818 Messages

28 nov. 2008, 18:13

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.
++ :lol:

teknomanik
Invité n'ayant pas de compte PHPfrance

28 nov. 2008, 18:48

le site est un site de petite annonces... bcp de monde... quand j'ai dis 2000 c'était juste..

Encore merci pour votre aide

Eléphant du PHP | 422 Messages

28 nov. 2008, 19:04

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.

Invité
Invité n'ayant pas de compte PHPfrance

01 déc. 2008, 11:07

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.... :roll:

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...
     }
}

teknomaniak
Invité n'ayant pas de compte PHPfrance

01 déc. 2008, 11:08

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.... :roll:

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...
     }
}

ViPHP
ViPHP | 3607 Messages

01 déc. 2008, 12:19

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]

teknomaniak
Invité n'ayant pas de compte PHPfrance

01 déc. 2008, 13:00

Pas de différence.. simplement cela ne fonctionne pas...