Fusebox Migration: From ColdFusion to PHP
November 18, 2001
When I was first learning PHP, I was coming from a background in Perl and ColdFusion. I had cut my teeth on Perl, so PHP syntax was familiar, and I had learned how to better organize my code using Fusebox for ColdFusion. It was a natural extention of those two facts that I should approach my education in PHP as a blending of those two histories.
The result was a database of ColdFusion Fusebox code snippets married up to their PHP syntax equivalents. I even built a little administrative interface where I could add new "translations" as I figured them out. This was a great learning experience, both in building the tool and in using it. But there was still a lot of Fusebox to figure out in the mix.
However, with the advent of Fusebox 3.0, the differences between the ColdFusion and PHP versions are almost purely syntactical. I am tempted to tell you to simply look at the code from each side and figure it out for yourself, because it is really not that complicated! But perhaps that would be because I have been so steeped in it for the past few months that the lines are overblurred...
Instead, I have reorganized the original "Migration" article I wrote here on bombusbee.com. We start with the basics, move on to some more complicated tricks, and then finish with some PHP-specific enhancements to the Fusebox 3.0 framework.
And away we go!
|
::: The Basics: setting variables :::
|
ColdFusion puts everything into tags*. You set variables, include other files, and even delimit conditional blocks using tags.
In PHP, tags are left to the HTML. Instead we have to do our coding within script delimiters much like JavaScript or ASP. In PHP, these delimiters look like this:
| |
<?php
//code goes in here...
?>
|
From within those delimiters, however, we can do everything PHP allows. Let's start by setting a variable:
In ColdFusion:
In PHP:
You may have noticed the "$" (dollar sign) in front of the variable name. In PHP that is the way the PHP engine differentiates a variable from the rest of the code. There is also a ";" (semicolon) at the end of the line. That tells the PHP engine that this is the end of a line (;-D). This is just like JavaScript, though PHP is a little more strict about the presence of that ";".
In ColdFusion, you can also conditionally set variables using CFParam. Like this:
In ColdFusion:
| |
<cfparam name="foo" default="bar">
|
In PHP:
| |
<?php
if(!isset($foo)) { $foo = "bar"; }
?>
|
isset is the equivalent of ColdFusion's IsDefined: it just asks if the variable has been set yet. The "!" (exclamation point) is the equivalent of ColdFusion's NOT operator: it essentially inverts the result of a boolean expression. So the PHP phrase basically says, "if $foo is not set, then set $foo equal to 'bar'.". In ColdFusion, the same can be written this way (and this is also equivalent to CFParam):
| |
<cfif NOT IsDefined(foo)>
<cfset foo="bar">
</cfif>
|
|
::: The Basics: including files :::
|
Dynamic includes are essential to the way Fusebox works. It gives the programmer the ability to break down their code into simple, manageable templates, which by extension are easy to reuse and debug.
In ColdFusion there are two ways to include a file: CFInclude (of course), and CFModule.
In PHP, there are four ways to include a file: include(), require(), include_once(), and require_once().
Let's look at how all these line up.
ColdFusion's CFInclude and PHP's include() are essentially the same. At runtime, when the application engines encounters one of these functions, they pause interpretation of the current template, read through and interpret the requested include file, allowing access to all variables available to the calling template, and then return control to the original template.
The short version is that the application engine sees an included file as if its contents were there in the original template in the first place, more or less. The following are equivalent:
In ColdFusion:
| |
<cfinclude template="foo.cfm">
|
In PHP:
| |
<?php
include("foo.php");
?>
|
CFModule, unlike CFInclude, does not intrinsically have an equivalent in PHP*. CFModule is essentially the same as CFInclude, but it runs the requested file in its own namespace. That is, the variables available to the original template are not inherently available to the CFModule'd template variables are explicitly passed to that template instead.
Neither does PHP's require() have an equivalent in ColdFusion. require(), again, is essentially the same as include(), but require() will throw a fatal error and halt further processing if the requested file is not available, where include() would only throw a non-fatal warning.
Which leaves include_once() and require_once(). These are fairly obvious functions: they will include() or require() the requested file only if the requested file has not yet been included previously during the processing of the current request. That way, your code will only require a function library _once() during a request, and you will not get any errors stating that a function has already been defined, or something in that vein.
|
::: The Basics: miscellaneous :::
|
A couple other essentials to programming Fusebox applications are conditionals like if... then... else or switch... case..., conditional operators, and commenting.
The following are equivalents*:
In ColdFusion:
| |
<cfif Len(Trim(foo)) AND foo NEQ "bar">
<cfoutput>
A man walks into a #foo#, and says, "Ouch!"
</cfoutput>
<cfelse>
<cfset error="Please enter a value for <b>foo</b>, other than 'bar'.">
</cfif>
|
In PHP:
| |
<?php
if(strlen(trim($foo)) && $foo != "bar") {
print "A man walks into a $foo, and says, \"Ouch!\"";
} else {
$error = "Please enter a value for <b>\$foo</b>, other than 'bar'.";
}
?>
|
You'll notice the PHP has special characters where the ColdFusion uses words. AND and && are the same, and NEQ and != also match up. There are many of these types of differences in syntax, but I can't possibly cover them all here. Nor would I want to when there is already a fabulous resource available at http://www.php.net/manual/.
A switch block is what we in the Fusebox world call the "Fusebox". Not a big difference there again just syntax differences:
In ColdFusion:
| |
<cfswitch expression="#Fusebox.fuseaction#">
<cfcase value="main">
[...]
</cfcase>
<cfcase value="this,that,other" delimeters=",">
[...]
</cfcase>
<cfdefaultcase>
[...]
<cfdefaultcase>
</cfswitch>
|
In PHP:
| |
<?php
switch($Fusebox["fuseaction"]) {
case "main":
[...]
break;
case "this":
case "that":
case "other":
[...]
break;
default:
[...]
break;
}
?>
|
Finally, we all know that good programmers comment their code. In ColdFusion, comments look just like they do in HTML, but with one more "-" (hyphen). In PHP there are actually three ways to write comments:
In ColdFusion:
| |
<!--- I am a single-line comment --->
<!---
but I really
could go on
and on
for a few lines
--->
|
In PHP:
| |
<?php
//I am a single-line comment
# and I am also a single-line comment
/*
but if I want to
go on for a while
I need to use
a different style
*/
?>
|
Next, on to the good stuff!
|
::: Fusebox-Enhanced PHP :::
|
Fusebox has a few requirements of the languages it runs on. Dynamic includes is one we discussed earlier, but another is output buffering. ColdFusion Fusebox developers have historically had the benefit of Steve Nelson's CF_BodyContent custom tag, and with ColdFusion 5, now have CFSaveContent (really the same thing, but without credit being given to Steve).
PHP3 had no way to buffer output to a variable the way CF_BodyContent and CFSaveContent can, but with PHP4, a set of output buffering functions were added, making PHP-Fusebox far more attainable. I have encapsulated those functions an a class I first called (wait for it...) BodyContent! With the revamping I gave the BodyContent class for Fusebox 3.0, I have now changed the name to (you guessed it...) SaveContent. Both of these versions are available in the downloads section.
So it looks like PHP can do just about everything ColdFusion can do, right? That's actually more or less true, and PHP actually has an impressive set of add-on modules that ColdFusion could not handle without an external COM object or CFX tag things like image manipulation, PDF, Flash, and CyberCash to mention a few. To get a full picture of what I mean, just take a look at the PHP Manual and scroll through the function reference.
But what can PHP not do? Well, custom tags are something that PHP cannot handle. Because PHP relies on the delimiters mentioned earlier (<?php [...] ?>), a tag inline with the rest of the HTML would not get interpreted by PHP.
However, another piece of the custom tag puzzle is that code running within a custom tag is running in its own namespace. This concept came up before when we were discussing CFModule, and for a good reason calling a template via CFModule is the same as calling a ColdFusion custom tag.
PHP does not have the plethora of built-in variable scopes that ColdFusion comes with, but there is a way to create a protected space for variables via custom classes. With the release of Fusebox 3.0 for PHP, I monkeyed around with the new SaveContent class, and found a way to mimic the functionality of CFModule in PHP! I also abstracted the call a bit to simplify coding. You call the function like this:
In ColdFusion:
| |
<CFModule template="foo.cfm" var="value" stan="cox">
|
In PHP:
| |
<?php
Module("foo.php", array("var"=>"value", "stan"=>"cox"));
?>
|
The code in "foo.php" will now run in a safe namespace, and the variables passed in will be available to "foo.php" in the $attributes associative array: $attributes["var"] is set to "value", and $attributes["stan"] is set to "cox".
So, I hope that gives you a good head start on translating your ColdFusion Fusebox projects into PHP. With the release of Fusebox 3.0, the differences between the way you use the methodology on different platforms is going away. The goal of having a unified framework that any programmer in any language can understand is coming that much more into focus...
Keeps your eyes on the Fusebox community. We're always working to find better ways to make your work easier!
Resources:
|