Ik ben het er mee eens, al lang trouwens.
De slechte reputatie van PHP als traag e.d. komt volgens mij ook vaak door slechte code die er rondzwerft op het internet.
Ook van PEAR word ik niet zo heel erg blij, maar das vnl omdat ik al wat langer met PHP 5 werk.
Ook wat crisp zegt, goede html erg belangrijk, natuurlijk gescheiden van de business logic, de xml tussenstap heeft voordelen, zoals al genoemd caching, maar in combinatie met XSL ook nog een mooie skinning engine.
Veiligheid is ook nog absoluut een punt, er zijn hopen sites waar je dmv een GET variable aan te passen andere, soms niet voor je ogen bedoelde informatie kan krijgen, ik schreef me ooit in op een php site, ik kreeg een tekstje in de zin van: "Welkom $gebruikersnaam, je passwoord is $passwoord."
Nu was dit in een popup en kreeg je niet meteen de URL hiervan te zien, maar ff view page info in mozilla, url kopieren, in gewone browser: welkom.php?user=$mijnuid
Nummertje veranderen en je kon andere gasten hun username & passwoord zien (erg moeilijk om dan met die account in te loggen

).
Een ander voorbeeld was SQL injection bij een van de grootste ISP's van België die een lanparty organiseerden, ingeschreven personen konden inloggen en hun gegevens wijzigen. Geen addslashes, dus als username (die je uit een lijst kon c/p'n) met een single quote, punt-komma en twee streepjes (commentaar in sql) (';--) en je kwam op die persoon z'n account
Zelf heb ik mijn grootste frustraties opgelost met wat collega studenten door een eigen framework op te bouwen, zoals pear hoeft het ook slechts op één plaats op de server te staan zodat een geupdate versie ook meteen alle bugs fixed in alle apps die ermee geschreven zijn.
Warning volgende code fragmenten bevatten aardige java ripoff
PHP:
1
2
3
4
5
6
7
8
9
| <?php
include('../zen-ng/zen.php');
zen::import('/core/http/request.class.php');
zen::import('/core/ui/listview.class.php');
zen::import('/core/tpl/tpl.class.php');
zen::import('/core/error/fileLogger.class.php');
zen::import('/core/error/mailNotification.class.php');
zen::import('/core/error/socketNotification.class.php');
?> |
Die error handling classen zijn eigenlijk ontstaat vanuit het feit dat ik errors netjes wilde weergeven, maar het is meteen ook wat uitgebreid geworden met zogenaamde "debugdrivers" waarmee we meteen als developer verwittigd kunnen worden bij een error, een vriend heeft PET ontwikkeld waarmee je à la msn errors krijgt. [
screenshot] [
screenshot]
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
| <?php
/*
de eerste parameter is null, maar kan een array bevatten met files
waarvan hij de source niet mag tonen (kan ook volledig uitgezet worden)
zie eerste screenshot
2de parameter bevat de directory waar de error template zich bevind
die kan in de lokale applicatie overriden worden met een eigen template per app
en de 3de is de error reporting level
*/
new ErrorHandler(null, zen::path().zen::tplPath, E_ALL); // template based
/* hier word er notification gestuurd naar een socket, kan ook een file,
sqllite db, e-mail zijn, en zodra er jabber classes zijn ook een jabber versie
erg handig als je met 4 developers aan een project werkt met een stuk of 20 testusers,
moeten ze niet meer manueel in een mailtje zeggen van woops er ging wat fout, weet niet weer,
weet niet wat maar je hebt meteen alle uitgebreide informatie die je maar wil
*/
ErrorHandler::registerNotificationDriver(new errSocketNotification('10.0.0.2', 666));
/* dankzij php5 kunnen we hier ook een erg uitgebreide interface voor maken
en typehinting gebruiken als parameter voor de registerNotificationDriver functie */
interface errorNotificationDriver {
public function raiseError($errno, $errstr, $errfile, $errline, $vars);
}
/**
* @return void
* @param errorNotificationDriver $end
* @desc registers a notification driver that will be excecuted when an error occurs
*/
static public function registerNotificationDriver(errorNotificationDriver $end){
ErrorHandler::$notificationList[] = $end;
}
?> |
Wat ook meteen het punt van documentatie duidelijk maakt, er zijn standaard pakketten als phpDoc en javaDoc achtige toestanden die hieruit prachtige html bestanden kunnen genereren, de Zend development enviroment gebruikt ze dan ook nog eens bij de auto completion zodat je niet manueel naar de docs moet gaan kijken.
Voor de security is er de dbl die alles afhandelt dmv arrays en daar zelf de escape functie over haalt, t'is in de stijl van de key is veld dat geupdate moet worden en de value eraan is de nieuwe waarde.
En voor de GET/POST vars is er de request classe ism de Type classe, je krijgt bijvoorbeeld een warning wanneer je een $_GET['onbestaandeGetVar'] doet, een simpele wrapper functie lost dat op en daar kan je dan meteen typing doen desgewenst.
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| <?php
/**
* @return mixed
* @param mixed $index
* @param integer $type
* @desc returns a get variable but with isset and optional type checking
*/
public static function get($index, $type = null){
if (isset($_GET[$index])){
if (is_null($type)){
return $_GET[$index];
} else {
return Type::setType($_GET[$index], $type);
}
} else {
return false;
}
}
?> |
PHP:
1
2
3
| <?php
$id = Request::get('id', Type::INTEGER);
?> |
Ook de herbruikbaarheid van templates voor userinterfaces vond ik beter kunnen, hoe vaak zit je niet opnieuw een tabel volledig uit te typen.
Nu laat de template engine dit toe door een dir met standaard templates te hebben zoals een listview achtig iets, natuurlijk heeft de klasse die dit produceerd dan wel een instantie nodig van de Template engine, daarom moet die dus eerst aangemaakt worden en geregistreerd bij de Framework classe:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| <?php
zen::register(new Template('bleh.tpl'));
// in de Listview class:
$tpl = zen::getInstanceOf('Template');
// properties instellen van de listview:
// data kan ook rechtstreeks uit de Database layer komen
$lvwParams['data'] = array(array('bleh', 'blah', 'blehz0r'),
array('blahz0r', 'bloeh', 'bloehz0r'),
array('','blieh',null),
array(null, null, 'bleh'));
$lvwParams['headers'] = array('naam', 'voornaam', 'bleh');
$lvwParams['highlight'] = 'naam';
$lvwParams['selectname'] = 'id';
$lvwParams['listmode'] = Listview::LVW_SELECT;
new listview($lvwParams);
?> |
Wat er dan uiteindelijk zo komt uit te zien:
Nogmaals geef ik Crisp nog eens gelijk en vindt ik dat niet alles serverside moet, zo heb ik bij m'n isp slechts statische ruimte ter beschikking wat me dwong creatief te zijn, uiteindelijk zijn er wel server side scripts die lokaal draaien en thumbnails maken pagina's genereren en die via ftp doorstuurt naar m'n static webspace, maar daar heb ik dan zoveel mogelijk met JavaScript gewerkt om een dynamisch feel te geven, en uiteindelijk ziet het er nu allemaal vlotter uit omdat er geen postbacks zijn, slideshow kan zonder page reloads of andere truukjes. [
vb] (slideshow wanneer je op een thumb klikt)
Nu vrees ik dat deze post veels te lang geworden is (t'regent buiten

), maar ik hoop vooral dat mensen hier wat originele ideeën uit kunnen putten en php misschien een beetje positiever bekijken, natuurlijk zijn dingen als dit ook vrij persoonlijk (coding/documenting style) maar dat heeft niet meteen iets te maken met security gaten die ontstaan in je web app.
Ik hoop dat met de komst van PHP 5 er een kwaliteitsverbetering komt in de source base die openlijk beschikbaar is. Een standaard reporting level van E_ALL of beter nog E_STRICT (

) zou al een hoop schelen bij beginners

Niet te vergeten dat ook E_ALL code langer zal blijven draaien terwijl PHP in versie nummers stijgt en compatibiliteit breekt, zoals met superglobals het geval was.
Een jaar geleden heb ik trouwens een tutorial/code guideline-achtig iets gemaakt (35 bladzijden) maar das al vrij hopeloos outdated en heeft ook niet echt een groot publiek bereikt, iets wat het probleem is met veel tutorials denk ik. Wanneer je als team werkt aan een professioneel PHP project lijkt het mij wel nuttig om zoiets op te stellen als het al niet aanwezig is.
edit:
@AtleX: woei, graag gedaan

Nog 2 kleine tips:
drm's tiplist:
http://gerard.yoursite.nl/got/php-tiplist/
en ACM had een PDF geschreven over beveiling van web applicaties, heb er geen url meer van, maar als hij dit leest wil hij hem misschien nog wel eens posten, k'heb em toen iig doorgenomen en vond hem wel nuttig (maar ik kan de pdf zelf ook niet meer terugvinden maar denk wel dat het van hem was

)
[
Voor 10% gewijzigd door
Apache op 05-07-2004 16:00
]