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 »).