Converting from PHP to ColdFusion
As a bit of relaxation on the Labor Day weekend 2004, I decided to move my site from Hurricane Electric (who have been absolutely fabulous for the last nearly five years!) to SmarterLinux which is a division of HostMySite. They've also been exemplary in their helpfulness, getting me up and running in a very short space of time. In made the move purely so that I could convert my site from PHP over to ColdFusion, and stop all those embarrassing questions about why such a staunch advocate of ColdFusion (me) would be maintaining their own site using another technology!
First Steps
The first thing to do was get the basic site moved across and up and running
on the new host. I had a variety of Perl CGI scripts that needed some tweaking,
partly to handle the different path (htdocs instead of public_html) and partly
to address how SmarterLinux handles sendmail (they require an explicit "from"
address be supplied at the command-line). Having moved Movable Type over, none
of the database files were readable. Fortunately, I was able to export the
entire blog from my old site and import it into the new MT install so nothing
was lost (I think!).
PHP to ColdFusion
I copied my mach-ii.xml file to mach-ii-cf.xml and
did a find'n'replace to change .php to .cfm throughout.
Then I created some shell scripts to do the brunt of the raw file conversion.
If you have read my Fusebox
to Mach II conversion, you'll know that I set the title in my view pages
using this PHP code:
<? $GLOBALS['title'] = "the page title"; ?>
The ColdFusion equivalent is:
<cfset request.title = "the page title" />
A simple sed script (Unix stream editor)
combined with the Unix find command
allowed me to create .cfm versions of every .php page
with the correct title setting code and all references to the local index.php replaced
by index.cfm. Time to try http://localhost/index.cfm for
the first time... a white screen of death. I picked apart the exception view
- it still had PHP code in it. I converted it and tried again. White screen
of death. Hmm. Then I realized I had applicationRoot set to "." which
was what I had needed for the PHP version (as opposed to "/" which
I'm used to from ColdFusion). I set it to "" and tried
again. Bingo! An exception page appeared. At least I had a debuggable error
to deal with. After about another half hour of rewriting PHP code in a few
views to CFML, I was able to get a basic page to appear. I continued replacing
PHP <? ?> code with CFML, mostly simple stuff like replacing:
<? include('lay_topnav.php'); ?> and <? echo $GLOBALS['content']; ?>
with:
<cfinclude template="lay_topnav.cfm" /> and <cfoutput>#request.content#</cfoutput>
Soon I had most of the site working in ColdFusion. I wrote another find script
to search for <? inside .cfm pages and systematically
replaced the last vestiges of PHP code (in the views!) with CFML. It was just
looping code or layout code. The next thing to work on was the small collection
of PHP classes.
Classes to Components
The PHP version of the site had just two listeners: one to send email, one to power the bookstore. The first one was very simple - a single method that sent email:
function email($who,$where,$email,$subject,$message) {
$args = compact('who','where','email','subject','message');
if ( $where == 'corfield.org' || $where == 'bangles.com' ) {
mail( $who.'@'.$where, '['.$where.'] '.$subject,
$message, "From: webmaster@corfield.org\nReply-To: ".$email );
}
}
became:
<cffunction name="email" returntype="void" access="public" output="false"> <cfargument name="who" type="string" required="yes"/> <cfargument name="where" type="string" required="yes"/> <cfargument name="email" type="string" required="yes"/> <cfargument name="subject" type="string" required="yes"/> <cfif arguments.where is 'corfield.org' or arguments.where is 'bangles.com'> <cfmail from="webmaster@corfield.org" to="#arguments.who#@#arguments.where#" subject="[#arguments.where#] #arguments.subject#" replyto="#arguments.email#">#arguments.message#</cfmail> </cfif> </cffunction>
The second one was more daunting. My bookstore section is driven by an XML
file that specifies all the sections, books, authors and keywords listed on
the bookstore page. In PHP, the
XML is parsed with a SAX parser so you need start-element handlers and end-element
handlers that are called implicitly as the parser reads the XML. I constructed
a tree of objects on the fly for each request based on the XML. It's pretty
ugly. You need to keep track of which sub-element you are working on and maintain
a lot of state information. ColdFusion provides much neater ways to handle
XML so I wrote a completely new listener that read the XML file and called
XMLParse() on it and then responded directly to the three renderXxx() calls
that were in the corresponding view. Yes, that means I have presentation logic
in my model which is not ideal of course but it was the quickest way to provide
identical functionality to what I had before and still take advantage of the
power of CF. The net result is 200 lines of CFML compared to 400 lines of PHP.
I actually do quite a bit of low-level programmatic manipulation on the data
in the XML file so I'm not certain that I can just use XSL here. I might look
at reorganizing the XML file to make XSLT a possibility in the future.
That was it as far as the website code was concerned. A new, CF-powered corfield.org was up and running with only about a day of work (a long day, admittedly).
Redirects
The final issue was that several RSS aggregators and robots were still spidering
the old site because they had not spotted the DNS change. With CF-based aggregators,
that seems to be a bug in cfhttp that caches the DNS lookup and
never notices a site moved until you restart the server. An msnbot program
seemed to be the other major culprit. Since SmarterLinux provide a transition
domain ({domain}.tempwebpage.com) while
you are getting things set up, I was able to add redirects from certain key
files on the old site (e.g., /blog/index.rdf)
to the equivalent file on the transitional domain. Makes me glad my old ISP
(and my new one!) both use Apache so I can simply slip a couple of Redirect directives
into my .htaccess file!
I shall keep track of requests on the old site and see when it seems reasonable to shut down the old account.
Now, what cool things can I do on this site now that I have ColdFusion...?