I have read about that before...not that page though.
While I have used a similar technique (essentially intercept requests and over ride them with my own implementation) this current project is quite a mess.
For starters, there are about 3 dozen PHP scripts in the docroot and several sub-domains:
registration.domain.com
login.domain.com
members.domain.com
Each of the scripts in the docroot are mirrored in the sub-domain directories (a PHP proxy script which just includes the original -- horrible for SEO -- duplicates are not a good thing) in addition to dozens of PHP scripts which are of their own purpose, like adding members, classifieds, etc.
There are several systems at play here, each simple in nature, complex in interface and discombobulating in codebase.
Contact manager
Classifieds
Coupons builder
Membership (ie: MySPACE)
Community (forums)
Each script in the entire codebase follows a transaction script approach with the HTML hardcoded with inline SQL, CSS and JS.
Each script also uses upwards of 50 globals at the start of every script, and every script then includes a 'framework.php' file which basically checks the environment, access control, etc and initializes the globals.
Examples of what the globals are:
1. SF_title = title of the page -- this is initialized in the framework.php file after it connects to the DB and looks up the script in a table and returns SEO keywords.
2. SF_protocol = The protocol the site is using. At one time the site used SSL after someone logged into the system
3. SF_locale = The domain name (which is switched for testing and live deployment)
The site is hardcoded to work with only two domains (domainloc.com and domainpro.com). Installing the site under any other domain will cause hundreds of errors.
The framework.php is well over 1000 lines of messy code, initializing globals, many of which I am sure are redundant or dead code now.
This file includes a globals.php which includes about a dozen functions, many of which are wrappers around string functions to emulate a VB environment, such as
There are no functions outside of these wrappers -- everything is inline.
I have tried refactoring many of the scripts:
1. Refactoring the inline SQL into a DAL to provide some kind of API -- while this cleaned up the code a bit it usually requires refactoring the entire script as code is often tightly coupled with the HTML.
Code: Select all
$res = odbc_exec('SELECT * FROM blah...');
while($tmp = odbc_fetch($res)){
echo '<b>Some crap: </b>'.odbc_result($tmp, 'some)field');
echo '<b>Some crap: </b>'.odbc_result($tmp, 'some)field');
echo '<b>Some crap: </b>'.odbc_result($tmp, 'some)field');
echo '<b>Some crap: </b>'.odbc_result($tmp, 'some)field');
echo '<b>Some crap: </b>'.odbc_result($tmp, 'some)field');
}
// Do more crap with the ODBC connection
So while I can pull the SQL into a function and return a native PHP array I usually have to go over all the other code and make sure to use the array instead of the odbc_result() -- this actually speeds things up by about 1/10 of a second per page.
Once I had done this and documented the API I began attempting to extract the XHTML into a template layer and this is where things got really tricky.
The globals I mention above are used all throughout the HTML. Every href/src/whatever has it's URI dynamically generated with several variables:
SF_protocol
SF_locale
SF_suffix (TLD)
There are several other variables which you can use to compose the URI, such as $SF_root_url (which is everything but the protocol) as well as SF_root_dir -- which is used by includes. As well as SF_domain_pre which I am uncertain exactly what it does.
Because there are literally dozens and dozens of globals used in composing the HTML it makes it very difficult to just extract the XHTML as I need the templates to either:
1. Pass in the globals as template variables
2. Give templates access to globals
The alternative is to go through each line and remove the dependency on the globals as much as possible.
The template code is so complex and confusing, there is a tremensoud amount of duplication occuring, it is not uncommon for the template code too look like this:
Code: Select all
if($_SESSION['sess_uid'] != 0){
echo 'Do something';
}
if($_SESSION['sess_uid'] > 0){
echo 'Do something else';
}
if($_SESSION['sess_uid'] != 0 && $_SESSION['sess_blah'] !== 0){
echo 'Do something again';
}
if($_SESSION['sess_uid'] != 0){
echo 'Do something else -- whcih could be done in the first conditional test';
}
Not to mention nesting -- there is so much duplication caused by deep nesting and complex view/business logic/etc.
To top it all off, I am expected to improve the code while others work on it too...it took me 3 days to finally get the servers and each of our consoles configured so we could run the damn software locally, commit to a test server and implement batch files to update the live site wheneve the manager feels the code is where she expects it to be. SVN is a godsend in this scenario.
An important part of writing software is writing it in such as way that it facilitates change (ie: can be strangled later on). This software is not even remotely designed that way. The fact it's hardcoded to a domain made configurning the desktops to run WAMP and the software an extra special challenge.
Yesterday I started on re-working the classifieds section. Currently they are powered by a classifieds.php in the docroot and the management is handled by various scripts in the members.domain.com portion of the site.
I have essentially started from scratch, creating a 'classifieds' directory with it's own .htaccess, index.php, templates and functions. The script still needs to use the existing framework.php however as there is conditional checks that rely on the system state.
If the user is logged into the system, while browsing classifieds ads, they need to see an update button. There is no function to call to check for authentication, just a few session variables, which are initialized by framework.php. I have no idea where in framework.php all this happens so I just include it as until it works.
The problem with including any of the existing files, is the include files have a custom 'punter' check in the files to prevent direct access and I cannot remove those checks as they will break the original code if I do -- somehow the scripts in docroot are dependent on those checks passing.
So I have made copies of those scripts in my local working copy prefixed with '_i.php' i for improved
So long as I don't commit these files to the repo, no one else is even the wiser until I have everything working, at whihc point I rename to original and commit and force every to update as well.
There are essentially two global includes (outside of framework and global) which are the header.php and footer.php.
When I included these in my own version, everything broke, because they also have that 'punter' check to prevent direct access. Short of finding the code which 'punts' I just made local copies prefixed with '_i.php' and include those instead.
I removed all variables from the template XHTML code and pass in only the very essentials (data from array's etc).
Everytime I update my working copy I use WinMerge to merge the changes made by others to header.php/footer.php into my local copy -- this is a time consuming process as the code is wildly different. For starters, my templates are strictly presentation logic, no inline SQL, etc.
To make matters worse, I have no access to the DB schema, so I cannot change anything at that level, which is probably a good thing.
I think at this point, it's probably best ot just incermentally improve the code one script at a time.
Any tools, tips, etc anyone care to share?
Unit testing it out of the question at this point, the DAL are extremely simple and just serve to centralize the SQL and remove it from the scripts/templates.
Each script acts as a page controller, which pulls on the DAL API and initializes the templates. $_SESSION variables are the only globals directly depended upon by the XHTML templates.
Interested in hearing your horror stories, experiences, etc???
I have seriously never seen code is such bad shape in my life, prior to this experience, I thought WordPress was bad, this source base just takes the cake.
