Restricting your functions to scopes
Imagine we are sending some data through to a login page in our application within the URL
scope; the first and last name of a particular person. On the page, we want to join the two values and combine them into one string to form the individual's full name. We could write the code directly on the page, as follows:
<cfoutput> Hello, #URL.firstName# #URL.lastName# </cfoutput>
Listing 1.7 displaying URL variables as a string
Although this works, you can revise the code and transform it into a ColdFusion function to concatenate the two values into the required single string and return that value:
<cffunction name="getName"> <cfset var strFullName = URL.firstName & ' ' & URL.lastName /> <cfreturn strFullName /> </cffunction>
Listing 1.8 concatenate variables into string
You can then call this function within your .cfm
page to output the resulting string from the function:
<cfoutput> #getName()# </cfoutput>
However, within this code you have restricted yourself to using only the specific URL
scope. What if the first name and last name values were in the FORM
scope, or pulled from a query? This block of code is useful only for values within the form scope.
Using arguments within your methods
To allow us to be able to pass in any parameters into the getName()
function, we need to use the cfargument
tag to send data into the method. By changing the function in the following code example, the method will create the concatenated string and produce the same results from two parameters or arguments that you choose to pass in.
<cffunction name="getName"> <cfargument name="firstName" type="string" /> <cfargument name="lastName" type="string" /> <cfset var strFullName = arguments.firstName & ' ' & arguments.lastName /> <cfreturn strFullName /> </cffunction>
Listing 1.10 using arguments within your function
The cfargument
tag creates a parameter definition within the component method, and allows you to send in arguments for inclusion into the functions.
The Arguments scope
The Arguments
scope only exists in a method. The scope contains any variables that you have passed into that method, and you can access the variables within the Arguments
scope in the following ways:
using structure notation -
Arguments.variablename
orArguments["variablename"]
using array notation -
Arguments[1]
Note
The Arguments scope does not persist between calls to available CFC methods, meaning that you cannot access a value within the Arguments scope in one function from inside a different function.
Redefine the function parameters
By defining two arguments and sending in the values for the first and last names, you have created an unrestricted function that is not tied to a specific scope or set of hardcoded values. You can instead choose what values to pass into it on your calling page:
<cfoutput> #getName('Gary', 'Brown')# </cfoutput>
Lsiting 1.11a sending parameters into our function
Now that we have removed any restrictions to the values we pass in, and taken away any references to hardcoded variables, we can reuse this function, sending in whichever values or variables we choose to. For example, we could use variables from the FORM
scope, URL
scope, or query items to concatenate the string:
<cfoutput> #getName(form.firstName, form.lastName)# </cfoutput>
Listing 1.11b sending parameters into our function
Let's take our getName()
method and add it into the greeting.cfc
file. By doing so, we are grouping two methods that have a similarity in purpose into one component. This is good programming practice and will aid in creating manageable and clearly organized code.
Our greeting.cfc
should now look like this:
<cfcomponent name="greetings"> <cffunction name="sayHello"> <cfset var strHelloMessage = 'Hello World!' /> <cfreturn strHelloMessage /> </cffunction> <cffunction name="getName"> <cfargument name="firstName" type="string" /> <cfargument name="lastName" type="string" /> <cfset var strFullName = arguments.firstName & ' ' & arguments.lastName /> <cfreturn strFullName /> </cffunction> </cfcomponent>
Listing 1.12 revised greeting.cfc
Combining your methods
As we have seen, you can easily access the methods within a defined CFC and output the data in a .cfm
template page.
You can also easily access the functionality of one method in a CFC from another method. This is particularly useful when your component definition contains grouped functions that may have a relationship based upon their common purpose.
To show this, let's create a new method that will use the results from both of our existing functions within the greetings.cfc
file. Instead of displaying a generic "Hello World" message, we will incorporate the returned data from the getName()
method and display a personalized greeting.
Create a new method within the CFC, called personalGreeting.
<cffunction name="personalGreeting"> <cfargument name="firstName" type="string" /> <cfargument name="lastName" type="string" /> <cfscript> strHello = sayHello(); strFullName = getName(firstName=arguments.firstName, lastName=arguments.lastName); strHelloMessage = strHello & ' My name is ' & strFullName; </cfscript> <cfreturn strHelloMessage /> </cffunction>
Listing 1.13 personalGreeting
method
Within this method, we are calling our two previously defined methods. The returned value from the sayHello()
method is being stored as a string variable, "strHello
".
We then retrieve the returned value from the getName()
method and store this in a string variable "strFullName". As we have written the getName()
function to accept two arguments to form the concatenated name string, we also need to add the same two arguments to the personalGreeting()
method, as done in the previous code. They will then be passed through to the getName()
method in exactly the same way as if we were calling that function directly.
Using the two variables that now hold the returned data, we create our strHelloMessage
variable, which joins the two values, and is then returned from the method using the cfreturn
tag.
In this method, we used CFScript instead of CFML and cfset
tags, which were used in our previous functions. There is no hard and fast rule for this. You can use whichever coding method you find the most comfortable.
Let's call this method on our hello.cfm
template page, using the following code:
<!--- instatiate the component ---> <cfset objGreeting = createObject('component', 'greetings') /> <!--- access the method and assign results to a string ---> <cfset strPersonalGreeting = objGreeting.personalGreeting( firstName="Gary", lastName="Brown") /> <cfoutput>#strPersonalGreeting#</cfoutput>
Listing 1.14 calling the personalGreeting
method
We are sending in the same arguments that we were passing through to the original getName()
method, in the same way. This time we are passing these through using the newly created personalGreeting()
method.
You should now see a personalized greeting message displayed in your browser: