Précédent   Forum des professionnels en informatique > PHP > Langage > Débuter
Débuter Forum d'entraide pour débuter en PHP. Avant de poster -> Cours PHP, FAQ PHP, Outils PHP, etc.
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 17/03/2011, 23h52   #1
Futur Membre du Club
 
Inscription : février 2007
Messages : 42
Détails du profil
Informations forums :
Inscription : février 2007
Messages : 42
Points : 19
Points : 19
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 :
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
leccux est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/03/2011, 00h09   #2
Modérateur
 
Avatar de sabotage
 
Homme Vincent
Inscription : juillet 2005
Messages : 14 929
Détails du profil
Informations personnelles :
Nom : Homme Vincent

Informations forums :
Inscription : juillet 2005
Messages : 14 929
Points : 16 381
Points : 16 381
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.
sabotage est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 19/03/2011, 01h29   #3
Membre émérite
 
Avatar de alain31tl
 
Alain
Inscription : novembre 2005
Messages : 897
Détails du profil
Informations personnelles :
Nom : Alain
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : novembre 2005
Messages : 897
Points : 910
Points : 910
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 :
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.
alain31tl est déconnecté   Envoyer un message privé Réponse avec citation 11
Vieux 20/03/2011, 08h38   #4
Expert Confirmé
 
Avatar de RunCodePhp
 
Inscription : janvier 2010
Messages : 2 709
Détails du profil
Informations personnelles :
Localisation : Réunion

Informations forums :
Inscription : janvier 2010
Messages : 2 709
Points : 3 279
Points : 3 279
Salut

Citation:
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]
RunCodePhp est déconnecté   Envoyer un message privé Réponse avec citation 11
Vieux 20/03/2011, 23h54   #5
Futur Membre du Club
 
Inscription : février 2007
Messages : 42
Détails du profil
Informations forums :
Inscription : février 2007
Messages : 42
Points : 19
Points : 19
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
leccux est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/03/2011, 12h19   #6
Membre Expert
 
Avatar de gwinyam
 
Homme Mathieu ROBIN
Développeur Web
Inscription : mai 2006
Messages : 1 116
Détails du profil
Informations personnelles :
Nom : Homme Mathieu ROBIN
Âge : 25
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 116
Points : 2 142
Points : 2 142
$_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.
__________________
Mon blog techno et son billet hebdomadaire sur l'actualité jQuery. Et mon blog cuisine pour une personne.
Le bouton ne masse pas les pieds, mais ça aide la communauté.
gwinyam est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 21/03/2011, 13h52   #7
Expert Confirmé
 
Avatar de RunCodePhp
 
Inscription : janvier 2010
Messages : 2 709
Détails du profil
Informations personnelles :
Localisation : Réunion

Informations forums :
Inscription : janvier 2010
Messages : 2 709
Points : 3 279
Points : 3 279
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

Citation:
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]
RunCodePhp est déconnecté   Envoyer un message privé Réponse avec citation 11
Vieux 21/03/2011, 18h11   #8
Futur Membre du Club
 
Inscription : février 2007
Messages : 42
Détails du profil
Informations forums :
Inscription : février 2007
Messages : 42
Points : 19
Points : 19

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.
leccux est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/03/2011, 18h20   #9
Futur Membre du Club
 
Inscription : février 2007
Messages : 42
Détails du profil
Informations forums :
Inscription : février 2007
Messages : 42
Points : 19
Points : 19
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.
leccux est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/03/2011, 18h25   #10
Futur Membre du Club
 
Inscription : février 2007
Messages : 42
Détails du profil
Informations forums :
Inscription : février 2007
Messages : 42
Points : 19
Points : 19
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.
leccux est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/03/2011, 18h48   #11
Futur Membre du Club
 
Inscription : février 2007
Messages : 42
Détails du profil
Informations forums :
Inscription : février 2007
Messages : 42
Points : 19
Points : 19
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
leccux est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/03/2011, 21h22   #12
Futur Membre du Club
 
Inscription : février 2007
Messages : 42
Détails du profil
Informations forums :
Inscription : février 2007
Messages : 42
Points : 19
Points : 19
Je vais craquer et me replonger dans ruby

Code :
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.
leccux est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/03/2011, 21h24   #13
Membre Expert
 
Inscription : septembre 2010
Messages : 1 240
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 1 240
Points : 1 562
Points : 1 562
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").
__________________
- Réalisations
- Interface graphique : génération en javascript d'objets défilants, texte et/ou images, mode horizontal ou vertical.
ABCIWEB est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 21/03/2011, 22h02   #14
Membre Expert
 
Inscription : septembre 2010
Messages : 1 240
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 1 240
Points : 1 562
Points : 1 562
Genre :

Code :
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';
 
?>
__________________
- Réalisations
- Interface graphique : génération en javascript d'objets défilants, texte et/ou images, mode horizontal ou vertical.
ABCIWEB est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 21/03/2011, 22h12   #15
Futur Membre du Club
 
Inscription : février 2007
Messages : 42
Détails du profil
Informations forums :
Inscription : février 2007
Messages : 42
Points : 19
Points : 19
Génial, ça fonctionne! Merci mec.

Mais, je ne capte toujours pas ce qui foire dans la mienne... As tu une idée?
leccux est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/03/2011, 22h39   #16
Membre Expert
 
Avatar de gwinyam
 
Homme Mathieu ROBIN
Développeur Web
Inscription : mai 2006
Messages : 1 116
Détails du profil
Informations personnelles :
Nom : Homme Mathieu ROBIN
Âge : 25
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 116
Points : 2 142
Points : 2 142
A la vue de ton code, je dirais que t'as oublié le session_start()
__________________
Mon blog techno et son billet hebdomadaire sur l'actualité jQuery. Et mon blog cuisine pour une personne.
Le bouton ne masse pas les pieds, mais ça aide la communauté.
gwinyam est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/03/2011, 22h44   #17
Membre Expert
 
Inscription : septembre 2010
Messages : 1 240
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 1 240
Points : 1 562
Points : 1 562
Ben le temps passé est toujours inférieur au temps actuel augmenté de 5 secondes

donc

Code :
$_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 )
__________________
- Réalisations
- Interface graphique : génération en javascript d'objets défilants, texte et/ou images, mode horizontal ou vertical.
ABCIWEB est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 21/03/2011, 22h59   #18
Futur Membre du Club
 
Inscription : février 2007
Messages : 42
Détails du profil
Informations forums :
Inscription : février 2007
Messages : 42
Points : 19
Points : 19
Citation:
Envoyé par ABCIWEB Voir le message
Ben le temps passé est toujours inférieur au temps actuel augmenté de 5 secondes

donc

Code :
$_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.
leccux est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/03/2011, 11h28   #19
Membre éclairé
 
Avatar de BornBanane
 
Homme
Ingénieur développement logiciels
Inscription : mars 2007
Messages : 274
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Hauts de Seine (Île de France)

Informations professionnelles :
Activité : Ingénieur développement logiciels

Informations forums :
Inscription : mars 2007
Messages : 274
Points : 350
Points : 350
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
BornBanane est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 23/03/2011, 11h55   #20
Futur Membre du Club
 
Inscription : février 2007
Messages : 42
Détails du profil
Informations forums :
Inscription : février 2007
Messages : 42
Points : 19
Points : 19
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
leccux est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 19h38.


 
 
 
 
Partenaires

Hébergement Web