Link to home
Start Free TrialLog in
Avatar of silemone
silemoneFlag for United States of America

asked on

Storing array in a session variable--values not persisting

I have an application cfm, with sessionmanagement on.  I store a 1 dimensional array as a session variable, however the values do not get updated when accessing the session variable from different pages within the application.  See code below.  So, what happens is, if I do a cfoutput or cfdump of the session variable myarray on each page, the values from page to page do not stick.  I only see the value for the page that I'm on, and the rest are undefined.  Any ideas?
Application.cfm:
 
<cfapplication name="myapp"  
			   sessionmanagement="yes"
			   sessiontimeout="#CreateTimeSpan(0,0,20,0)#">
 
	<cfset session.myarray= arraynew(1)>
 
Page1:
 
 <cfset session.myarray[1]="firstvalue">
<cfdump var=#session.myarray#>
 
 
<a href="page2.cfm">goto page2</a>
 
Page 2:
 
 <cfset session.myarray[2]="secondvalue">
 <cfdump var=#session.myarray#>
 
<a href="page3.cfm">goto page3</a>
 
 
Page 3:
 
 <cfset session.myarray[3]="thirdvalue">
 <cfdump var=#session.myarray#>
 
<a href="page1.cfm">goto page1</a>

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Plucka
Plucka
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Avatar of gdemaria
gdemaria
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of silemone

ASKER

@gdemaria, you are right about that, however,  I had already implemented what you mentioned.  The BIG thing that I failed to mention was that this is for a facebook application.   Sessions work normal outside of facebook.  However, when the above is part of a simple facebook app, the sessions do not persist as described above.  
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
It's worth mentioning that after instantiating the session variable I used ArraySet to initialized the first 5 elements to an empty string.  After moving the cfdump before the cfset, all I get are empty strings in the array instead of seeing the value for what the current page set. If I remove the arraySet, I will not surprisingly get an undefined array element.

gemaria, I'm not sure what you mean by "inside" and "outside", but there is only one application.cfm file.  Infact I'm using cf-facebook.    I also pass a parameter via url query string on each href as well to test parameter passing like:  ( <a href="http://apps.facebook.com/myappname/s2.cfm?test=testval">s2</a> ) . I don't think that has anything to do with sessions though.

> It's worth mentioning that after instantiating the session variable I used ArraySet to initialized the first 5 elements to an empty string

This should be done ONLY inside the CFIF NOT IsDefined statement where you create the array...


> I'm not sure what you mean by "inside" and "outside"

I was using your terminology when you said that it worked "outside" facebook..  I though you were referring to before and after a login

> "Sessions work normal outside of facebook. "
Yes, the ArraySet is being done with the cfif bock, right after the array definition.

Right, so, outside of facebook means a regular coldfusion app outside of facebook.

Can anyone out there create an app with cf-facebook where one stores an array in a session, and have a few pages linking to each other that adds elements the the array with the contents of the array persisting by looking at the cfdumps of those pages?

You said that there is only one application.cfm file in use with your regular app outside facebook and as part of cf-facebook.   That means you only have one CFAPPLICATION tag that's used.  It's really important that you are not using different CFAPPLICATION tags because they will create seperate applications and separate session variables.

You also have to make sure that you are not using CFLOCATION on the same page after setting your session variables.

I suspect the answer is hidden in code you haven't shown..
Yes, gdemaria, I only have one cfapplication tagthe one in cf-facebook.  I created a totally separate application as a regular coldfusion application just to make sure that sessions were persisting across pages, and they do.  

I've also tried different browsers on different machines. Still no luck.  In fact, it does not matter if its an array or a regular string.

 I will show you all that I have for an example using 3 pages: s1.cfm, s2.cfm, s3.cfm.  These pages link to each other and update session variables val1, val2, and val3, respectively.  The problem is that

values do not persist outside of the page respective page.  s3.cfm should display all three values, but it only displays its own.  Please see the code snippet for the application.cfm and the three s* pages.

Application.cfm:
 
<cfapplication name="TESTSessions"  
			   sessionmanagement="yes"
			   sessiontimeout="#CreateTimeSpan(0,0,20,0)#"> 
	
	<!--- http://apps.facebook.com/APP_NAME --->
	<cfset appName = "TESTAPP" />
	
	<cfset appNameCap = "TESTAPP" />
	<cfset appNameLow = "testapp" />
	
	<!--- what directory your files are stored in --->
	<cfset appDirectory = "http://myurl/testfolder/facebook/cf-facebook/" />
	
	<cfset api_key = "**the numbers**"/>
	<cfset secret_key = "**the numbers**"/>
	<cfset appID = "**the numbers**"/>
	
	<cfset urlPath = "http://www.myurl.com" />
	
	<!--- sets a profile image for profile box --->
	<cfset profileIMG = "http://myurl/myfolder/facebook/cf-facebook/images/facebookapplogo.jpg" />
	
	<cfset facebook = "http://www.facebook.com" />
	<cfset faceBookPath = "http://apps.facebook.com" />
 
	<!--- fbml client component, load it into application (could load into request if prefferred)--->
	<cfif not isDefined('FBMLClient')>
		<!--- comment out the applications scope for development purposes
			  un-comment when your application is completed --->
		<!--- <cflock scope="application" timeout="10"> --->
			<cfinvoke component="FacebookFBMLClient" method="init" returnvariable="FBMLClient">
				<cfinvokeargument name="apiKey" value="#api_key#">
				<cfinvokeargument name="secret" value="#secret_key#">
				<cfinvokeargument name="url" value="#faceBookPath#/#appNameLow#/">
				<cfinvokeargument name="callbackUrl" value="#urlPath#/#appDirectory#/">
			</cfinvoke>
		<!--- </cflock> --->	
	</cfif>
	
	<!--- include template to process user route to application --->
	<cfinclude template="fbRoute.cfm">
	
	<!--- once routed, set session/application variables for entire app --->
	<cfset session.fb_uid = "#fb_sig_user#">
	<cfset session.fb_session_key = "#fb_sig_session_key#">
	<cfset session.consent = "Y" >
 
	 <cfif NOT isDefined("session.myarray")>
	   <cfset session.myarray= arraynew(1)>
	   <cfset temp = ArraySet(session.myarray, 1,9, "")>
	</cfif>
	
	<cfif NOT isDefined("session.val1")>
		<cfset session.val1="">
	</cfif>
 
      <cfif NOT isDefined("session.val2")>
		<cfset session.val2="">
	
      </cfif>
	
      <cfif NOT isDefined("session.val3")>
		<cfset session.val3="">
      </cfif>
	 
 ---------------------------------------------  
pages s1-s3
 
s1.cfm:
<!--begin -->
 
 <cfset session.val1 = "val1">
 
<a href="http://apps.facebook.com/myapp/s2.cfm?test=s3">s2</a>
 
<br />
 
<cfoutput>
   val1: #session.val1#
</cfoutput>
 
<!--end-->
 
s2.cfm:
<!--begin -->
 
 
<a href="http://apps.facebook.com/myapp/s3.cfm?test=s3">s2</a>
 
<cfset session.val2 = "val2">
 
<cfoutput>
    val1: #session.val1#   
    <br />
    val2:  #session.val2#
</cfoutput>
 
<!--end-->
 
 
s3.cfm:
<!--begin -->
 
<a href="http://apps.facebook.com/myapp/s1.cfm?test=s1">s2</a>
 
<cfset session.val3 = "val3">
 
<cfoutput>
    val1: #session.val1#   
    <br />
    val2:  #session.val2#
    <br />
    val3:  #session.val3#
</cfoutput>
 
<!--end-->

Open in new window

Using your code, the session variables do persist on my server.

In Coldfusion administrator, do you have the ability to use session management turned on?
Wow.  Well,  I don't have access direct access to CF administrator, but I can make that happen.  However, sessions are turned on.  Other applications work fine on the server that deal with sessions.  It's only through facebook that I see this non-persistence problem.  Can you create a simple facebook app in CF that does persist session variables across pages like I'm trying to do above.  If so, please share.    Is there a problem with the code itself?
I meant to include in my last statement this important statement, that I commented out the CFINVOKE for facebook.  I do not have that available and the page was erroring on that command.

Therefore, perhaps a test for you would be to do the same.  Comment out CFinvoke for facebook (and the couple lines using it's response variables) and see if it makes a difference.

Well, gdemaria, if i comment out the cfinvoke, then I can't use it as a facebook application because facebook require those bits. However, If I take the code and and make a non-facebook application it works great.   I used this simple application.cfm:

<cfapplication name="myapp"  
                     sessionmanagement="yes"
                     sessiontimeout="#CreateTimeSpan(0,0,20,0)#">
 
<cfif NOT isDefined("session.val1")>
            <cfset session.val1="">
      </cfif>
 
 <cfif NOT isDefined("session.val2")>
            <cfset session.val2="">
      
      </cfif>
      
      <cfif NOT isDefined("session.val3")>
            <cfset session.val3="">
      </cfif>


      
      
Yes, I understand.  I just wanted to see if it worked on your end without the CFINVOKE before I downloaded the facebook cfc myself.   Since it did work on your end, I went ahead and downloaded the facebook cfc (by googling the name) and added it to my code.

It worked just fine.   The session variables stayed intact even though I was invoking the cfc and went to page s1, s2, s3..

Of course, I changed this URL being used in the link from this...
http://apps.facebook.com/myapp/s2.cfm?test=s3

to just this..
<a href="s2.cfm">  

because I'm not on that server.   Are you?   That is the path of the server you're working on now?  facebook.com ?


You're not going through the facebook api then, if you removed the apps.facebook/myapp/ (where myapp would point to YOUR) facebook app. Also, facebook would complain about relative urls.  But, you have proved that the code itself works, it is still an issue with facebook and the sessions handling.  I maybe be missing something about how facebook and session handling work.
if s1.cfm  s2.cfm  and s3.cfm are not on your server (the same place as your application.cfm file is located), then they are not sharing the same CFAPPLICATION and not sharing the same session.  Therefore, you should not expect any variables on your server to be present on the facebook server.   Only variables specifically made available to you by facebook would be available.

Typically, an integration like this, they would provide you a method to create a session on their server (via a method in their CFC).  This would allow you to connect without additional login from your site.  But the two sites are completely isolated from each other except via the API code.

I have done many API integrations, but not facebook.  


They are on my server, but they talk to the facebook api.  So that when someone goes to http://apps.facebook/myapp/  facebook will then transparently talk to my files. This is the FBML method of facebook development.  I'm thinking that the iframe method would be less hassle free in terms of this session problem.

I found this post on the facebook developers forum regarding sessions with PHP, but should apply to all languages.

http://forum.developers.facebook.com/viewtopic.php?id=17032

It says:

you can't manage state with sessions in a FBML app because of the way facebook/your server communicate. you will need to find another way. Attach the previous page to the querystring in this case..

So, I guess I would have to either store the values that I want persisted in a database, or pass them along via the url querystring.

Not sure how the facebook integration works, but I don't see how you're running s2.cfm on the facebook server.   This is a coldfusion file, is there really a file s2.cfm on the facebook server (in your area) that you can put coldfusion language in?

http://apps.facebook.com/myapp/s2.cfm?test=s3

> I guess I would have to either store the values that I want persisted in a database, or pass them along via the url querystring.

Right, depending on whether you will use them on the facebook side..  If yes, then pass them on the URL, if you only need them when the visitor returns to your site, you can store them in cookies, session variables or in the database.  But you won't be able to access them when on the facebook site.

oh wait, you said they are on your server

> They are on my server

then why are they linking to app.facebook.com ?


http://apps.facebook.com/myapp/.....

Shouldn't the link go to your own server...

http://www.yourdomain.com/s2.cfm 

The facebook integrations works in away (FBML) that it appears that your files are own the facebook server, but are really on your own.  So the files are really own my server, however it appears that they are on the facebook server.