We're starting to use OO in our PHP at work. I discovered when I started using it why I'd been having problems wrapping my head around some of the applications I've been programming lately: I've become accustomed in Perl to using an OO framework. Suddenly, programming in PHP was much easier.
There's a few things that are different, however. It appears that you cannot pass objects in object attributes, and then reference them like thus:
PHP doesn't like that kind of syntax (at least not in versions 4.x). Instead, you have to pass a reference to the object in the attribute, then set a temporary variable to that reference whenever you wish to use it:
$object->db =& $db;
$db = $object->db;
$res = $db->query($sql);
What if you want to inherit from another class and extend one of the methods? In
other words, you want to use the method from the parent class, but you want to
do some additional items with it? Simple: use
/* do some pre-processing */
parent::method1(); // Do the parent's version of the method
/* do some more stuff here */
Actually, you can reference objects when they are attributes of another object; you just have to define the references in the correct order:
$db =& DB::connect('dsn');
$this->db =& $db;
$res = $this->db->query($sql);
I've tested the above syntax with both PEAR's DB and with Smarty, and it works without issue.
CGI::Application::ValidateRM module utilizes
HTML::FillInForm to fill in
values in the form if portions did not pass validation. Basically, it utilizes
HTML::Parser to go through and find the elements and match them to values.
It's used because the assumption is that you've built your form into an
HTML::Template, and that way you don't need to put in program logic into the
Seems another good candidate for using
FillInForm would be to populate a form
with values grabbed from a database… I should look into that as well!
HTML::Template a little, mainly in the Secret Santa project I did
this past Christmas for my wife's family. One thing I disliked was using the
<TMPL_VAR NAME=IMAGE_SRC> — it made looking at it difficult (it
wasn't always easy to tell what was an HTML tag, what was plain text, and what
HTML::Template stuff), and it made it impossible to validate my pages
before they had data.
Fortunately, there's an alternate syntax: wrap the syntax in HTML comments:
<!-- TMPL_VAR NAME=IMAGE_SRC --> does the job. It uses more characters, true,
but it gets highlighted different than HTML tags, as well, and that's worth a
And why do I have to say "NAME=" every time? That gets annoying. As it turns
out, I can simply say:
<!-- TMPL_VAR IMAGE_SRC -->, and that, too will get the
Finally, what about those times when I want to define a template, but have it
broken into parts, too? Basically, I want
HTML::Template to behave a little
like SSI. No worries; there's a
TMPL_INCLUDE tag that can do this:
<!-- TMPL_INCLUDE NAME="filename.tmpl" -->.
I've been reading a lot of posts lately on the
CGI::App mailing list about using
CGI::Application::ValidateRM (RM == Run Mode); I finally went and checked it
Data::FormValidator in order to do its magic.
D::FV is built much like how I've buit our
library at work — you specify a list of required fields, and a list of fields
that need to be validated against criteria, then provide the criteria. It goes
exactly how I would have done our libraries had we been working in perl —
supplying the constraint as a regexp or anonymous sub in a hashref for the
Anyways, it looks like the combination of
could greatly simplify any form validations I need to do on the site, which will
in turn make me very happy!
I had some success last night with the
CGI::Application superclass I'm building — I actually got it working with
CGI::Wiki::Simple (after I debugged the latter to fix some delegation issues!). Now that I know the "proof-of-concept" works, I'm ready to start in on some other issues.
The first issue is: how can I specify different directories for different applications to search for templates, while retaining the default directory so that the superclass can build the final page? I could always simply keep all templates in a single directory and simply prefix them, but that seems inelegant, somehow. I'll need to explore how HTML::Template integration works with CGI::App.
Second, and closely related: how do I want it to look, in the end? I could see keeping the design we have — it's clean, simple, and yet somehow functionally elegant. Okay, I'm exaggerating — it's your standard three-column with header and footer. But it goes with the idea of blocks of content. I need to think about that.
I saw a design idea for a WikiWikiWeb today, though, that totally changed my ideas of how a Wiki should look. I hadn't been to Wikipedia for some time, but a Google link to Gaston Julia showed up on Slashdot as it shut down a site in Australia, and so I visited it. I like the new design — it separates out the common links needed into a nice left menu, and puts a subset of that at the top and bottom of the main column as well, using nice borders to visually separate things. I much prefer it to PhpWiki's default style, as well as to anything else I've really seen so far relating to Wiki layout.
So, I'm a bit of an idiot… it's been so long since I looked at
yet I felt I had such a grasp on it, that I overlooked the obvious step: look
at the manual!
In particular, there's a whole series of methods that are used to tailor
CGI:App to your particular needs, and these include
setup() method. It can be
used to load settings from elsewhere; if it were called only from a
superclass from which other modules inherited, it would then provide common
settings for all modules.
$self->prerun_mode('mode') call to to
override the selected run-mode, for instance, thus allowing you to redirect
to a different mode if a user isn't permitted there.)
In addition, you could specify in the superclass that you're using
CGI::Simple for the query object (using the
cgiapp_get_query method), or
you could rewrite the
load_tmpl() method to use
Template::Toolkit or some
other templating system, etc.
Doesn't look so crazy anymore…
I've been wanting to redevelop my home website for some time using
CGI::Application. The last time I rewrote it from PHP to perl, I developed
something that was basically a subset of the things
CGI::App does, and those
things weren't done nearly as well.
The problem I've been running into has to do with having sidebar content, and
wanting to run basically a variety of applications. I want to have a
WikiWikiWeb, a photo gallery, some mail forms, and an article database/blog;
CGI::App-based modules for each of these all exist. But I want them all to
utilize the same sidebar content, as well — and that sidebar content may vary
based on the user.
My interest got sparked by this node on
Perl Monks. The author tells of an acquaintance who goes
by the rule that a
CGI::App should have 10-12 states at most; more than that,
and you need to either break it apart or rethink your design. And all
inherit from a common superclass, so that they share the same DB connections,
So, I've been investigating this problem. One node on PM
notes that his ISP uses
CGI::App with hundreds of run modes spread across
many applications; they created a module for session management and access
control that calls
use base CGI::Application; each aplication then calls
use base Control, and they all automatically have that same session
management and access, as well as
Another node mentions the
same thing, but gives a little more detail. That author writes a module per
application, each inheriting from a super class:
Search.pm, etc. You create an API for that super class, and each
CGI::App utilizes that API to do its work.
This also seems to be the idea behind CheesePizza,
CGI::App-based framework for building applications. (All pizzas start out
as cheese pizzas; you simply add ingredients.) The problem with that, though,
is that I have to learn another framework on top of
CGI::App, instead of
intuiting my own.
But how do I write the superclass? Going back to the original node that sparked
my interest, I found a later reply that described how you
do this. The big key is that you override the
CGI::App you just called in
a main content area of your template.
Grist for the mill…
One thing I've wondered about is the syntax of the
robots.txt file, where it's
placed, and how it's used. I've known that it is used to block spiders from
accessing your site, but that's about it. I've had to look into it recently
because we're offering free memberships at work, and we don't want them indexed
by search engines. I've also wondered how we can exclude certain areas, such as
where we collate our site statistics, from these engines.
As it turns out, it's really dead simple. Simply create a
robots.txt file in
your htmlroot, and the syntax is as follows:
User-agent can specify specific agents or the wildcard; there are so many
spiders out there, it's probably safest to simply disallow all of them. The
Disallow line should have only one path or name, but you can have multiple
Disallow lines, so you can exclude any number of paths or files.