Clay Loveless wrote last
year an article entitled Stop
Writing Loner Applications in which he ranted about all the
monolithic applications that act like they're the only kid on the block when
it comes to user authentication. Basically, if you want to create a site
that utilizes several third-party, off-the-shelf PHP apps (say, a forum, a
blog, and a wiki), getting a shared authentication to work between them can
be more than a little painful.
I've hit a similar problem repeatedly the past couple months: most of these
apps simply are not embeddable, at least not without modifying the source.
"Why embed?" you ask. Simple: if I'm creating a site that has one or two of
these applications, but also my (or my company's) own custom functionality,
I may want to ensure that certain elements are present on all pages, or that
I can control some of the content in all pages: a unified header and footer,
ability to inject statistic tracking javascript, etc.
The predominant attitudes are either, "Don't embed our app, embed your app
in ours," or "Just modify the templates." Neither of these solutions is
acceptable.
Why not? In the first case, it's my site. If I'm mixing and
matching several such applications, which ones should I embed, and which
should be the master? Honestly, the applications I'm writing for
the site are the master application; the third party solutions should be
embedded in my website.
In the second case, I may have my own header and footer, and tools for
automating what tracking scripts are embedded when -- in other words, I'm
running my own display logic, possibly with my own tools. Embedding these
tools into another apps templates is at times difficult (if the application
is simply using PHP, the difficulty may be mainly finding what code to
alter), at times impossible (if the application uses a templating engine
vastly different than what I'm using, or one that does not allow arbitrary
PHP). Why should I have to write an interface to my code for each
application?
Truthfully, it simply makes sense to use a Two Step View in most cases,
having the application generate content that is then injected into a
sitewide template I control.
I've tried in a number of cases to write wrappers so I can grab content from
these third party apps, typically using output buffering to capture the
output so I can inject it into my own views. So far, my experience has been
universally dismal. Most of the secure, robust apps out there (I'm not going
to name names) still use procedural methods for at the very least
the main script, usually index.php. This includes slurping in configuration
from other files... all of which happens in the global namespace. What's the
problem? Most wrappers I write are by necessity class methods or functions,
or run from within one, meaning the global namespace is no longer in effect.
The end result is that I have to greatly alter the code to get things to
work -- in one case, my colleague and I ended up changing all $_GLOBALS
references to $_SESSION simply to get things to work. Hackish, but it got
the job done. However, it also means it will be a nightmare to upgrade
until we can script it.
If you're writing a standalone PHP application, maybe the next great forum
software, or blog software, or wiki, or what have you, please design it in
such a way that it is easily embeddable:
-
When using configuration files, use a configuration component that
doesn't require use of the global namespace (PEAR's Config, Solar's
Solar_Config, and Zend Framework's Zend_Config come to mind); when
coupled with a registry or implemented as a static class property (in
PHP5), you can have access to the configuration from anywhere in your
application.
-
Have your bootstrap script call on class methods or functions to do
their work. Don't do any decisioning in the global namespace.
-
Better yet, use an MVC pattern in your apps, and have your bootstrap
simply dispatch the controller. This can easily be duplicated in
somebody else's code, or simply directly included.
-
Make sure your templates are easily modified to allow developers to
strip out header, footer, and menu elements.
-
Create an API to allow retrieving necessary javascript and CSS so that
it can later be injected into another system's templates.
-
Don't use $_GLOBALS ever. It seems like an easy way to keep variables
accessible across classes and functions, but with PHP 5's static
properties, or judicious usage of singleton's in PHP 4, there are other
ways to accomplish the same effect with fewer side effects.
If you're responsible for maintaining an existing project, please start
fixing your application today so it can be embedded. Believe it or not, it
may actually increase adoption of your project, as more people will
be able to use it within their existing sites. At the very least, you'll
stop me from ranting, and reduce the amount I spend on acetaminophen.
PHP 4 is end-of-life very soon. In addition to offering projects the chance to refactor and improve their application design, PHP 5 offers many things PHP 4 just doesn't. This series of posts will deal with things projects can get their fingers into that
Tracked: Nov 02, 13:38