Archiv der Kategorie: PHP

In more pro­jec­ts than I care to think about, I’ve seen a pat­tern that I dis­li­ke the more I see it. It appears qui­te inno­cent, but it brings about cost with no dis­cer­ni­ble bene­fit.

Inclu­ding all of the application’s source code on each and every call being made to a page. It may be that one file is inclu­ded that lists all files the app brings along; it may be a list of require_once state­ments in every ent­ry page it has. But what is the bene­fit? Even if the page loads only tho­se files that it might even­tual­ly need, it pro­bab­ly inclu­des more than is war­ran­ted given the task it is cur­r­ent­ly given.

One solu­ti­on is to get into using an auto­loa­der; let the inter­pre­ter figu­re out by its­elf whe­ther it has alrea­dy seen all that it needs to exe­cu­te a given pie­ce of code. The other opti­on is to requi­re exter­nal files only at the point that you’­re cer­tain that you need them. Does your code do input saniti­zing and vali­da­ti­on befo­re it loads the clas­ses that then work with the saniti­zed values? Pro­bab­ly not – it’s much more com­mon to first load all the code, and only then start to work with what you are given.

Lazy loa­ding means that the inter­pre­ter only runs on tho­se code parts it needs, hel­ping to con­tri­bu­te to bet­ter app­li­ca­ti­on per­for­mance (becau­se we’­re not spen­ding time on code we don’t real­ly need, any­way). This also means using less resour­ces on the ser­ver, which means bet­ter use of resour­ces – ulti­mate­ly, having your code use less elec­tric power. But the­re is even more bene­fits: code that has not been loa­ded can­not be causing any kind of inter­fe­rence; you’­re cer­tain that you don’t have to look into tho­se files when you’­re debug­ging. And then, code that has not been loa­ded also can­not be used for secu­ri­ty exploits – so you have less side effec­ts the­re as well.

It’s not that this is a par­ti­cu­lar­ly com­plex intel­lec­tu­al chal­len­ge, it’s more a mat­ter of per­spec­tive and may­be wri­ting infra­st­ruc­tu­re code for your app. But to me, the bene­fits are worth the few more minu­tes spent whilst thin­king about your code.

We’­re cur­r­ent­ly in the pro­cess of tran­si­tio­ning our web ser­vers from Net­BSD to Dra­gon­flyBSD; along with that, we’­re also swit­ching our PHP plat­form to php-fpm. The­re are a few les­sons we lear­ned in the pro­cess.

First: At least on Dra­gon­flyBSD 2.10, apache2 does not at all per­form well as apa­che-mpm-worker. Swit­ching to apa­che-mpm-pre­fork chan­ged our CPU load from 98% of apa­che to about 3 – 5% of apa­che.

I’m cur­r­ent­ly wri­ting a libra­ry of PHP stuff for our inter­nal use. I’ve been able to make it do a few fun tricks.

To express a que­ry with a sub­que­ry, I can now do this:$sube = new Expression('subtable');
$sube->setResultField('id');
$sube->beginGroup('and');
$sube->addTerm('field1','=',$valueA);
$sube->addTerm('field2',' =','expr:now()');
$sube->endGroup;
$e = new Expression('table');
$e->addTerm('field2','not in',$sube);

While wri­ting the code to hand­le a small form in PHP, I just rea­li­zed that I have a very bad habit — and many just do the same.

When I wri­te a new file, I place all the includes at the very top, befo­re anything else hap­pens. But in my cur­rent script, the­re are many code paths that do not requi­re the major part of all tho­se inclu­des. Only in one spe­ci­fic instan­ce do we requi­re the bulk of the code. Pre­vious­ly, any invo­ca­ti­on of that script would have got­ten all the code drag­ged in. Now, I’ve moved the include to just whe­re I need the code (basi­cal­ly, going into a spe­ci­fic case of a lar­ger switch state­ment … And the load on the web ser­ver has just been redu­ced, wit­hout any chan­ge to the func­tio­n­a­li­ty.