In addition to the basic functionality reviewed thus far, advanced CFC features are also available. ScopesAll the invocation examples reviewed thus far instantiate CFCs without specifying a scope. In other words, they used the default VARIABLES scope (just as <cfset> would if no scope is specified). CFCs can also be loaded into these other scopes so as to make them persist:
NOTE CFCs cannot be loaded into the CLIENT scope, as CLIENT does not support complex data types. The advantages of persistent CFCs are that they need not be reloaded, and that they can contain data and state within themselves that persists in between requests. Loading a CFC into a shared scope requires that it be loaded as an object (using <cfobject> or CreateObject() as reviewed above). The example below uses <cfobject> to load a CFC into a users SESSION scope: <!--- Load CFC as an object ---> <cfobject component="user" name="SESSION.userObj"> <!--- Invoke method ---> <cfinvoke component="#SESSION.userObj#" method="Get" returnvariable="user_id"> Using code like this, each user (each SESSION) can have its own instance of a component. TIP Generally CFCs should not access specific scopes (like SESSION). Rather, the CFC itself should be instantiated in a scope whenever possible. The THIS ScopeWithin a CFC there is a special scope named THIS. THIS persists for as long as the CFC persistsif loaded as an object, then THIS will persist for as long as the object persists; if loaded with a simple <cfinvoke>, then THIS will persist for a single request only. To set a variable in THIS, simply use the THIS prefix: <cfset THIS.user=StructNew()> <cfset THIS.user.NameFirst="Ben"> <cfset THIS.user.NameLast="Forta"> THIS is automatically available to all functions in a component, so a data set in one function (or in the constructor, as seen below) can be accessed in other functions. NOTE Each instance of a CFC has its own THIS scope, so if a CFC is loaded into a users SESSION, each user will have a separate THIS. The VARIABLES ScopeCFML is not an object-oriented language, but CFCs do share traits with objects, and do support some object-type features. But unlike objects in typical object oriented languages, THIS within the CFC is not private. That is to say that code that instantiates a CFC as an object can access CFC THIS scope members. To keep CFC internal data private, use the VARIABLES scope inside of the CFC instead of THIS. ConstructorsIn object-oriented development, constructors are specials functions that are automatically executed when an object is instantiated. Constructors are often used for initialization, validation, and error-checking. In CFCs, constructors are supported as follows: any code within a <cfcomponent> but not within a <cffunction>, is constructor code. Consider the following example: <cfcomponent> <cfset THIS.user=StructNew()> <cffunction name="Get"> <cfargument name="id"> <cfset result=""> ... <cfreturn result> </cffunction> </cfcomponent> The above snippet is a CFC with a single method named Get. The <cfset> statement (second line) is constructor code, which will be executed automatically when the CFC is instantiated. So when will the constructor code be executed? That depends:
Constructor code may be used to store data in THIS or VARIABLES, which makes it available to all CFC methods. NOTE Destructors are not supported by CFCs. InheritanceInheritance is another object oriented feature that has made its way into CFML. Inheritance allows code to be reused by basing a CFC on another CFC. For example, the user.cfc snippet used throughout this chapter contains methods for interacting with users. If an additional CFC was needed for a special class of user, an administrator, the new CFC could be based on the old one by simply using the following syntax: <!--- admin.cfc file ---> <cfcomponent extends="user"> ... </cfcomponent> Using the above syntax, the methods and functionality defined in user.cfc would also be available to admin.cfc (but not vice-versa). This way the base CFC can be extended. A single CFC can be extended multiple times (multiple CFCs can extend it). In addition, nested inheritance is supportedso the admin.cfc created above could be extended (another CFC could extend it). NOTE Multiple inheritance is not supported. |