Zend FR

Consultez la FAQ sur le ZF avant de poster une question

Vous n'êtes pas identifié.

#1 26-06-2008 17:53:00

Bast
Membre
Date d'inscription: 07-06-2007
Messages: 138

[Résolu] Fonctions globales : où les placer ?

Bonjour à tous !
Me revoilà avec une nouvelle question  ^^

Je voudrais créer des fonctions appelables nativement (j'entend par là : sans les appeler sur un objet ou une classe).
Des exemples :
__($string) qui traduit $string en fonction du code pays
__HTTP(mixed params) qui utilise les params pour générer des url (celà dépend de beaucoup de choses, comme l'OS du serveur, https ou non, le nom de domaine, etc... tout cela stocké dans des fichiers de config)
__DB(mixed params) qui retournes la bonne config pour créer un adapter (pareil, on a beaucoup de serveurs de DB, tres hétéroclytes)

Ces fonctions, pour être maniables, devraient pouvoir être appelées telles quelles, sans avoir besoin d'écrire UneClasse::__HTTP() par exemple. Ca serait trop lourd smile
Ma solution pour l'instant, c'est d'inclure un bon vieux fichier de fonctions en procédural dans le bootstrap. Effet garanti. Mais ouch, quelle horreur !

Alors ma question : existe-t-il un endroit approprié où placer ces fonctions, que je suis susceptible d'appeler dans les controllers aussi bien que dans les vues ?

Dernière modification par Bast (27-06-2008 10:44:05)

Hors ligne

 

#2 26-06-2008 18:53:40

philippe
Administrateur
Lieu: Grenoble
Date d'inscription: 01-03-2007
Messages: 1624

Re: [Résolu] Fonctions globales : où les placer ?

Le moyen propre pour ce genre de truc, c'est le "singleton". Je te laisse regarder dans google, tu devrais avoir quelques millions de réponses... (en gros c'est une classe qui ne peut avoir qu'une seule instance et que tu peux utiliser partout dans ton code)

A+, Philippe


twitter : @plv ; kitpages.fr : Création de sites internet à Grenoble et Paris

Hors ligne

 

#3 27-06-2008 07:11:46

whitespirit
Membre
Date d'inscription: 25-01-2008
Messages: 393

Re: [Résolu] Fonctions globales : où les placer ?

Dans mon bootstrap j'ai toutes mes includes et cette ligne

Code:

Scholastie::run();

Scholastie (il est trop moche ce prénom, et c'est le deuxième de ma copine sad) est une classe contenant que des fonctions et variables statiques, donc globales. Dedans, je découpe le contenu d'un bootstrap et je retrouve la fonction setupEnvironnement() et prepare() qui contient toutes les fonctions de types :

Code:

        self::setupFrontController();
        self::setupConfiguration();
        self::setupRoute();
        self::setDefaultController();
        self::setupCache();
        self::setupRegistry();
        self::setupListBD();        
        self::setupIni_DbSectionName();            //-- charge les paramètres de la base de données à utiliser        
        self::setupDatabase();                    //-- charge la base de données en prenant compte des informations ci-dessus
        self::setupView();
        self::setupAcl();        
        self::setupMenu();        
           self::initProfiling(false);                //-- Profiling de la db

Si j'aurai voulu ajouter une fonction ou variable globale, je l'aurai mis en static ici.

Dernière modification par whitespirit (27-06-2008 07:12:39)

Hors ligne

 

#4 27-06-2008 09:37:36

Bast
Membre
Date d'inscription: 07-06-2007
Messages: 138

Re: [Résolu] Fonctions globales : où les placer ?

Merci Philippe, mais en passant par un singleton, je devrai appeler mes fonctions de cette manière :
$mon_singleton->__fonction() ;
Or, je voudrais y accéder de partout en ne faisant que :
__fonction() ;

White : c'est pas bien de chambrer ta copine !! yikes
Tu lances le run() de Scholastie dans ton bootstrap ? Ce fameux run() appelle toutes tes fonctions self::bla() ?

Je ne vois pas bien comment implémenter mes fonctions statiques dans scholastie, ni comment les rendre accessibles à toutes les autres classes... Tu aurais un exemple ?

Merci ^^

Hors ligne

 

#5 27-06-2008 10:11:14

philippe
Administrateur
Lieu: Grenoble
Date d'inscription: 01-03-2007
Messages: 1624

Re: [Résolu] Fonctions globales : où les placer ?

Bonjour Bast,

En fait c'est pire que ce que tu dis, dans un code tu appelles ta fonction par :

Code:

MonSingleton::getInstance()->__fonction();

cela dit ça a 2 intérêts :
- ça sépare bien le code. Si tu veux regrouper 2 sites en un, tu n'as pas à dédoublonner tes fonctions globales
- si certains fonctions "globales" on besoin d'être initialisées, tu peux les initialiser dans ton bootstrap en injectant les données dans ton objet (tu peux chercher "injection de dépendance" dans google, tu auras encore quelques millions de réponses).

Bon... sur un petit projet ta méthode marche aussi bien... te prends pas forcément la tête là dessus, mais garde dans un coin de ta tête le fait que ça existe pour un plus gros projet smile

A+, Philippe


twitter : @plv ; kitpages.fr : Création de sites internet à Grenoble et Paris

Hors ligne

 

#6 27-06-2008 10:14:18

Bast
Membre
Date d'inscription: 07-06-2007
Messages: 138

Re: [Résolu] Fonctions globales : où les placer ?

Qu'appelles tu par "initialiser" une fonction ?

Ce ne sont pas de petits projets. Et il y en a un paquet (une 10 aine de sites, au bas mot)

-> je vais faire des recherches sur l'injection de dépendances (mais déjà l'expression me déplait, je hais les dépendances xD )

Edit : ok je vois ce que c'est. Sauf que je ne sais pas vraiment en quoi l'injection de dépendances m'aiderait dans ce cas là !
Ma seule demande, c'est : Comment faire pour appeler mes fonctions directement, sans $un_objet->, ou pire, UneClasse::getInstance()-> devant ?

Dernière modification par Bast (27-06-2008 10:31:22)

Hors ligne

 

#7 27-06-2008 10:35:14

philippe
Administrateur
Lieu: Grenoble
Date d'inscription: 01-03-2007
Messages: 1624

Re: [Résolu] Fonctions globales : où les placer ?

Justement l'injection de dépendance permet d'avoir le projet global qui ne dépend pas des "classes outils" qu'il utilise...

Le problème posé :
Imagine une classe qui se charge d'écrire des logs. Tu peux décider de dire le répertoire de logs c'est LOG_DIR et je code ma classe en mettant la constante LOG_DIR en dur dedans.
Le problème est que le fonctionnement de ta classe impose au site la présence de la constante LOG_DIR, tu as donc une dépendance de ton site à ton système de logs.

La solution : l'injection de dépendance (ou inversion de contrôle, tu trouveras les 2 dans la littérature)
dans ta classe de logs, tu crées une méthode setLogDir($dir).
Dans ce cas ta classe de log n'impose rien au reste du site, c'est le site qui dit à la classe de log que le répertoire est celui ci ou celui là.

un autre exemple : le routeur du ZF :
Dans son code, le ZF utilise de façon systématique l'injection de dépendance. Par exemple ton routeur n'impose rien à ton appli, c'est ton bootstrap qui injecte les données dans le routeur. Tes données de routage, peuvent être dans un config.ini, des constantes ou n'importe quoi, le routeur s'en fout... c'est en ça que ton appli est beaucoup plus indépendante de ton routeur...

Sinon ce que j'appelle un gros projet, c'est un projet avec plusieurs développeurs avec chaque développeur qui doit faire évoluer le code des autres de temps à autre... là si le code n'est pas très standard et formalisé, on met 2 fois plus de temps à le reprendre. Accessoirement ça peut donner des envies de meurtre assez récurrentes smile

A+, Philippe

Dernière modification par philippe (27-06-2008 10:36:03)


twitter : @plv ; kitpages.fr : Création de sites internet à Grenoble et Paris

Hors ligne

 

#8 27-06-2008 10:39:05

philippe
Administrateur
Lieu: Grenoble
Date d'inscription: 01-03-2007
Messages: 1624

Re: [Résolu] Fonctions globales : où les placer ?

Pour ton problème en particulier... un include dans ton bootstrap avec les fonctions globales dedans... ça marche bien smile
A+, Philippe


twitter : @plv ; kitpages.fr : Création de sites internet à Grenoble et Paris

Hors ligne

 

#9 27-06-2008 10:41:03

Bast
Membre
Date d'inscription: 07-06-2007
Messages: 138

Re: [Résolu] Fonctions globales : où les placer ?

Ce que tu viens d'expliquer, nous l'appliquons déjà dans nos scripts. On fait tout pour virer un maximum de dépendances (notamment, comme tu l'as fait remarquer, les constantes qui ne doivent surtout pas être ne dur dans le code, mais externalisées).
J'ai parfaitement compris tes explications.

Edit : Après lecture de ton deuxième post, la phrase suivante n'a plus lieu d'être :
Cependant, je n'ai toujours pas compris où écrire le code de mes fonctions, ni comment, au final, les appeler nativement...


Merci à tous pour votre aide ! smile

Dernière modification par Bast (27-06-2008 10:43:44)

Hors ligne

 

#10 27-06-2008 11:46:53

whitespirit
Membre
Date d'inscription: 25-01-2008
Messages: 393

Re: [Résolu] Fonctions globales : où les placer ?

Entre temps vous avez bien discuter à ce sujet, donc je ne sais pas si ma solution est toujours d'actualité. Dans le doute je te donne plus de détail :
- en dehors des includes dans mon index.php j'ai donc uniquement Scholastie::run() (serieux, scholastie !!!! mais heureusement que c'est son deuxième prénom, et que le premier ne soit pas Robert) dont voici le code (je n'ai volontairement pas épuré le code pour que tu vois concrètement ce qu'il y'a exactement à l'intérieure des principales fonctions)

Code:

    /**
     * Lance l'application après avoir initialisé les variables
     *
     */
    public static function run()
    {
        self::setupEnvironment();
        self::prepare();
        try {
            $response = self::$frontController->dispatch();
            self::sendResponse($response);
            
            //===========================================
            //    Si le profiling de db est activé
            //===========================================
            if (self::$is_profiling_on == true)
            {
                $db = self::$registry->database;
                $start = microtime(true); 
                $longestTime  = 0;
                $longestQuery = null;
                $end = microtime(true) - $start; // ici du capture le temps d'execution total du script (code+bdd)
                $profiler = $db->getProfiler();
                foreach ($profiler->getQueryProfiles() as $query) {
                    if ($query->getElapsedSecs() > $longestTime) {
                        $longestTime  = $query->getElapsedSecs();
                        $longestQuery = $query->getQuery();
                    }
                }
                $totalTime    = $profiler->getTotalElapsedSecs();
                $queryCount   = $profiler->getTotalNumQueries();
                echo "totalTime :$totalTime <br /> queryCount : $queryCount <br> Requête plus longue : $longestQuery";
            }
            
        }
        catch (Exception $exception) 
        {
            exit(    $exception->getMessage().'<br/>'.
                    $exception->getfile().' à la ligne '.
                    $exception->getLine().'<br/>'    
                );
        }
    }    

    /**
     * Setup de l'environnement
     *
     */
      public static function setupEnvironment()
    {
        error_reporting(E_ALL|E_STRICT);
        date_default_timezone_set('Europe/Paris');
        ini_set('session.save_path', './data/sessions');
        Zend_Session::start();
        self::$scholastieNamespace = new Zend_Session_Namespace(self::$TXT_NAME_SESSION);
        self::$root = dirname(dirname('<u>_FILE_</u>'));
    }
   
    /**
     * Appel tous les autres setup et charge les paramètres d'applications
     *
     */
    public static function prepare()
    {
        //****************************************************************
        //            PARAMETRE DE CONFIGURATION A PLACER DANS LE FICHIER INI
        //****************************************************************
        $type_checkbox_liste = TK_CB_CHECK;
        Zend_Registry::set('type_checkbox_liste', $type_checkbox_liste);    
        Zend_Loader::registerAutoload();    
        
        self::setupFrontController();
        self::setupConfiguration();
        self::setupRoute();
        self::setDefaultController();
        self::setupCache();
        self::setupRegistry();
        self::setupListBD();
        
        self::setupIni_DbSectionName();            //-- charge les paramètres de la base de données à utiliser
        
        self::setupDatabase();                    //-- charge la base de données en prenant compte des informations ci-dessus
        self::setupView();
        self::setupAcl();        
        self::setupMenu();
        
           self::initProfiling(false);                //-- Profiling de la db

    }

Je ne sais pas ce qu'en pense les puristes, moi je n'en suis pas un. Mais cette solution réponds à mes besoins (pour l'instant). Le seul truc important c'est que tous les paramétres sont chargés dans un fichier .ini, et que j'ai une conception modulaire (au sens propre et non ZF) ce qui veut dire que rien n'est dépendant. Ceci dit, quand j'ai commencé à codé je ne connaissais pas design pattern Singleton sad

Hors ligne

 

Pied de page des forums

Propulsé par PunBB
© Copyright 2002–2005 Rickard Andersson
Traduction par punbb.fr

Graphisme réalisé par l'agence Rodolphe Eveilleau
Développement par Kitpages