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

Langage PHP Discussion :

Comment faire pour qu'un script ne puisse pas être lancé plusieurs fois simultanément


Sujet :

Langage PHP

  1. #1
    Nouveau membre du Club
    Inscrit en
    Février 2007
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 42
    Points : 30
    Points
    30
    Par défaut Comment faire pour qu'un script ne puisse pas être lancé plusieurs fois simultanément
    Bonjour,

    Un script appelé par un formulaire AJAX consomme pas mal de ressources. Je souhaite qu'un utilisateur ne puisse le lancer qu'une seule fois. Mais je bloque vraiment. J'ai essayé ça:
    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
     
    if (empty($_SESSION['count'])) {
     $_SESSION['count'] = 0;
    } 
     
    $_SESSION['count']++;
     
     
    if ($_SESSION['count'] > 1)
    {
            # code...
            echo "Attention, ";
            echo $_SESSION['count'];
            echo " analyses en cours";   
            exit();                
    }
    Et en fin de script

    Avez-vous une idée svp?

    Merci

  2. #2
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    Ca devrait déjà fonctionner par un effet de bord : deux script ne peuvent pas accéder à une session en même temps.
    Le deuxième doit attendre que le premier libère le fichier de session pour démarrer la sienne.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  3. #3
    Membre éprouvé Avatar de alain31tl
    Homme Profil pro
    Inscrit en
    Novembre 2005
    Messages
    935
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Novembre 2005
    Messages : 935
    Points : 1 019
    Points
    1 019
    Par défaut
    Citation Envoyé par leccux Voir le message
    ...Un script appelé par un formulaire AJAX consomme pas mal de ressources. Je souhaite qu'un utilisateur ne puisse le lancer qu'une seule fois
    Bonjour
    A première vue, je mettrais un champ de type hidden dans ton formulaire et sa valeur (controle) mise en Session php.
    Quoique...
    On peut aussi utiliser n'importe quelle variable transmise par le formulaire, mais bon, c'est pour l'exemple.
    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
    <?php
    session_start();
     
    if(isset($_POST['controle'])) {
    $_SESSION['controle'] = '$controle';
    }
     
    if (isset($_SESSION['controle']) {
    // Je ne fais rien
    }
    else
    {
    // Je sollicite mon script
    }
    ?>
    Ou alors, je n'ai pas trop pigé ton souci.
    Ce n'est pas parce que les choses sont difficiles qu'on n'ose pas les entreprendre.
    C'est parce qu'on n'ose pas les entreprendre qu'elles sont difficiles.

  4. #4
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    Salut

    Je souhaite qu'un utilisateur ne puisse le lancer qu'une seule fois
    Tel que tu décrit le problème, ce serait plutôt une action du coté de l'utilisateur qu'il faudrait agir, comme l'empêcher de valider 2 fois un formulaire, de cliquer 2 fois sur le bouton.

    Si c'est ça, on peu par exemple et en 1er désactiver le bouton avec l'attribut disabled (disabled="disabled") en Javascript, ça va le "griser" d'ailleurs.
    Il est théoriquement pplus possible de cliquer une 2ème fois, et même appuyer sur le touche "entrée".

    A près avoir désactiver le bouton, il suffit d'exécuter le code Ajax.
    Le serveur ne devrait plus obtenir 2 fois la même requête HTTP de l'Ajax pour le même utilisateur.

    Pour info, il vaut mieux que cette action soit déclenchée sur un bouton (ou submit), car si je ne dis pas de bêtise, l'attribut disabled est valide/conforme que pour les éléments HTML input/bouton (pas pour un lien, div, etc ...ni même un form).
    Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
    Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]

  5. #5
    Nouveau membre du Club
    Inscrit en
    Février 2007
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 42
    Points : 30
    Points
    30
    Par défaut Limiter le nombre d'exécutions simultanées d'un script.
    Bonjour,

    Un script PHP demande pas mal de ressources. Sa fonction est l'analyse d'un texte, les textes sont parfois long et la langue française compte beaucoup de mots...

    Après un gros travail sur l'optimisation, j'ai ajouter un contrôle javascript afin d'éviter qu'un même utilisateur lance des analyses simultanées et ne me plombe tout.

    Problèmes:
    - si beaucoup d'utilisateurs, ça ne change rien
    - j'ai l'impression qu'au moins un utilisateur s'amuse à passer au delà du contrôle JS.

    J'aimerais donc trouver une méthode pour:
    1 créer un système de "file d'attente" simple ou au moins limiter le nombre d'utilisation simultanés du script (par exemple à 10)
    2 utiliser $_SESSION (ou autre chose) pour éviter qu'un même utilisateur ne lance plusieurs fois le script avant la fin.

    Ce serait vraiment chouette de m'aider.

    Julien

  6. #6
    Membre chevronné
    Avatar de gwinyam
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2006
    Messages
    1 162
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2006
    Messages : 1 162
    Points : 2 015
    Points
    2 015
    Par défaut
    $_SESSION est un tableau que tu peux modifier mais propre à chaque client. Ajoute donc un nouveau champ à celui-ci que tu définiras à TRUE si il n'existe pas encore ou est défini à FALSE.

    Si quand ton script démarre, le champ ciblé est déjà true, tu ne fais rien.

    Pour le nombre d'exécutions simultanés, je ne sais pas si Apache ou PHP autorise ce genre de limitations, ceci dit, avec la variable $_SERVER peut-être que tu pourras faire quelque chose.
    Comparez la qualité et le prix du matériel de bricolage ou de maison avant d'acheter : MatosMaison
    Le bouton ne masse pas les pieds, mais ça aide la communauté.

  7. #7
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    Salut

    A mon avis le problème est la suite de ton topic :
    Comment faire pour qu'un script ne puisse pas être lancé plusieurs fois simultanément

    j'ai l'impression qu'au moins un utilisateur s'amuse à passer au delà du contrôle JS.
    Je n'en suis pas certain, j'en doute même.
    Essai toi même de le faire, ça me semble très loin d'être simple.


    Ton problème est non seulement qu'un seul utilisateur ne peux pas pas exécuter le même traitement faute de traitements trop long, mais aussi 2 (ou 3, etc ...) utilisateurs différents, donc session différentes aussi, ne peuvent pas exécuter le même traitement pour la même raison.


    Ces traitements (très) longs seraient le fond du problème à mon sens.
    Utiliser les sessions n'est pas la solution, car cette info est propre à chaque utilisateur comme ça a été dit, ça veut dire que si 1 utilisateur déclenche le traitement, l'utilisateur 2 ne le saura pas.
    Du coup, impossible aussi de savoir quand un utilisateur aura terminé.


    Pour ça, il faut au minimum une info globales accessible à tous les utilisateurs, comme par exemple créer un fichier et écrire dedans 0 ou 1 (0 -> verrouillé, 1 -> déverrouillé).
    Mais c'est pas si simple et c'est un peu "casse gueule". Ce n'est qu'un exemple de toute manière.


    Faudrait à mon sens faire le point sur ce que tu fais, et voir s'il n'y a pas moyen d'optimiser ces traitements.
    Pourquoi pas diviser ça en plusieurs étapes plus petites.
    Est ce qu'il n'y a pas moyen d'opter pour une formule d'hébergement plus pro, plus rapide.
    ... etc ...


    On ne sait pas quel est le service qui est proposé, mais le principe de la file d'attente est à double tranchant.
    Si tu as affaire à des utilisateurs impatients dans mon genre, dans la seconde qui suit je m'en vais, et ne reviendra plus jamais
    J'irais illico presto voir ailleurs et trouver le même service, sans devoir faire la queue.
    Il y en déjà assez comme ça dans la vie courante.
    (A part les impôts où là, on a pas trop le choix )
    Faut voir.
    Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
    Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]

  8. #8
    Nouveau membre du Club
    Inscrit en
    Février 2007
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 42
    Points : 30
    Points
    30
    Par défaut

    Et merde, j'avais oublié que j'ai déjà demandé. Et sur le même site en plus. À ma décharge, il était tard et ma question n'était pas formulée de la même façon.
    Jsuis vraiment une quiche.

    Merci à vous deux pour vos réponses.
    Je vais demander la clôture de ce dernier et contenue sur l'autre.

    (edit)
    Mais t'as complétement raison, sans le vouloir c'est la suite logique.

  9. #9
    Nouveau membre du Club
    Inscrit en
    Février 2007
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 42
    Points : 30
    Points
    30
    Par défaut
    Merci pour vos réponses précieuses, je vais essayer d'intégrer vos conseils à mon code et vous tiens au courant.

    En attendant, je vais essayer de mieux structurer mon code PHP pour rendre le contrôle plus pratique.

    Pour l'utilisation de contrôles JS, c'était mis en place. Mais j'ai l'impression que je suis face à du sabotage pour passer au-delà du contrôle côté" client. Pour ça que j'aimerais en ajouter une couche en PHP
    Côté hébergement, je vais voir...

    j'ai quasi double posté (involontairement ) car c'est une question qui me turlupine. J'ai demandé la suppression.

  10. #10
    Nouveau membre du Club
    Inscrit en
    Février 2007
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 42
    Points : 30
    Points
    30
    Par défaut
    Citation Envoyé par sabotage Voir le message
    Ca devrait déjà fonctionner par un effet de bord : deux script ne peuvent pas accéder à une session en même temps.
    Le deuxième doit attendre que le premier libère le fichier de session pour démarrer la sienne.
    Ba oui ça fonctionne, mais trop justement. Si un utilisateur clique 2 fois, le compteur fait son oeuvre, le script n'est pas lancé. Mais l'utilisateur est obligé de fermer/relancer le navigateur pour lancer une analyse.

    Je me demande si, au lieu d'utiliser un compteur, je ne devrais pas jouer sur le temps. Genre un blocage de 5 secondes.

    Si vous avez une idée, je suis preneur.

  11. #11
    Nouveau membre du Club
    Inscrit en
    Février 2007
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 42
    Points : 30
    Points
    30
    Par défaut
    Citation Envoyé par gwinyam Voir le message
    Pour le nombre d'exécutions simultanés, je ne sais pas si Apache ou PHP autorise ce genre de limitations, ceci dit, avec la variable $_SERVER peut-être que tu pourras faire quelque chose.
    C'est une trop bonne piste pour ma seconde question. Je vais voir ça
    Merci encors

  12. #12
    Nouveau membre du Club
    Inscrit en
    Février 2007
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 42
    Points : 30
    Points
    30
    Par défaut
    Je vais craquer et me replonger dans ruby

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    $limit = time()+5;
    if (!empty($_SESSION['lastana']) && $_SESSION['lastana'] < $limit) 
    {
            # code...
            echo "Merci de ne pas réaliser plus d'une analyse toute les 5 secondes";  
            $_SESSION['lastana']=time();
            exit();                
    }
     
    $_SESSION['lastana'] = time();
    L'idée est simple: si un même utilisateur lance plus de 2 fois le script en 5 seconde, un petit message est affiché et le script arrété.
    Là ça marche, sauf que si le test fonctionne (pénalise) une fois, la session est grillée et même 60 secondes plus tard, le script ne se lance plus.

    HELP les amis.

  13. #13
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 380
    Points : 10 410
    Points
    10 410
    Par défaut
    Citation Envoyé par leccux Voir le message
    Je me demande si, au lieu d'utiliser un compteur, je ne devrais pas jouer sur le temps. Genre un blocage de 5 secondes.

    Si vous avez une idée, je suis preneur.
    Ce serait le plus simple à faire. Tu peux très bien enregistrer le temps t de la connexion à ta bdd dans une variable de session et ensuite tu compare à la prochaine connexion et tu envoie un message d'annonce si le même utilisateur tente des connexions à répétitions (genre "vous devez attendre 5 secondes entre plusieurs recherches").

  14. #14
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 380
    Points : 10 410
    Points
    10 410
    Par défaut
    Genre :

    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
    <?php
     
    session_start();
    $temps_min = 5;
     
    $test = (!isset($_SESSION['user_time']) || (isset($_SESSION['user_time']) && time() - $_SESSION['user_time'] > $temps_min )) ? true : false;
     
    $_SESSION['user_time'] = time();
     
    if(!$test)
    {
    echo 'vous devez attendre '.$temps_min.' secondes avant de faire une seconde requête';
    }
    else echo 'traitement de la requête';
     
    ?>

  15. #15
    Nouveau membre du Club
    Inscrit en
    Février 2007
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 42
    Points : 30
    Points
    30
    Par défaut
    Génial, ça fonctionne! Merci mec.

    Mais, je ne capte toujours pas ce qui foire dans la mienne... As tu une idée?

  16. #16
    Membre chevronné
    Avatar de gwinyam
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2006
    Messages
    1 162
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2006
    Messages : 1 162
    Points : 2 015
    Points
    2 015
    Par défaut
    A la vue de ton code, je dirais que t'as oublié le session_start()
    Comparez la qualité et le prix du matériel de bricolage ou de maison avant d'acheter : MatosMaison
    Le bouton ne masse pas les pieds, mais ça aide la communauté.

  17. #17
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 380
    Points : 10 410
    Points
    10 410
    Par défaut
    Ben le temps passé est toujours inférieur au temps actuel augmenté de 5 secondes

    donc

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $_SESSION['lastana'] < time()+5
    est toujours vrai étant donné que $_SESSION['lastana'] enregistre un temps antérieur.

    (Mets un +1 dans le message de la bonne réponse, c'est plus clair pour les futurs visiteurs )

  18. #18
    Nouveau membre du Club
    Inscrit en
    Février 2007
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 42
    Points : 30
    Points
    30
    Par défaut
    Citation Envoyé par ABCIWEB Voir le message
    Ben le temps passé est toujours inférieur au temps actuel augmenté de 5 secondes

    donc

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $_SESSION['lastana'] < time()+5
    est toujours vrai étant donné que $_SESSION['lastana'] enregistre un temps antérieur.

    (Mets un +1 dans le message de la bonne réponse, c'est plus clair pour les futurs visiteurs )

    ok, je vais me coucher.

  19. #19
    Membre averti Avatar de BornBanane
    Homme Profil pro
    dev
    Inscrit en
    Mars 2007
    Messages
    284
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : dev

    Informations forums :
    Inscription : Mars 2007
    Messages : 284
    Points : 416
    Points
    416
    Par défaut
    Sinon tu as une méthode un poil plus lourde mais qui pourrait éviter tous tes problèmes. Par contre cela nécessite que l'appel ajax ne renvoie pas d'info spécifique au traitement.

    Je m'explique. Ce qu'il faudrait faire :
    Lorsque l'utilisateur fait la demande d'un traitement, cela produit un appel ajax. L'appel ajax va alors simplement aller remplir une table en bdd avec les infos nécessaires au traitement.
    Ensuite, via un système de cron, tu lances les traitements toutes les X secondes.
    Celui-ci fera :
    0 - si fichier lock.tmp existe :j'arrête l'exécution du script ,
    sinon : je crée un fichier lock.tmp
    1 - je prend la ligne la plus ancienne dans la table en bdd,
    2 - j'effectue le traitement sur les données,
    3 - une fois le traitement effectué j'efface la ligne en cours dans la bdd.
    4 - j'efface le fichier lock.tmp


    Tu peux ensuite ajouter au script une détection de doublons.
    Smiley de Plomb 2009
    Anciennement FrancoisIT

  20. #20
    Nouveau membre du Club
    Inscrit en
    Février 2007
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 42
    Points : 30
    Points
    30
    Par défaut
    joli. vraiment joli.
    J'aime le principe même si je vais essayer de l'adapter pour éviter d'avoir des accès en écriture à ma base.
    merci

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 8
    Dernier message: 17/04/2009, 18h16
  2. comment faire pour que mes scripts ne soient pas mis en cache ?
    Par Alexdezark dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 21/01/2009, 15h25
  3. comment faire pour tourner un script sur un serveur et lequel?
    Par patchiko dans le forum Serveurs (Apache, IIS,...)
    Réponses: 1
    Dernier message: 20/07/2007, 16h00
  4. Réponses: 2
    Dernier message: 06/10/2006, 10h38
  5. Réponses: 1
    Dernier message: 13/05/2006, 10h24

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