• Home
  • Docker
  • Kubernetes
  • LLMs
  • Java
  • Ubuntu
  • Maven
  • Big Data
  • Archived
ColdFusion | Portée des variables
  1. Introduction
  2. La portée des variables
  3. Les structures prédéfinies de ColdFusion

  1. Introduction
    Les variables définies dans les pages ColdFusion ont toutes une portée (scope) qui détermine leurs durées de vie ainsi que leurs visibilités dans le code. Par exemple une variable déclarée dans une page avec la portée « REQUEST » est accessible dans cette page et dans toutes les pages qui y sont incluses. ColdFusion génère une exception quand il échoue à résoudre la portée d'une variable, typiquement vous obteniez l'erreur suivante « Variable VAR_NAME IS UNDEFINED ».

    L'objectif de ce chapitre est d'expliquer le concept de la portée des variables ainsi que décrire les différentes structures prédéfinies et leurs portées dans ColdFusion.
  2. La portée des variables
    Généralement, lorsqu'on parle de portée d'une variable, on fait référence à la durée de vie d'une variable et aux blocs du code où elle est accessible.

    Certaines variables ont une durée de vie limitée au bloc du code où elles sont définies, et par conséquent la propriété durée de vie est étroitement liée à la propriété d'accessibilité. Par exemple, une variable déclarée dans une fonction en utilisant le mot clé « var » n'est pas accessible à l'extérieur de cette fonction et vit le temps d'exécution de la fonction.

    D'autres variables peuvent avoir une durée de vie qui ne dépend pas du bloc du code ou elles sont déclarées ; typiquement ces variables sont associées à des structures prédéfinies par le serveur et par conséquent la durée de vie et l'accessibilité de ces variables dépendent de la durée de vie et l'accessibilité de la structure au quelle elles sont attachées. Par exemple, une variable définie dans la portée « REQUEST » est accessible dans la page où elle a été définie ainsi que dans toutes les autres pages impliquées par la requête http. La durée de vie de la variable dans ce cas est limitée au temps d'exécution de la requête, c.-à-d. elle vit du moment où elle a été définit jusqu'à ce que la réponse complète de la requête soit envoyée au client. Pour une durée de vie plus longue, vous utiliseriez la portée « SESSION » dans laquelle la variable est accessible à l'ensemble des pages de l'application Web courante et vit tant que la session utilisateur n'a pas expirée.

    Dans ce qui suit, je ne vais pas faire de distinction entre la portée et la structure préfinie. En fait, l'implémentation d'une portée (exemple « VARIABLES ») passe par l'utilisation d'une structure prédéfinie (dans ce cas « VARIABLES »).
  3. Les structures prédéfinies de ColdFusion
    ColdFusion crée automatiquement plusieurs structures qui peuvent être utilisées pour lire et écrire des données. Chaque structure correspond à une portée bien précise et ainsi une variable attachée à une structure a par défaut la même portée de cette structure.

    Typiquement une variable est définie et attachée à une structure (implicitement à une portée) en utilisant la syntaxe MY_SCOPE.MY_VARIABLE (par exemple SESSION.VAR1, REQUEST.STRUCT2.VAR2, … etc.).
    Attention, l'ajout du point indique au ColdFusion que la variable qui précède le point est une structure, ce qui veut dire, qu'en cas d'initialisation (en utilisant le mot clé CFSet) ColdFusion crée automatiquement une structure au nom de cette variable (par exemple, ColdFusion va créer automatiquement une structure avec le nom « STRUCT2 » à laquelle il attachera la variable « VAR2 »).

    Seul exception pour cette règle est la portée « CLIENT » et « COOKIE » qui n'acceptent que des variables simples. Par exemple dans « CLIENT.NOTSTRUCT.VAR3 » la totalité de la chaine de caractères « NOTSTRUCT.VAR3 » est considérée comme nom de la variable ; en fait dans ce cas le point n'est pas considéré comme un séparateur, mais plutôt comme n'importe quel autre caractère autorisé pour nommer des variables simples.

    a) Les portées Globales : « REQUEST », « SESSION », « CLIENT », « APPLICATION », et « SERVER »

    Je considère les portées « REQUEST », « SESSION », « CLIENT », « APPLICATION », et « SERVER » comme globales, car les variables définies dans ces portées sont visibles et accessibles dans tout le code de l'application (incluant toutes les pages CFM, les tags personnalisés, et les CFCs). La seule différence entre ces portées, comme vous allez le voir ci-après, est la durée de vie des variables qui y sont définies.

    • REQUEST :
      La portée « REQUEST » est créée à la réception d'une requête http.
      La portée « REQUEST » est créée avant la création de la portée « SESSION » et « APPLICATION ».
      La portée « REQUEST » est détruite quand traitement de la requête http est terminé.

      Une variable définie dans cette portée vit du moment où elle a été créée jusqu'à ce que le traitement de la requête http soit terminé. Les variables « REQUEST » sont visibles et accessibles dans la page cible de la requête http ainsi que toutes les sous pages et tags incluses dans cette page.

      TODO : Quand utiliser la portée « REQUEST » ?

      TODO : Vérifier et tester s'il est plus performant de gérer les variables de traduction en utilisant les fichiers « properties ». Aussi vérifier et tester s'il est plus performant d'utiliser la portée « APPLICATION », au lieu de la portée « REQUEST », pour gérer ces variables. Peut être le problème ici et que dans le cas où on utiliserait plusieurs langues au même temps, ça pourrait surcharger la mémoire du serveur. Il faut aussi noter qu'avec la portée « REQUEST » on peut facilement mettre à jour les variables de traductions.

      Voici la note d'Adobe concernant ce point:
      « If many users access the application simultaneously and you use Application scope variables extensively, your application performance might degrade. If your application uses many application variables, consider whether the variables must be in the Application scope or whether they can be Session or Request scope variables. »

    • SESSION :
      La portée « SESSION » est créée après la création de la portée « APPLICATION ».
      La portée « SESSION » est détruite quand le durée passée depuis la dernière requête reçue par le serveur est supérieur au temps d'expiration définit pour la portée « SESSION ».

      La portée « SESSION » est privée à un utilisateur. Deux utilisateurs ne peuvent pas utiliser la même variable de la structure « SESSION », chacun obtient une instance distincte de la structure « SESSION ». Ainsi les modifications faites par un utilisateur sur une variable de la portée « SESSION » ne sont pas visibles par les autres utilisateurs.
      Une variable définie dans cette portée vit du moment où elle a été créée jusqu'à ce que la session soit annulée ou terminée, ou que le temps limite défini pour cette portée est atteint ou que l'application n'est plus accessible.
      Les variables « SESSION » sont visibles et accessibles dans toutes les pages d'une application (incluant les tags personnalisés et les CFCs).

      TODO : Quand utiliser la portée « SESSION » ?

    • CLIENT :
      La portée « CLIENT » est une extension de la portée « SESSION » ; ainsi les variables définies dans cette portée peuvent être sauvegardées et restaurées entre plusieurs sessions. Les variables « CLIENT » sont uniques pour chaque utilisateur et elles sont visibles et accessibles dans toutes les pages d'une application (incluant les tags personnalisés et les CFCs). Les variables « CLIENT » peuvent être sauvegardées dans une base de registre, cookies, ou base de données.

      TODO : Quand utiliser la portée « CLIENT » ?

    • APPLICATION :
      La portée « APPLICATION » est créée après la création de la portée « REQUEST » mais avant la portée « SESSION ».
      La portée « APPLICATION » est créée uniquement quand le fichier « application.cfc » est exécuté ou quand le tag <application> est appelé.
      La portée « APPLICATION » est détruite quand le durée passée depuis la dernière requête reçue par le serveur est supérieur au temps d'expiration définit pour la portée « APPLICATION ».

      Une variable définie dans cette portée vit du moment où elle a été créée jusqu'à ce que le temps limite défini pour cette portée est atteint ou que l'application n'est plus accessible (arrêt de déploiement de l'application ou arrêt du serveur). Les variables de la portée « APPLICATION » sont privées à l'application où elles étaient créées ; elles sont visibles et accessibles dans toutes les pages (incluant les tags personnalisés et les CFCs) de cette application.

      TODO : Quand utiliser la portée « APPLICATION » ?

    • SERVER :
      La durée de vie de cette portée est celle du serveur, c.-à-d. qu'elle vit du moment où le serveur est démarré jusqu'à son arrêt. En ce qui concerne la visibilité ou l'accessibilité des variables attachées à cette structure, elle est globale à toutes les applications déployées sur le serveur. Donc dans toutes les pages (incluant les tags personnalisés et les CFCs) vous pouvez déclarer, initialiser, et lire la valeur des variables de la structure « SERVER ».
      Il faut noter que la portée « SERVER » est unique à l'instance du serveur et donc à ne pas utiliser si ColdFusion est installé sur un serveur Cluster.

      TODO : Quand utiliser la portée « SERVER » ?
    Remarque (1) : Si vous devez modifier des variables partagées (que ce soit celles de la portée SERVER, APPLICATION, SESSION, ou CLIENT), il faudra protéger le code qui modifie ces variables en utilisant le tag CFLock à cause qu'il y a un risque des accès concurrents.

    Remarque (2) : ColdFusion attache par défaut quelques variables à certaines structures prédéfinies (comme SERVER) qui sont accessibles en lecture seule uniquement. Vous ne pouvez pas modifier les valeurs de ces variables : vous obtiendrez dans ce cas une erreur qui vous informe que vous ne pouvez pas modifier ou supprimer une variable accessible en lecture seule « ATTEMPTED TO UPDATE OR DELETE A READ-ONLY VARIABLE ».

    b) Les portées locales : « VARIABLES », « LOCAL », « CALLER », « THIS », « ARGUMENTS», et « ATTRIBUTES »

    Je considère les portées « VARIABLES », « LOCAL », « CALLER », « THIS », « ARGUMENTS», et « ATTRIBUTES » comme locales, car les variables définies dans ces portées sont visibles et accessibles dans un bloc du code plus restreindre.

    • VARIABLES :
      C'est la portée par défaut de toutes les variables définies avec le tag CFSet ou CFParam et qui ne sont associées à aucune portée.

      Une variable définie dans une page CFM et qui a la portée « VARIABLES » est visible et accessible dans toutes les pages CFM. Cette variable vit du moment où elle a été créée (typiquement quand une requête http est faite sur la page qui déclare cette variable) jusqu'à ce que la réponse soit envoyée au client.

      Les variables définies dans un tag personnalisé (custom tag) sont privées à ce tag et donc ne sont pas accessible à l'extérieur de ce tag. Un tag personnalisé peut toute fois accéder aux variables de la page mère (ou tag parent) en utilisant la structure « CALLER ».

      De même les variables définies dans un CFC sont accessibles uniquement au CFC et ses fonctions.

      Voici un exemple de déclaration de variables qui auront une portée « VARIABLES » :

      Les deux variables, dans l'exemple précédent, vont avoir la portée « VARIABLES » mais les deux syntaxes sont différentes dans la mesure où dans le premier exemple la variable « var1 » va être attachée à la structure prédéfinie « VARIABLES » alors que la variable « var2 » va avoir sa propre déclaration dans le code Java généré : ColdFusion va ajouter pour chaque variable une déclaration du genre « private Variable VAR2 » (où Variable est une classe préfinie Java dans ColdFusion).

      Enfin, il faut faire attention à cette déclaration :

      Dans cet exemple ColdFusion crée une variable (structure) « mystruct3 » (si inexistante) à la quelle la variable « var3 » sera attachée. La portée de la variable « mystruct3 » est la portée « VARIABLES ».

      TODO : Quand utiliser la portée « VARIABLES » ?

      TODO : tester si ce n'est pas plus performant d'utiliser toujours le préfixe « VARIABLES » pour déclarer les variables.

    • LOCAL :
      Disponible uniquement à l'intérieur des fonctions et vit tant que la fonction s'exécute. Il est possible d'utiliser la structure « LOCAL » dans les pages CFM mais elle est considérée comme n'importe quel structure créée par le développeur et dont la portée est celle de « VARIABLES ». Considérant l'exemple suivant :

      Si vous pensiez que la variable « var4 » va avoir la portée « LOCAL » alors vous vous trempiez : Vu que cette instruction n'est pas à l'intérieur d'une fonction, ColdFusion va tout simplement créer une variable structure dont le nom est « LOCAL » (implicitement la portée est celle de « VARIABLES ») et ensuite il va attacher la variable « var4 » à cette structure « LOCAL ».

      Il est aussi possible de déclarer des variables qui ont une portée limitée au temps d'exécution de la fonction et accessible uniquement à l'intérieur de celle-ci en utilisant le mot clé « var » :

      Remarques :
      • Le mot clé « var » peut être utilisé uniquement à l'intérieur des fonctions. Sinon ColdFusion générera l'erreur suivante : « The local variable bookID cannot be declared outside of a function. All variables defined with the var keyword must be declared inside a function. »

      • Par contre, le mot clé « LOCAL » peut être utilisé n'importe où dans le code, mais il ne va correspondre à la structure prédéfinie « LOCAL » que s'il est utilisé dans le code de la fonction.

      • Avec la version 9 de ColdFusion, il n'est plus obligatoire de déclarer les variables locales au top de la fonction (que ces soit avec le mot clé « var » ou « LOCAL »).

    • CALLER :
      Utilisée uniquement dans les tags personnalisées, et permet d'accéder (ajouter et modifier) à toutes les variables de la portée « VARIABLES » de la page mère.

    • THIS :
      Cette structure existe uniquement dans les CFC ou les fonctions qui sont déclarées dans des objets tels que les structures ColdFusion. Elle existe tant que l'instance de l'objet qui lui appartient existe. Les variables déclarées dans cette structure sont accessible dans les autres pages en utilisant l'instance ou le nom de l'objet comme préfixe.

    • ARGUMENTS :
      Contient les variables passées en paramètres lors de l'appel d'une fonction.

    • ATTRIBUTES :
      Contient les variables passées en paramètres lors de l'appel d'un tag personnalisé ou un thread.

    c) Des portées "spéciales" : « URL », « FORM », et « CGI »

    Les variables définies dans les portées « URL », « FORM », et « CGI » sont visibles et accessibles dans tout le code de l'application (incluant toutes les pages CFM, les tags personnalisés, et les CFCs).
    Les valeurs de ces variables sont initialisées automatiquement par ColdFusion et permettent de savoir l'état de l'application du client (typiquement un navigateur) à la dernière requête http reçue par le serveur.
    À mon avis, elles doivent être utilisées en lecture seule uniquement !

    • URL :
      Contient la liste de tous les paramètres de l'URL (méthode http GET).

    • FORM :
      Contient la liste de tous les paramètres d'un formulaire de la page (méthode http POST).

    • CGI :
      Contient des informations sur la requête (données client et serveur).
    Remarque : Toutes ces structures sont créées et initialisées automatiquement par ColdFusion en fonction du contexte d'exécution du code (par exemple, la structure « CALLER » est créée uniquement à l'appel d'un tag personnalisé), à l'extérieur du contexte de création et d'initialisation de chaque structure, ces structures sont inexistantes!
    • Et donc si vous essayez de lire à partir de ces structures ( <cfset var1 = ARGUMENTS.var4 /> ), vous obteniez une erreur ( Element VAR4 is undefined in ARGUMENTS. ).
    • Par contre, si vous modifier ces structures ( <cfset ATTRIBUTES.var4 = "valeur4" /> ), alors ColdFusion va les considérer comme n'importe quelle autre structure créée par le développeur et ColdFusion va tout simplement les attacher à la structure « VARIABLES » (voir l'exemple de la structure « LOCAL »).
© 2025  mtitek