Macromedia Flash MX and PHP
Table of Contents
Transferring data with the LoadVars object
A LoadVars object transfers data between a server-side scriptsuch as PHP, ASP, CF, Perl or JSPand a Macromedia Flash MX movie. Properties of the LoadVars object is sent to the script as variables, either by the POST or GET method. Any variables returned from the script are available to Macromedia Flash as properties of the LoadVars object specified in the load method.
Using LoadVars.send
format = loadVarsObject.send( url, target, method ), where all are expressions
In your sample, you want to send the letter of the tab you selected so that the PHP script can use it to query the database. So a LoadVars object must be created and one of its properties must be set to that letter. Before looking at the code in the sample, here is an example in which a value is assigned to a property of a newly created LoadVars object and sent to a PHP script:
var
c = new LoadVars();
c.thisLetter = "A";
c.send("dbquery.php","_self","POST");
The script reads that property as a POSTed variable and uses it to query the database and display the information found:
<?php
mysql_connect("servername","username","password");
mysql_select_db("dbname");
$qr = mysql_query("SELECT
* FROM contacts WHERE LEFT(lastName,1) =
'".$HTTP_POST_VARS['thisLetter']."'");
// display
visitors row (1)
$nrows = mysql_num_rows($qr);
for ($i=0; $i < $nrows; $i++) {
$row = mysql_fetch_array($qr);
echo $row['lastName'].", ".$row['firstName']."<br>";
echo " ".$row['phone']." ".$row['email']."<Br>";
echo " ".$row['picFile'].":
".$row['caption']."<Br><Br>";
}
?>
This is what gets output to the output window (the same window in which the Flash movie was running, because you specified "_self" as the target in your loadVars.send):
Anderson, Lois 301-424-5555 lois@yahoo.com lois.jpg: Lois, 2001
Armand, Cheryl and Joe 912-948-4444 armandcj@hh.com babysue.jpg: C and J's baby Sue, 9 days old
(etc.)
Because you used POST as a send parameter, you had to read the variables with PHP $HTTP_POST_VARS. If you need to build the query string yourself (which is sometimes the case), you can just send it without specifying a method and it will default to GET because of the appended querystring:
var c = new
LoadVars();
c.send("dbquery.php?thisLetter=A","newWindow");
This code in dbquery.php produces the same result in the output window as above, but in a new document window (newWindow):
<?php
mysql_connect("servername","username","password");
mysql_select_db("dbname");
$qr = mysql_query("SELECT * FROM contacts
WHERE LEFT(lastName,1) = '".$HTTP_GET_VARS['thisLetter']."'");
// display visitors row (1)
$nrows = mysql_num_rows($qr);
for ($i=0; $i < $nrows; $i++) {
$row = mysql_fetch_array($qr);
echo $row['lastName'].", ".$row['firstName']."<Br>";
echo " ".$row['phone']." ".$row['email']."<Br>";
echo " ".$row['picFile'].":
".$row['caption']."<Br><Br>";
}
?>
When writing a Flash-to-server-side application, it's a good idea to run simple tests like the above code, using .send to make sure variables are passed as expected, before trying to test the whole application.
Receiving using LoadVars.load
format = loadVarsObject.load( url ), where url is an expression
Now that you've got variables being sent to the PHP script and used successfully there, how do you get the information returned to Macromedia Flash? Before tackling sending and receiving together, let's look at just receiving, with the LoadVars object's load method.
Variables sent to Macromedia Flash from a server-side script must always be sent as a string of var=value's separated by &'s; for example:
lastName=Anderson&phone=301-424-5555
If such a string is sent in response to a LoadVars load, the variables can then be read in Macromedia Flash as properties of the LoadVars object.
But there's one more thing that needs to be taken into consideration. Getting information from a database and sending it back to Macromedia Flash does not happen instantaneouslysomething needs to signal Macromedia Flash when the operation is complete so the movie won't try to use the variables before they're available (a very common newbie problem). What needs to be done is to define a function that will be executed when data is returned and assign that function to the onLoad property of the LoadVars object. That is, when variables have been received, execute the function. This can be done in one of two ways: with an anonymous function (also called a function literal, I think):
var c = new
LoadVars();
c.onLoad = function() {
returnvals.text = "returned from php:
\n\n";
for (i in this) {
returnvals.text += i + "
= " + this[i] + "\n";
}
};
or with a named function, which is then assigned (but not calledfor example, don't put () after the function name) to the onLoad property:
function
showValues() {
returnvals.text = "returned from php: \n\n";
for (i in this) {
returnvals.text += i + " = " + this[i]
+ "\n";
}
}
var c = new LoadVars();
c.onLoad = showValues;
Either way, referring to "this" inside the function is the same as calling the LoadVars object by name.
So with either piece of code above, followed by this line to actually request the data:
c.load("passvars.php");
and in passvars.php, this code...
<?php $lastName = "Anderson"; $phone = "301-424-5555"; echo "lastName=".$lastName."&phone=".$phone; ?>
...results in this output:
returned from php: phone = 301-424-5555 lastName = Anderson onLoad = [type Function]
The two variables you want to receive are phone and lastName. In your example, onLoad shows up too, even though it's not a variable, because it's also a property of the LoadVars object. Usually you know which variables you're expecting and will do something only with those variables and ignore any other properties of the LoadVars object. You can also delete any superfluous properties before issuing the load (although onLoad is not superfluous and must always be a property of LoadVars for it to function correctly).
Sending & receiving at once with LoadVars.sendAndLoad
format = loadVarsObject.sendAndLoad( url, loadVarsObject,
method ),
where url and method are expressions and loadVarsObject
is not
In your sample, you want to pass the selected letter (of whatever tab is clicked) and pass back all records handed back by the query. So your PHP routine has to send back a var=value string of all those variables and your Macromedia Flash movie has to use the right properties of the LoadVars object to display them in the scrolling text field you put in the movie.
The PHP script returns a string that looks like this:
"n=4&lastName0=Anderson&firstName0=Lois&phone=301-424-5555&...&caption3=lastyear"
which includes values for the four records found with last name starting with A. Notice that you've also added a variable at the beginning of the string to tell Macromedia Flash how many records to expect, so that you can set up an appropriate loop to read them all. This is what that part of the PHP script looks like:
$nrows =
mysql_num_rows($qr);
$rString = "n=".$nrows;
for ($i=0; $i < $nrows; $i++) {
$row = mysql_fetch_array($qr);
$rString .= "&lastName".$i."=".$row['lastName'].
"&firstName".$i."=".$row['firstName'];
$rString .= "&phone".$i."=".$row['phone']."&email".$i."=".$row['email'];
$rString .= "&picFile".$i."=".$row['picFile'].
"&caption".$i."=".$row['caption'];
}
echo $rString;
You've seen all of the Macromedia Flash code to set things up already; now you just have to define the function to execute when the variables are returned (to read and do something with those variables) and then issue the correct sendAndLoad command. Here is that code from the Macromedia Flash movie (where ¬ indicates a line break):
function
showContent() {
var i;
content.htmlText = "";
for (i=0; i < this.n; i++) {
if (this["picFile"+i] != "")
{
content.htmlText += ¬
"<b>" + this["firstName"+i]
+ " " + this["lastName"+i] + ¬
"</b>" + "<a
href='asfunction:showjpg," + this["picFile"+i]
+ ¬
"," + escape(this["caption"+i])
+ ¬
"'> (<font color='#0000cc'>pic</font>)¬
</a><Br>";
} else {
content.htmlText += ¬
"<b>" + this["firstName"+i]
+ " " + this["lastName"+i] + ¬
"</b><Br>";
}
content.htmlText += " "
+ this["phone"+i] + "<Br>";
content.htmlText += ¬
" <a href='mailto:"
+ this["email"+i] + "'>" + ¬
this["email"+i] + "</a><Br><Br>";
}
}
// Create new load vars object c for data transfer var c = new LoadVars(); c.onLoad = showContent;
Remember that you execute the sendAndLoad itself from within the onRelease routine for the selected tab with this code:
this["tab"+chr(i)].onRelease
= function() {
...
c.sendAndLoad("flashmx_dbPassAndReturnString.php",c,"POST");
}
Now you're all set up to send an A, B or C to the PHP script and do something with the variables it returns, using the same LoadVars object c for both sending and receiving. To make sense of the code in function showContent, you have to remember that these are all equivalent ways of accessing the phone3 property of object c:
c.phone3 and c["phone"+3] and i=3 c["phone"+i] and i=3 this["phone"+i] if the code is inside a function assigned to c
(For more information on that, see the Addressing Movieclips page from my actionscript-toolbox.com site, which applies to all ActionScript objects, not just movie clips.)
Thus, you simply take each property that is returned and display it as you wish in the text field you created.
asfunction
format = asfunction:functionname,param where param is an expression
There are two more interesting things in this sample. One
is the use of asfunction
to call a function within Macromedia Flash; the other is
to load a JPEG directly into Macromedia Flash. As you can
see from the code in showContent above, asfunction
allows you to provide an HTML-like link within a Macromedia
Flash text field to another Macromedia Flash routine. In
this case, it calls function showjpg and passes a parameter
(it can only pass one) that contains both the name of the
JPEG file and the caption, separated by a #. This is what
showjpg looks like:
function
showjpg(paramString) {
// get the individual parameters:
// params[0] = picture file name
// params[1] = caption
var params = paramString.split("#");
picHolder.loadMovie(params[0]);
caption.text = unescape(params[1]);
}
The first thing to do is split the passed parameter into the two parameters you really want, using the string split function to produce a two-element array. The first element now holds the JPEG name; the second holds the caption.
Loading a JPEG
format = mcInstanceName.loadMovie(jpgfile) where jpgfile is an expression
The following line
picHolder.loadMovie(params[0]);
says to load the image specified by the filename stored in params[0] into the picHolder movie clip. Because picHolder was created with an upper-left registration point (0,0), and you sized all the photos to match its size, the photo loads into exactly the right place and you don't need to do anything more with it. After you load the JPEG into its holder, fill in the caption with the passed caption text. The unescape function is used to unURL-encode the value (notice that you used the escape function to URL-encode the value before sending itotherwise characters in the caption like ":" and "," would not show up correctly).
That's it. The LoadVars object sends data, the PHP script uses it and sends data back, and the showContents function deals with the data once it's received by Macromedia Flash.