Executer une fonction php lors de la fermeture

bZx Messages postés 8 Date d'inscription dimanche 24 septembre 2006 Statut Membre Dernière intervention 20 novembre 2010 - 26 mai 2009 à 10:24
bZx Messages postés 8 Date d'inscription dimanche 24 septembre 2006 Statut Membre Dernière intervention 20 novembre 2010 - 28 mai 2009 à 09:38
Pour les besoins de genbio.fr j'ai programmé 2 fonctions php "compteur" et "compteurApply".
la fonction compteur, exécutée sur chaque page, stoque ses variables dans $_SESSION.
La fonction compteurApply ne doit être exécuté qu'une fois: lorsqu'un utilisateur quitte le site.
Elle va récupérer les variables de sessions stoquées par compteur, les analyser et mettre à jour la bdd en incrémentant par exemple le nombre de page vues.

Mon problème est le suivant:

Pour que ce système fonctionne correctement il faudrait que la fonction compteurApply soit executé lors de la fermeture de la fenêtre. Je me suis donc intéressé à la fonction javascript onbeforeunload que je souhaitais coupler avec de l'ajax pour executer la fonction compteurApply. Malheureusement la fonction compteurApply va alors être executé à chaque fois que l'on change de page ce qui pose problème ...

Comment faire en sorte que la fonction compteurApply ne soit executé que lorsqu'on quitte le site (90% des pages du sites sont contenues dans un contrôleur (design pattern MVC) nommé avec originalité genbio.php donc au pire si on quitte genbio.php on peut dire qu'on quitte le site) ?
 
Voici pour informations les 2 fonctions incriminées et les fonctions qu'elles utilisent mais normalement vous ne devriez pas en avoir besoin pour comprendre et résoudre mon problème:

function ispro() //retourne vrai si l'on est sur une page qui porte  penser que le visiteur est un professionnel
{
    if (isprofessionnelsur()) return true;
    if ($rubrique == "pro") return true;
    return false;
}
function iscandidat() //retourne vrai si l'on est sur une page qui porte  penser qu'on est candidat
{    if ((iscandidatsur()) || ($rubrique "offre") || ($_SESSION['niveauUtilisateur'] 1)) return true;
    return false;
}
function iscandidatsur() //retourne vrai si l'on est sur une page qui porte  penser qu'on est candidat
{    if (($action "postuler") || ($_SESSION['niveauUtilisateur'] 2)) return true;
    return false;
}
function isprofessionnelsur() //retourne vrai si l'on est sur une page qui porte  penser qu'on est candidat
{
        if (($page "refana") || ($page "dmdmat") || ($_SESSION['niveauUtilisateur'] > 2)) return true;
    return false;
}
function compteurApply()
{
    $cmp = new Compteur();
    $cmp = unserialize(Compteur::getLast());
    $cmp->__set("pagesVues",($cmp->__get('pagesVues') + (int)$_SESSION['pagesVues']));
    if ($_SESSION['professionnelsur'] == 1) $cmp->addPro();
    else    if ($_SESSION['candidatsur'] == 1) $cmp->addCan();
            else
            {
                //Si on n'est pas totalement sur qu'il est pro ou candidat:
                if (($_SESSION['professionnel'] > 0) || ($_SESSION['candidat'] > 0))
                {
                    if (($_SESSION['visiteur'] > $_SESSION['professionnel']) && ($_SESSION['visiteur'] > $_SESSION['candidat']))
                    {
                        //Il est tres probablement juste un visiteur si il a vu en grande majorit des pages de visiteurs
                        $cmp->addVis();
                    }
                    else
                    {           
                        //Il est ou professionnel ou candidat:
                        if ($_SESSION['professionnel'] > $_SESSION['candidat']) $cmp->addPro();
                        else $cmp->addCan();
                    }
                }
                else
                {
                    //Il est seulement visiteur
                    $cmp->addVis();
                }
            }
    $cmpt->update();
}

function compteur()
{
    //VAR EXTRACTION
    $var = $_GET;
    $var2 = $_POST;
    foreach($var as $v)    $v = $v;
    foreach($var2 as $v2) $v2 = $v2;
    extract($var);
    extract($var2);
    if (!(isset($_SESSION['ip'])))//nouveau visiteur
    {
        if (ispro()) $_SESSION['professionnel']++;
        else
        {
            $_SESSION['professionnel']=0;
            if (iscandidat()) $_SESSION['candidat']++;
            else
            {
                $_SESSION['candidat']=0;
                $_SESSION['visiteur']=1;//on lui attribue un role de visiteur (puisque normalement il est sur la page d'acceuil)
            }
        }
    }
    else
    {
        //ancien visiteur
        if ($_SESSION['ip'] != $_SERVER['REMOTE_ADDR']) //ancien visiteur ayant chang d'ip
        {
            $_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
        }
       
        if (((int)$_SESSION['professionnelsur'] != 1) && ((int)$_SESSION['candidatsur'] != 1)) //Si on n'est pas certain qu'ils soient pro on candidat
        {
            if (iscandidat()) // Si il est sur une page qui porte  penser qu'il est candidat
            {   
                if ((int)$_SESSION['visiteur'] > 0) (int)$_SESSION['visiteur']--;
                $_SESSION['candidat']++;
                // Si il est sur une page qui prouve qu'il est professionnel on le met en professionnelsur
                if (iscandidatsur())
                {
                    $_SESSION['candidatsur']=1;
                    $_SESSION['visiteur']=0;
                    $_SESSION['professionnel']=0;
                }
            }
            else if (isprofessionnel()) // Si il est sur une page qui porte  penser qu'il est professionnel
            {   
                if ((int)$_SESSION['visiteur'] > 0) $_SESSION['visiteur']--;
                $_SESSION['professionnel']++;
                // Si il est sur une page qui prouve qu'il est professionnel on le met en professionnelsur
                if (isprofessionnelsur())
                {
                    $_SESSION['professionnelsur']=1;
                    $_SESSION['visiteur']=0;
                    $_SESSION['candidat']=0;
                }
            }
            else //Il est sur une page qui porte  penser qu'il est simple visiteur
            {
                $_SESSION['visiteur']++;
            }
        }
    }
    $_SESSION['pagesVues']++;
}

3 réponses

KrqcS Messages postés 22 Date d'inscription mardi 31 mars 2009 Statut Membre Dernière intervention 8 janvier 2010
26 mai 2009 à 10:48
Essaye de scinder l'application globale en deux frames

La frame de droit affichera normalement le site

La frame de gauche (1cm) est suffisant, n'affichera rien , mais elle sera affichée en permanence. Cette page ne sera jamais modifiée, jamais reloadée.

Tu pourras donc lui associer l'évenement suivant



L'évenement OnUnLoad ne s'effectuera UNIQUEMENT qu'en cas de fermeture de la page
Dans ce cas , ta fonction sera éxécuté.
0
kohntark Messages postés 3705 Date d'inscription lundi 5 juillet 2004 Statut Membre Dernière intervention 27 avril 2012 30
26 mai 2009 à 20:41
Salut,

A mon avis l'utilisation de onUnload n'est pas une bonne idée, et encore moins celle des frames ("jamais reloadée" => et si l'utilisateur appuie sur F5 ??)

Je n'ai parcouru que brièvement tes fonctions mais pourquoi ne mets tu pas à jour dynamiquement ta base de données ?
Tu peux très bien créer une table qui enregistre la navigation des visiteurs (après traitement par compteur())
Tu crées un "signe de vie" du visiteur via ajax (par ex 1 requête toutes les 5 sec) que tu entres en DB
Tu testes à intervalles réguliers si le visiteur est toujours sur le site.
Si il ne l'est pas (dernière requête ajax > 15 sec par ex) tu fais appel à ta fonction compteurApply() qui traite les données et met à jour la DB.

Ce ne sont bien sur que les grandes lignes, mais il me semble que ça sera bien plus fiable.

Cordialement,

Kohntark -
0
bZx Messages postés 8 Date d'inscription dimanche 24 septembre 2006 Statut Membre Dernière intervention 20 novembre 2010
28 mai 2009 à 09:38
Bonjour,

Merci pour ces conseils !
Je pense également que les frames ne sont pas un moyen très propre d'arriver à mes fins ...
Parcontre mon temps étant compté (mon stage approche de sa fin) j'ai une certaine apréhension quant à reprendre tout le travail que j'avais accompli dans la classe compteur et dans ces fonctions que je vous ai présenté ... tanpis je vais m'y remettre mais j'ai en tête une troisième méthode, car ta proposition avec l'ajax et les "signes de vies" va être un peu trop lourde et longue à implémenter à mon goût !
Je vais garder en majorité le fonctionnement actuel de la classe compteur à la différence près qu'il devra également tenir le rôle de compteurApply:
on stoque dans les variables de session un flag qui correspondra au fait qu'on ai ou non déjà inséré les statistiques (pro/candidat/visiteur) de l'utilisateur du site web dans la base de données.
Ainsi la fonction compteur verifira à chaque fois ce flag et accédera ou non à la base de donnée en fonction des variables de session de l'utilisateur pour éviter toute requette inutile.
Elle accédera aussi à la base pour faire passer un utilisateur de pro vers candidat par exemple si ses variables de sessions correspondent aux conditions déjà présentes dans mes fonctions.
Merci de m'avoir aiguillé même si je n'applique pas vos suggestions finalement !

Amicalement,

bZx
0
Rejoignez-nous