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.
Sisi ni kuanza kutumia OO katika PHP yetu kazini. Nilipogundua wakati nilianza kuitumia kwa nini nilikuwa na matatizo ya kuzunguka kichwa changu karibu na baadhi ya maombi ambayo nimekuwa programu hivi karibuni: Nimekuwa kutumika katika Perl kutumia OO mfumo. Kwa ghafula, programu katika PHP ilikuwa rahisi zaidi. Hata hivyo, kuna mambo machache ambayo ni tofauti. Inaonekana kwamba huwezi kupita vitu katika sifa ya kitu, na kisha rejea yao kama hivi: PHP haina kama aina hiyo ya syntax (angalau si katika matoleo 4.x). "Kama ilivyoelezwa hapo juu, ""kuhitaji"" ni sawa na ""kuhitaji"" kwa sababu ya ""kuhitaji"" kwa sababu ya ""kuhitaji"" kwa sababu ya ""kuhitaji"" kwa sababu ya ""kuhitaji"" kwa sababu ya ""kuhitaji"" kwa sababu ya ""kuhitaji"" kwa sababu ya ""kuhitaji"" kwa sababu ya ""kuhitaji"" kwa sababu ya ""kuhitaji"" kwa sababu ya ""kuhitaji"" kwa sababu ya ""kuhitaji"" kwa sababu ya ""kuhitaji"" kwa sababu ya ""kuhitaji.""" Kwa maneno mengine, unataka kutumia njia kutoka darasa mzazi, lakini unataka kufanya baadhi ya vitu vya ziada na hayo? "Kama ilivyoelezwa hapo juu, ""mfano"" ni ""mfano"" wa ""mfano"" wa ""mfano"" wa ""mfano"" wa ""mfano"" wa ""mfano"" wa ""mfano"" wa ""mfano"" wa ""mfano"" wa ""mfano"" wa ""mfano"" wa ""mfano"" wa ""mfano"" wa ""mfano"" wa ""mfano"" wa ""mfano"" wa ""mfano"" wa ""mfano"" wa ""mfano"" wa ""mfano"" wa ""mfano"" wa ""mfano"" wa ""mfano"" wa ""mfano"" wa ""mfano"" wa ""mfano"" wa ""mfano"" wa ""mfano"" wa ""mfano"" wa ""mfano"" wa ""mfano"" wa ""mfano"" wa ""mfano"" wa ""mfano"" wa ""mfano"" wa ""mfano"" wa ""mfano"" wa ""mfano"" wa ""mfano"" wa ""mfano"" wa ""mfano""""""""""""""" CGI: Application: ValidateRM moduli hutumia HTML: FillInForm kujaza katika maadili katika fomu kama sehemu hakuwa kupita uthibitisho. Kimsingi, inatumia HTML::Parser kwenda kupitia na kupata vipengele na kulinganisha yao na maadili. "Kama unavyoona, hii ni njia ya kuunda fomu ya fomu ya fomu ya fomu ya fomu ya fomu ya fomu ya fomu ya fomu ya fomu ya fomu ya fomu ya fomu ya fomu ya fomu ya fomu ya fomu ya fomu ya fomu ya fomu ya fomu ya fomu ya fomu ya fomu ya fomu ya fomu ya fomu ya fomu ya fomu ya fomu ya fomu ya fomu ya fomu ya fomu ya fomu ya fomu ya fomu ya fomu ya fomu ya fomu ya fomu.""" "Hii ni kwa sababu ya ""Msingi wa Santa"" ambao nilifanya kwa familia ya mke wangu." Jambo moja mimi disliked alikuwa kutumia <TMPL_VAR NAME=IMAGE_SRC> <unk> alifanya kuangalia ni vigumu (haikuwa daima rahisi kusema nini ilikuwa HTML tag, nini ilikuwa maandishi ya kawaida, na nini HTML::Template mambo), na alifanya ni vigumu kuthibitisha kurasa zangu kabla ya kuwa na data. Kwa bahati nzuri, kuna syntax mbadala: wrap syntax katika maoni ya HTML: <!-- TMPL_VAR NAME=IMAGE_SRC --> hufanya kazi. "Hii ni kwa sababu ina alama nyingi, lakini kwa sababu ya kuwa na alama nyingi, ni muhimu sana kutumia tags za HTML, na kwa hivyo, kwa hivyo, ""Name"" inapaswa kuwa na alama nyingi." Hilo huwa lenye kukasirisha. "Kama ilivyoelezwa hapo juu, ""TMPL_VAR_IMAGE_SRC"" ni neno la kawaida ambalo linatumiwa kwa kuunda templeti, lakini kwa njia ambayo haijulikani." Kimsingi, nataka HTML::Template kujiendesha kidogo kama SSI. "Hakuna wasiwasi, kuna tag ya ""TMPL_INCLUDE"" ambayo inaweza kufanya hivyo: ""TMPL_INCLUDE NAME"" - ""TMPL_INCLUDE NAME"" - ""TMPL_INCLUDE NAME"" - ""TMPL_INCLUDE NAME"" - ""TMPL_INCLUDE NAME"" - ""TMPL_INCLUDE NAME"" - ""TMPL_INCLUDE NAME" "Kama unavyoona, kuna baadhi ya tovuti ambazo zinatumia ""CGI: Application Validator"" (RM = Run Mode) na ""Data: Form Validator"" (FVV) kama njia ya kuharakisha." Dfv ni kujengwa sana kama jinsi mimi buit maktaba yetu katika kazi <unk> wewe kutaja orodha ya mashamba required, na orodha ya mashamba ambayo haja ya kuthibitishwa dhidi ya vigezo, kisha kutoa vigezo. Ni huenda hasa jinsi ningekuwa alifanya maktaba yetu alikuwa sisi walikuwa kufanya kazi katika Perl <unk> kusambaza kizuizi kama regexp au anonymous sub katika hashref kwa ajili ya anyways, inaonekana kama mchanganyiko wa inaweza sana kurahisisha yoyote fomu validations mimi haja ya kufanya kwenye tovuti, ambayo kwa upande kufanya mimi furaha sana! Nilikuwa na baadhi ya mafanikio usiku jana na CGI::Application superclass mimi nina kujenga <unk> Mimi kweli got ni kufanya kazi na CGI::Wiki::Simple (baada ya mimi debugged mwisho kurekebisha baadhi ya masuala ya uwakilishi!). Sasa kwa kuwa najua "uthibitisho wa dhana" kazi, Mimi ni tayari kuanza katika baadhi ya masuala mengine. Suala la kwanza ni: jinsi gani naweza kutaja directory tofauti kwa ajili ya maombi tofauti ya kutafuta templates, wakati kuhifadhi directory default hivyo kwamba superclass inaweza kujenga ukurasa wa mwisho? Mimi daima inaweza tu kuweka templates zote katika directory moja na tu prefix yao, lakini kwamba inaonekana unelegant, kwa namna fulani. Mimi itabidi kuchunguza jinsi HTML:: Template ushirikiano kazi na CGI:: App. Pili, na inayohusiana kwa karibu: ninataka ionekaneje, mwishowe? Ningeweza kuona kuweka muundo tuna <unk> ni safi, rahisi, na bado kwa njia fulani kazi kifahari. Okay, mimi nina exaggerating <unk> ni yako ya kawaida tatu safu na header na footer. Lakini inaenda na wazo la vitalu vya maudhui. Ninahitaji kufikiri juu ya hilo. Niliona wazo la kubuni kwa WikiWikiWeb leo, ingawa, kwamba kabisa iliyopita mawazo yangu ya jinsi Wiki inapaswa kuangalia. Wikipedia haijawahi kuonekana kwa muda mrefu, lakini kiungo cha Google kwa Gaston Julia kilionekana kwenye Slashdot wakati ilifunga tovuti moja nchini Australia, na hivyo nilitembelea. Ninapenda kubuni mpya <unk> ni kutenganisha nje ya viungo kawaida zinahitajika katika nzuri kushoto orodha, na kuweka subset ya kwamba juu na chini ya safu kuu pia, kutumia mipaka nzuri kwa kuona kutenganisha mambo. Mimi sana kupendelea ni kwa mtindo default ya PhpWiki, kama vile kwa kitu kingine chochote mimi kweli nimeona hadi sasa kuhusiana na mpangilio Wiki. Kwa hiyo, mimi ni kidogo ya mjinga... imekuwa muda mrefu tangu mimi inaonekana bado nilihisi nilikuwa na ufahamu kama juu yake, kwamba mimi overlooked hatua ya wazi: kuangalia mwongozo! Kwa mfano, kuna njia kadhaa ambazo zinatumiwa kurekebisha CGI: App kwa mahitaji yako maalum, na hizi ni pamoja na njia ya kuanzisha. Inaweza kutumika kupakia mipangilio kutoka mahali pengine; kama ni kuitwa tu kutoka superclass ambayo modules nyingine kurithi, ingekuwa kisha kutoa mipangilio ya kawaida kwa modules zote. $self->prerun_mode ('mode') wito kwa override kuchaguliwa kukimbia-mode, kwa mfano, hivyo kuruhusu wewe kuelekeza kwa hali tofauti kama mtumiaji si kuruhusiwa huko.) Kwa kuongezea, unaweza kutaja katika superclass kwamba unatumia CGI::Simple kwa kitu cha swali (kwa kutumia njia ya cgiapp_get_query), au unaweza kuandika upya njia ya load_tmpl () kutumia Template::Toolkit au mfumo mwingine wa templating, nk. Haionekani hivyo wazimu tena... Nimekuwa wanataka redevelop tovuti yangu nyumbani kwa muda fulani kwa kutumia CGI:: Maombi. Wakati wa mwisho nilipoandika kutoka PHP hadi Perl, nilitengeneza kitu ambacho kilikuwa sehemu ya vitu ambavyo CGI: App hufanya, na vitu hivyo havikufanywa karibu na vile. Tatizo nimekuwa mbio katika ina kufanya na kuwa na maudhui sidebar, na wanataka kukimbia kimsingi aina ya maombi. WikiWikiWeb, gallery ya picha, baadhi ya fomu za barua pepe, na makala database blog; CGI::App-msingi modules kwa kila moja ya haya yote zipo. Lakini nataka wote kutumia sawa sidebar maudhui, kama vizuri <unk> na kwamba sidebar maudhui inaweza kutofautiana kulingana na mtumiaji. Maslahi yangu got sparked na node hii juu ya Perl Monks. "Mwandishi anasema, ""Mtu anayejulikana ambaye anafuata sheria kwamba CGI: App inapaswa kuwa na hali 10-12 zaidi ya hapo, na unahitaji ama kuivunja au kufikiria upya muundo wako.""" Kwa hivyo, kila kitu kinachohusiana na superclass, na kila kitu kina uhusiano wa DB, na kila kitu kina uhusiano wa DB. "Kama ilivyoelezwa hapo juu, ""node moja kwenye PM inabainisha kwamba ISP yake hutumia CGI::App na mamia ya hali za kukimbia zilizoenea katika maombi mengi; waliunda moduli ya usimamizi wa kikao na udhibiti wa ufikiaji ambao huita kutumia msingi wa CGI::Application; kila maombi kisha huita kutumia msingi wa udhibiti, na wote wana usimamizi wa kikao sawa na ufikiaji, na vile vile node nyingine inataja kitu kimoja, lakini inatoa maelezo zaidi.""" Mwandishi kwamba anaandika moduli kwa kila maombi, kila urithi kutoka super darasa: Search.pm, nk. Unatengeneza API kwa ajili ya darasa hilo kubwa, na kila CGI::App hutumia API hiyo kufanya kazi yake. Hii pia inaonekana kuwa wazo nyuma CheesePizza, CGI::App-msingi mfumo kwa ajili ya kujenga maombi. (Pizza zote huanza kama pizza za jibini; unapoongeza tu viungo.) Tatizo na kwamba, ingawa, ni kwamba mimi kuwa na kujifunza mfumo mwingine juu ya CGI::App, badala ya intuiting yangu mwenyewe. Lakini ninawezaje kuandika superclass? Kurudi kwa node ya awali ambayo sparked maslahi yangu, Nilipata jibu baadaye kwamba ilivyoelezwa jinsi ya kufanya hivyo. Kumbuka, kwa mfano, kwamba CGI: App inaweza kuonekana kama sehemu ya template yako. Grist kwa ajili ya kinu... Jambo moja nimekuwa ajabu kuhusu ni syntax ya faili robots.txt, ambapo ni kuwekwa, na jinsi ni kutumika. Mimi najua kwamba ni kutumika kuzuia buibui kutoka kupata tovuti yako, lakini kwamba ni kuhusu hilo. Kwa sababu ya kuonekana kwa muda mrefu, tumeamua kuwapa wanachama wa bure, na hatutaki kuorodheshwa na injini za utafutaji. Pia nimejiuliza jinsi tunaweza kuondoa maeneo fulani, kama vile ambapo sisi kukusanya takwimu zetu tovuti, kutoka injini hizi. Kama inavyotokea, ni kweli kifo rahisi. "Kufanya hivyo, fanya faili ya ""robots.txt"" kwenye HTML yako, na syntax ni kama ifuatavyo: ""Mtumizi-wakala anaweza kutaja mawakala maalum au wildcard; kuna buibui wengi huko nje, ni pengine salama zaidi tu kuachana nao wote.""" Disallow mstari lazima kuwa na njia moja tu au jina, lakini unaweza kuwa na mstari Disallow nyingi, hivyo unaweza kutengwa idadi yoyote ya njia au faili.