IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PHP & Base de données Discussion :

[Sécurité] Arret d'un script au bout d'une heure


Sujet :

PHP & Base de données

  1. #1
    Nouveau membre du Club
    Inscrit en
    Mai 2004
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 39
    Points : 34
    Points
    34
    Par défaut [Sécurité] Arret d'un script au bout d'une heure
    Bonjour,

    J'ai un script faisant des traitements assez lourd ( recherche de doublons possibles sur une table Mysql client assez garnie ).
    Sur de petits traitement, cela fonctionne à merveille, mais lorsque je le passe sur une table plus importante, au bout d'une heure le navigateur me marque : impossible d'afficher la page.
    J'ai d'abord pensé que c'était le serveur qui coupait le script j'ai mis un set_time_limit() pour corriger le problème mais rien n'y fait.
    Une idée ?

    Merci d'avance

  2. #2
    Expert éminent Avatar de Mr N.
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    5 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 5 418
    Points : 6 449
    Points
    6 449
    Par défaut
    Euh... une heure pour faire une requète sql Tu es sur que ta requête est bonne ? des index sur tes tables bien placés ? analyze statement effectué ?

  3. #3
    Nouveau membre du Club
    Inscrit en
    Mai 2004
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 39
    Points : 34
    Points
    34
    Par défaut
    Il n'y a pas qu'une seule requete !

    à vrai dire ce n'est pas moi qui ai fait le script mais je suis chargé de l'améliorer.

    en gros ce qu'il s'y passe pour le moment :

    on prend le premier client que l'on compare à toute la table pour voir si il a des doublons.
    ( avec comparaison sur quasiment tout les champs )

    on prend le deuxieme client que l'on compare à toute la table pour voir si il a des doublons.

    etc sur toute la table

    tout ca couplé à un systeme de pondération ( une sorte de match à xx % ) qui permet d'automatiser la suppression.

    Je me suis peut etre mal expliqué sur doublons : c'est par exemple meme nom pas meme prenom, meme adresse , meme nom de société etc !

  4. #4
    Expert éminent Avatar de Mr N.
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    5 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 5 418
    Points : 6 449
    Points
    6 449
    Par défaut
    A ouais quand même ! combien de lignes dans la table ?

  5. #5
    Nouveau membre du Club
    Inscrit en
    Mai 2004
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 39
    Points : 34
    Points
    34
    Par défaut
    environ 6000 ...

    je comprends que le serveur aime pas

  6. #6
    Expert éminent Avatar de Mr N.
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    5 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 5 418
    Points : 6 449
    Points
    6 449
    Par défaut
    Bof c'est presque rien du tout 6000. Tout est relatif

    Je ne résoud toujours pas ton problème, mais as tu fais un analyze table de ta table ? Parfois ca aide

  7. #7
    Nouveau membre du Club
    Inscrit en
    Mai 2004
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 39
    Points : 34
    Points
    34
    Par défaut
    j'ai fait, ça me marque OK OK OK

    à vrai dire je penche plutot pour la configuration du serveur ( surement apache ), qui n'aime pas les temps d'execution long malgré le time_limit de php, seulement je n'y ai pas acces

    je vais devoir me debrouiller autrement pour essayer d'y aller petit à petit ...

    je sens deja le mal de tete venir

    Merci des reponses !

  8. #8
    Expert confirmé
    Avatar de siddh
    Inscrit en
    Novembre 2005
    Messages
    3 868
    Détails du profil
    Informations personnelles :
    Âge : 47

    Informations forums :
    Inscription : Novembre 2005
    Messages : 3 868
    Points : 5 011
    Points
    5 011
    Par défaut
    le temps me parais excessivement long quand meme, je suis sur qu on peut le faire en beaucoup moins de temps.

    mysql n'est pas oracle certes mais 6000 enregs c est pas des masses.

    pour le time limit :
    If seconds is set to zero, no time limit is imposed.
    c'est ca que tu as essayé ?

    et il y a certainement une limitation apache a mon avis
    Alunissage : Procédé technique consistant à déposer des imbéciles sur un rêve enfantin.

    Cours | FAQ | Sources Javascript
    Cours | FAQ | Sources PHP
    Mes Articles

  9. #9
    Nouveau membre du Club
    Inscrit en
    Mai 2004
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 39
    Points : 34
    Points
    34
    Par défaut
    à vrai dire j'ai essayé de mettre 7200 histoire de voir si au bout de 2h il plantait, mais non toujours au bout d'une heure ...
    et moi aussi ça me parait long mais bon c'est pas mon code ...
    je vais essayer de voir si je peux optimiser certains trucs parce que bon ... quitte à tout refaire

    Merci de vos réponses.

    Sinon une idée utopique comme ça : on peut pas arreter le script au bout de 55 min pis le relancer apres exactement là où il c'etait arreté ? car vu que je n'ai pas le droit d'acceder à la conf du serveur ...

  10. #10
    Expert confirmé
    Avatar de Sub0
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2002
    Messages
    3 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 573
    Points : 4 219
    Points
    4 219
    Par défaut
    Salut!

    Perso, peut-être que je ne comparerais pas tous les champs, mais seulement 1 au départ. Et si ce champs est le même, alors je compare le 2ème, ainsi de suite. Il existe la fonction in_array qui te serait peut-être utile... Une autre solution est de recréer une nouvelle table propre en utilisant le paramètre LIMIT 1 dans les requêtes, etc... Le plus embêtant en fait, c'est qu'il ya une limite mémoire (8M je crois). On ne peut donc pas créer des tableaux trop volumineux. Eventuellement, récupère un enregistrement, et effectue avec un select dans la table. Si mysql_num_rows te retourne une valeur > à 1, cela signifie que l'enregistrement est double, ou triple... sinon, pas besoin de faire la recherche. je vais voir si je possède un code similaire, je te le passerais.
    De retour parmis vous après 10 ans!!

  11. #11
    Expert confirmé
    Avatar de Sub0
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2002
    Messages
    3 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 573
    Points : 4 219
    Points
    4 219
    Par défaut
    Le code suivant cherche et supprime les doublons en comparant tous les champs sauf le premier (id normalement) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    $table="nom_de_ta_table";
     
    //============================================================
    //  RECUPERE LES CHAMPS DE LA TABLE
    //============================================================
    $champs=Array();
    $sql="SHOW COLUMNS FROM `".$table."`;";
    $res=@mysql_query($sql);
    if(!$res) die('Impossible d\'éxécuter la requête !<br>'.@mysql_error());
    while($row=mysql_fetch_array($res)) $champs[]=$row['Field'];
    $cnt_champs=count($champs);
    if($cnt_champs<=0) die('Champs introuvable dans la table "'.$table.'" !');
     
    //============================================================
    //  RECUPERE LE NOMBRE D'ENREGISTRMENT
    //============================================================
    $sql="SELECT * FROM `".$table."`";
    $res=@mysql_query($sql);
    $num_rows=@mysql_num_rows($res);
    if(!$res || $num_rows<=0) die('Impossible d\'éxécuter la requête !<br>'.@mysql_error());
     
    //============================================================
    //  POUR CHAQUE ENREGISTREMENT, VERFIER SI DOUBLON
    //============================================================
    while($row=@mysql_fetch_array($res)){
      $sql="SELECT * FROM `".$table."`";
      for($x=1;$x<$cnt_champs;$x++){
        if($x==1) $sql.=" WHERE ";else $sql.=" AND ";
        $sql.=$champs[$x]."='".$row[$champs[$x]]."'";
      }
      $sql.=";";
      $res2=@mysql_query($sql);
      $num_rows2=@mysql_num_rows($res2); 
      if($num_rows2>1){
        $first=true;
        while($row2=@mysql_fetch_array($res2)){
          if(!$first){
            //====================================================
            //  SUPPRESSION DES DOUBLONS
            //====================================================
            $sql="DELETE FROM `".$table."`";
            for($x=0;$x<$cnt_champs;$x++){
              if($x==0) $sql.=" WHERE ";else $sql.=" AND ";
              $sql.=$champs[$x]."='".$row2[$champs[$x]]."'";
            }
            $sql.=";";
            $res3=@mysql_query($sql);
            if(!$res3) die('Impossible d\'éxécuter la requête !<br>'.@mysql_error());
            echo 'Enregistrement '.$row2[$champs[0]].' supprimé.<br>';
          }
          $first=false;
        }
      }
    }
    die('Opération terminée.<br>');
    à+
    De retour parmis vous après 10 ans!!

  12. #12
    Nouveau membre du Club
    Inscrit en
    Mai 2004
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 39
    Points : 34
    Points
    34
    Par défaut
    Alors là !

    J'étais justement en train de me dire qu'il fallait que je refasse tout plutot que de bidouiller le code existant, reste plus qu'a adapter ce code au systeme de pondération en place !

    Vraiment un grand merci

    !

  13. #13
    Membre régulier
    Inscrit en
    Octobre 2005
    Messages
    76
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 76
    Points : 76
    Points
    76
    Par défaut
    Hmmmm... en même temps, c'est quoi le système de pondération ?

    Parce que ne comparer les autres champs que si le premier correspond tu risque de zappé bon nombre de "doublon" potentiel...

    Enfin pour moi, un système de pondération donne une note à chaque comparaison unitaire valide (chaque champs) et concidère comme le tout comme un doublon si la note dépasse une certaine valeur... un peu comme sont fait actuellement les popups killer ou les spams assassins

    Par contre, une autre optimisation utile :
    tu compare le premier client à tout le reste...
    tu compare le second à tout le reste sauf le premier (vu qu'il a déjà été fait dans l'autre sens avant)
    tu compare le troisième à tout le reste sauf le premier et le deuxième...

    Tu peux faire ca rapidement avec un order et un where dans ta requete de selection.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    // Selection du prochain element à comparer :
    Select * from client where id > $last_id order by id limit 0,1
     
    // Selection des elements avec lesquels le comparer :
    Select * from client where id > $new_id order by id

  14. #14
    Membre confirmé Avatar de a028762
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    419
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 419
    Points : 537
    Points
    537
    Par défaut Un peu de SQL
    Sur une base PERSONNES , pour trouver des doublons sur le NOM et le PRENOM, la solution la plus rapide est la commande SQL :

    select count(*),NOM,PRENOM from PERSONNES group by NOM,PRENOM having count(*) > 1;

    Et cela ne ramène que les lignes ayant des DOUBLONS , et PHP n'a pas besoin de faire des efforts de mémoire particuliers
    Pour info, même MYSQL qui n'est pas une SGBD dite très puissante résoud cette question sur 30.000 lignes en 3 secondes !!!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Arreter tous les scripts en cours
    Par Fabthebug dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 02/07/2009, 10h39
  2. Réponses: 8
    Dernier message: 26/11/2007, 15h01
  3. [PHP-JS] Arrêter le script au bout de x secondes
    Par AsQuel dans le forum Langage
    Réponses: 1
    Dernier message: 28/07/2007, 00h41
  4. [Sécurité] Securité cross site scripting
    Par doudou439 dans le forum Langage
    Réponses: 3
    Dernier message: 20/01/2007, 13h59
  5. Réponses: 3
    Dernier message: 23/02/2006, 08h30

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo