2010-03-15 16 views
2

Je veux simplement définir une fonction dans application.cfc et l'exposer à toutes les demandes. De préférence, "l'affectation" ne se produirait qu'au démarrage de l'application.Quelle est la bonne façon d'assigner un fichier uf général à application.cfc?

est la méthode préférée pour faire quelque chose le long des lignes de celle-ci:

<CFCOMPONENT OUTPUT="FALSE"> 
<CFSET this.name = "Website"> 
<CFSET this.clientManagement = true> 
<CFSET this.SessionManagement = true> 

<CFFUNCTION NAME="GetProperty" OUTPUT="False"> 
    <CFARGUMENT NAME="Property"> 

    <CFRETURN this.Props[Property]> 
</CFFUNCTION> 

<CFFUNCTION NAME="OnApplicationStart" OUTPUT="FALSE"> 
    <CFSET Application.GetProperty = GetProperty> 
. 
. 
. 

ou est-il quelque chose de mieux?

Répondre

2

La meilleure façon de site stocker les données de configuration spécifique va probablement être de créer un nouveau composant nommé quelque chose comme SiteConfig .cfc avec des méthodes telles que getProperty (propertyName) et setProperty (propertyName, value). Vous pouvez ensuite stocker ce CFC dans le champ d'application en procédant comme suit dans la méthode onApplicationStart de Application.cfc comme:

<cfset application.siteConfig = createObject("component", "SiteConfig").init() /> 

Retour à votre question initiale si sur le stockage d'une UDF dans le champ d'application, ci-dessous est un moyen de faire cette. La base est que dans onApplicationStart vous allez créer une nouvelle structure persistante d'application avec les propriétés de configuration de votre site comme siteName et tout le reste. Ensuite, une fonction est stockée dans un fichier CFM qui n'est inclus que dans onApplicationStart, puis copié dans la portée de l'application. Cela signifie que tous vos fichiers CFM de page standard peuvent utiliser application.getProperty (propertyName). Étant donné que la fonction n'est créée qu'une seule fois et stockée dans la portée de l'application, elle répond aux exigences de votre question initiale concernant "l'affectation ne se produirait qu'au démarrage de l'application".

Espérons que cela aide un peu!

getProperty.function.cfm

<cffunction name="getProperty" output="false"> 
    <cfargument name="propertyName" type="string" required="true" /> 
    <cfreturn application.config[propertyName] /> 
</cffunction> 

Application.cfc

<cffunction name="onApplicationStart" output="false"> 
<cfset application.config = structNew() /> 
<cfset application.config.siteName = "My App's Display Name" /> 
<cfinclude template="getProperty.function.cfm" /> 
<cfset application.getProperty = variables.getProperty /> 
</cffunction> 

test.cfm

<cfset propertyValue = application.getProperty("siteName") /> 
<cfdump var="#propertyValue#" /> 
+0

Merci Greg. Essentiellement, il s'agit d'une base de code qui va exécuter plusieurs sites Web et changer en fonction de l'URL. Ainsi, un site particulier aura des informations spécifiques à lui-même (nom du site, par exemple). –

+0

Merci pour les infos supplémentaires Tom. J'ai mis à jour la réponse ci-dessus. Pas sûr de la meilleure façon de gérer plusieurs sites à partir d'une base de code unique, mais espérons que cela vous aide le long de votre chemin. – sqrl0

+0

Merci Greg. C'est génial, cela répond à la question et donne une meilleure façon de le faire. –

2

Par défaut, GetProperty sera déjà visible dans la portée Variables, cela peut être suffisant pour de nombreuses utilisations (dans les modèles .cfm).

Si vous souhaitez utiliser ces méthodes directement dans les composants, il est recommandé de les référencer dans la portée Application. Bien que je le fasse avec l'étendue de demande dans onRequestStart(), c'est juste ma préférence personnelle. Quelque chose comme ceci:

request.udf = {}; 
request.udf.halt = halt; 

S'il vous plaît noter que les meilleures pratiques en général est incapsulating les objets et les ayant fait référence dans les variables portée de l'objet hôte. Je le fais généralement lors de l'initialisation de l'objet, il suffit de passer les objets précédemment créés en arguments init().

P.S. De nos jours, il est recommandé d'utiliser des minuscules pour les étiquettes et leurs attributs. Genre de bonnes pratiques de codage.

+0

Nous utilisons onRequestStart qui, je crois, ne met pas automatiquement la fonction dans la portée des variables. –

+0

Si vous voulez dire ma première phrase, CF le fait par défaut, simplement parce que vous avez créé la méthode dans Application.cfc – Sergii

+0

Ce lien explique ce que je disais. Essentiellement, l'appel cfm aura seulement les fonctions dans la portée variable si vous utilisez la méthode onRequest car elle utilise cfinclude: http://www.bennadel.com/blog/805-ColdFUsion-Application-cfc-OnRequest-Creates-A- Component-Mixin.htm –

0

Vous pourriez envisager de créer un « propriétés » séparées CFC et instancier comme un singleton dans le champ d'application de serveur, il sera disponible sur toutes les pages CFML même si elle ne fait pas partie d'une application. Si vous suivez cette route, il n'y a pas d'événement "serveur start" à lier. vous pouvez plutôt mettre cela dans le contructor de application.cfc ou dans le corps de application.cfm

<cfif not structkeyexists(server,"properties")> 
     <cflock name ="loadProperties" 
      timeout ="10" 
      type ="exclusive" 
     > 
      <cfif not structkeyexists(server,"properties")> 

       <cfset server.properties = 
        createObject("component","path-to-props.cfc") 
        .init({..inital properties..}) 
       > 
      </cfif> 
     </cflock> 
    </cfif> 

Le code de verrouillage est d'empêcher la surcharge de créer et assigner l'UDF à chaque requête . Cela permet également les propriétés par exemple de persister afin que d'avoir une fonction properties.SetProperty() fonctionnera

0

vous pourriez aussi wa nt pour utiliser la technique discutée here