Ik ben de maintainer van een open source PHP applicatie. Deze applicatie bestaat al ruim 10 jaar en zo'n 5 jaar geleden heb ik de development overgenomen. De applicatie is dus ooit geschreven in PHP3 en slechts mondjesmaat aangepast naar PHP4 en PHP5. De oorspronkelijke auteur was een doorgewinterde OO-ontwikkelaar en die heeft ook een keuring objectmodel bedacht. Ik ben maar een hobby-programmeur en ben zo'n beetje in zijn stijl verder gegaan. De classes bevatten de Model-code, maar Controller en View staan zo'n beetje door elkaar heen.
Vorig jaar heb ik het boek Professional PHP5 (aanrader!) gelezen en er achter gekomen dat veel van mijn PHP-kennis achterhaald was.
Ik ben dus nu begonnen om nieuwe code volgens nieuwe principes te schrijven (public/private, static methods ipv global functions, phpdoc tags, etc.) en daar hoort natuurlijk ook een nette MVC-scheiding bij. Ik wil geen gebruik maken van een framework omdat ik geen afhankelijkheid van externe code wil, frameworks vaak veel meer bieden dan ik nodig heb en natuurlijk ook omdat ik gewoon eigenwijs ben.
Ik heb op GoT en op de rest van Internet van alles gelezen over MVC, templates, etc. Ik heb ook van een aantal frameworks de sourcecode en de documentatie bekeken maar ik ben er toch nog niet uit hoe ik templates netjes op moet lossen. Doordat ik enige ontwikkelaar ben en ik zelf ook niet in de softwaredevelopmenthoek werk mis ik een beetje een sparring partner, daar ga ik jullie dus voor misbruiken :-) en misschien wordt dit nog wel een topic waar anderen nog wat van kunnen leren.
Dit is ruwweg zoals het nu in elkaar zit:
Zo zijn er een aantal functies die allerlei soorten HTML elementen genereren, maar her-en-der staat er ook wel wat HTML in de models. Dat moet dus anders.
Het afgelopen half jaar heb ik gewerkt aan een nieuwe feature, en die heb ik ongeveer zo opgezet:
Hier is de HTML netjes van de rest gescheiden en het ziet er allemaal redelijk overzichtelijk uit. Maar, nu ga ik een nieuwe feature toepassen, waar de forms veel uitgebreider en complexer zijn en eigenlijk heb ik geen zin om die forms helemaal handmatig te gaan uitschrijven. Natuurlijk kan ik in de templates gebruik maken van wat foreach-lussen e.d., maar bij complexere formulieren (met geneste fieldsets, verschillende typen input-velden, etc.) wordt dat lastig om dat netjes voor elkaar te krijgen.
Nu zou ik natuurlijk een aantal objecten form, input, fieldset, etc. aan kunnen maken en op die manier een form gaan opbouwen, dit is volgens mij hoe bijvoorbeeld Symfony dat doet.
Dan zou je zoiets krijgen:
Maar ja, dan zit de HTML weer in de form/input/fieldset objecten en niet in een template. Dus iemand die een nieuwe template voor mijn applicatie bouwt kan de HTML niet aanpassen...
Natuurlijk kan ik de HTML dan weer uit die objecten halen en daar mini-templates voor maken, maar dan wordt het echt onoverzichtelijk, denk ik.
Kortom: zijn er nog andere manieren om zoiets aan te pakken, hoe zouden jullie dit doen? Is er op een nette manier een combinatie van bovenstaande te maken? Waar ik aan zat te denken was om de manier met de template-class aan te houden en daar voor de complexe en dynamische delen van de site (met name forms dus) een aantal classes aan te maken zoals in het laatste voorbeeld, maar ik ben toch bang dat het dan onoverzichtelijk wordt.
Vorig jaar heb ik het boek Professional PHP5 (aanrader!) gelezen en er achter gekomen dat veel van mijn PHP-kennis achterhaald was.
Ik ben dus nu begonnen om nieuwe code volgens nieuwe principes te schrijven (public/private, static methods ipv global functions, phpdoc tags, etc.) en daar hoort natuurlijk ook een nette MVC-scheiding bij. Ik wil geen gebruik maken van een framework omdat ik geen afhankelijkheid van externe code wil, frameworks vaak veel meer bieden dan ik nodig heb en natuurlijk ook omdat ik gewoon eigenwijs ben.
Ik heb op GoT en op de rest van Internet van alles gelezen over MVC, templates, etc. Ik heb ook van een aantal frameworks de sourcecode en de documentatie bekeken maar ik ben er toch nog niet uit hoe ik templates netjes op moet lossen. Doordat ik enige ontwikkelaar ben en ik zelf ook niet in de softwaredevelopmenthoek werk mis ik een beetje een sparring partner, daar ga ik jullie dus voor misbruiken :-) en misschien wordt dit nog wel een topic waar anderen nog wat van kunnen leren.
Dit is ruwweg zoals het nu in elkaar zit:
PHP: something.inc.php
1
2
3
4
5
6
7
8
9
10
| class something extends dbTable { [...] public function get_edit_array() { $return=array() foreach($this->fields as $name->$value) { $return[]=array("name"=>$name, "value"=> $value); } return $return; } } |
PHP: util.inc.php
1
2
3
4
5
6
7
8
9
| <?php function array_to_form($array) { $html="<form>\n"; foreach($array as $field) { $html.=" <input name=\"" . $field["name"] . "\">" . $field["value"] . "</input>"; } $html.= " <input type=submit>"; $html.="</form>" } |
PHP: something.php
1
2
3
4
5
6
7
8
9
| <?php $var=getvar("var"); ?> <h1><?php echo $title; ?></h1> <?php if($_action="edit") { echo array_to_form($something->get_edit_array); } ?> |
Zo zijn er een aantal functies die allerlei soorten HTML elementen genereren, maar her-en-der staat er ook wel wat HTML in de models. Dat moet dus anders.
Het afgelopen half jaar heb ik gewerkt aan een nieuwe feature, en die heb ik ongeveer zo opgezet:
PHP: form.tpl.php
1
2
3
4
5
6
7
8
9
10
| <form action="<?php echo $tpl_action ?>"> <fieldset> <legend>fieldset 1</legend> <label>eerste</label> <input><?php echo $tpl_field1 ?></input> <label>tweede</label> <input><?php echo $tpl_field2 ?>/input> </fieldset> <input type="submit"> </form> |
PHP: template.inc.php
1
2
3
4
5
6
7
| class template { private $vars=array(); function __toString() { extract($this->vars, EXTR_PREFIX_ALL, "tpl"); include($this->template); } } |
PHP: something.php
1
2
| $tpl=new template("form", array("action"=>"something.php", "field1"=>"value1", "field2"="value2")) echo $tpl; |
Hier is de HTML netjes van de rest gescheiden en het ziet er allemaal redelijk overzichtelijk uit. Maar, nu ga ik een nieuwe feature toepassen, waar de forms veel uitgebreider en complexer zijn en eigenlijk heb ik geen zin om die forms helemaal handmatig te gaan uitschrijven. Natuurlijk kan ik in de templates gebruik maken van wat foreach-lussen e.d., maar bij complexere formulieren (met geneste fieldsets, verschillende typen input-velden, etc.) wordt dat lastig om dat netjes voor elkaar te krijgen.
Nu zou ik natuurlijk een aantal objecten form, input, fieldset, etc. aan kunnen maken en op die manier een form gaan opbouwen, dit is volgens mij hoe bijvoorbeeld Symfony dat doet.
Dan zou je zoiets krijgen:
PHP:
1
2
3
4
5
6
| $form=new form(); $fieldset=new fieldset("fieldset"); $input=new input("field1", "value1"); $fieldset->addField($input); $form->addFieldset($fieldset); $form->display(); |
Maar ja, dan zit de HTML weer in de form/input/fieldset objecten en niet in een template. Dus iemand die een nieuwe template voor mijn applicatie bouwt kan de HTML niet aanpassen...
Natuurlijk kan ik de HTML dan weer uit die objecten halen en daar mini-templates voor maken, maar dan wordt het echt onoverzichtelijk, denk ik.
Kortom: zijn er nog andere manieren om zoiets aan te pakken, hoe zouden jullie dit doen? Is er op een nette manier een combinatie van bovenstaande te maken? Waar ik aan zat te denken was om de manier met de template-class aan te houden en daar voor de complexe en dynamische delen van de site (met name forms dus) een aantal classes aan te maken zoals in het laatste voorbeeld, maar ik ben toch bang dat het dan onoverzichtelijk wordt.