[PHP] Eval(): wel of niet gebruiken?

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Zyppora
  • Registratie: December 2005
  • Laatst online: 12-09 10:59

Zyppora

155/50 Warlock

Topicstarter
Hoi allemaal.

De situatie
Ik zit op dit moment met een (homebrew) templating systeem dat vrij simplistisch van opzet is. HTML templates zitten in een (MySQL) database, en ik laat PHP deze opvragen en echo-en. Allemaal heel simpel en aardig, ware het niet dat er -ook- wat dynamica aanwezig is, en wel in de volgende vorm (simpel voorbeeld):

code:
1
<td>Naam: $username</td>


Uiteraard gaat het puur over het weergeven van data, en wordt er geen logica in de templates verweven. Wat ik nu doe, is een bepaalde pagina op volgende wijze aanroepen:

PHP:
1
2
3
4
5
6
7
8
9
<?php

// Username verkregen vanuit database
$username = 'Piet';

// getTemplate('template') roept bovenstaande template aan
$template = eval('echo "'.getTemplate('template').'";'); 

?>


Het alternatief
Het enige alternatief wat ik mij zo kan bedenken is gaan werken met str_replace() functies, maar ik vrees dat dat zo'n jungle aan code en bijhouden van variabelen gaat worden dat dat (onder andere) de maintainability van de code totaal niet ten goede gaat komen, zeker aangezien templates nog wel eens aangepast worden. Dat kan dan weer afgevangen worden met een (semi)globale array of zo:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php

// (semi)globale array met uit database verkregen data
$parsables['username'] = 'Piet'; 

// Roep bovenstaande template aan
$myTemplate = getTemplate('template');

// Parsen kan evt. in een functie
foreach ($parsables as $key => $value) {
  $myTemplate = str_replace('$'.$key, $value, $myTemplate);
}

echo $myTemplate;

?>


Misschien zie ik een heel simpel en beter alternatief over het hoofd, maar dit lijkt me het beste voor deze situatie.

De vraag
Ik heb Programming en SEA doorgezocht om te kijken wat er zoal te vinden is over het gebruik van eval(), en de meeste resultaten behandelden practische issues die (m.i.) relatief gemakkelijk op andere wijze opgelost konden worden. Daarbij kwam meer dan eens het mantra 'eval() is vies' langs (waar ik het overigens niet mee oneens ben, aangezien het in veel gevallen niet de juiste 'tool' is). Het verschil met mijn situatie hierboven is dat ik er geen suitable alternatief voor kan verzinnen. Zouden jullie hier eens jullie licht op kunnen laten schijnen?

Phenom II X4 945 \\ 8GB DDR3 \\ Crosshair IV Formula \\ R9 290


Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
eval = evil en is vrijwel nooit de juiste oplossing, hier ook niet imo.

Als je eens kijkt naar een andere template engine en kijkt hoe zij dat doen. Of gebruik simpelweg een bestaande en ontwikkelde template engine. Ook al gedacht aan het parsen van blokken ipv. enkele zinnen?

Acties:
  • 0 Henk 'm!

  • Brakkie
  • Registratie: Maart 2001
  • Niet online

Brakkie

blaat

Ik zou een template class maken met een property (array) waarin je je variabelen zet die je beschikbaar wilt hebben in je template. Geef die class een functie $template->render(); waarin je de output buffert en de juiste template include. Je template wordt dan gewoon door php geparsed. De gebufferde output kun je dan in een variabele zetten en er mee doen wat je wilt.

Systeem | Strava


Acties:
  • 0 Henk 'm!

Verwijderd

Toch zou ik gaan voor de alternatieve code die je zelf aangeeft. Dit zal op de manier zoals je het in je bericht plaatste, inderdaad een jungle aan code worden als het een stuk groter wordt. Echter kun je vrij eenvoudig de replace-functionaliteit in een functie stoppen, of wellicht zelfs in een class die het laden van templates en het vervangen van keys met waardes uit een array volledig overneemt. Zodat je met een simpele $template->replace(<array-met-keys-en-values>) klaar bent, of je 'set' elke key in je template met een $template->set(key, value) (of function set($key, $date, $template)).

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

Het replacen met str_replace hoeft helemaal geen zooitje te worden. Je kunt voor het vervangen gewoon een map maken (wat ze in php ook gewoon een array noemen). Hierin zet je in de key het label en in de value de te gebruiken tekst. Vervolgens kun je een functie gebruiken alla:
PHP:
1
2
3
4
5
6
7
8
9
$labelMap = Array();

$labelMap['username'] = $username;

function processTemplate($map, $template) {
  foreach ($map as $key => $value) {
    str_replace('{{'.$key.'}}',$value, $template);
  }
}


Code uit de losse pols

Ga asjeblieft niet met allemaal variabele variabelen werken. Dat maakt je code een stuk minder voorspelbaar en dus onveiliger. Door zelf een map te bouwen heb je exact de controle over welke labels je wel en welke labels je niet in je template wil. Denk maar eens aan de volgende situaties:

Hacker weet een template in de DB te krijgen met daarin variabelen als $mysql_password of andere gegevens die je liever voor jezelf houdt.
Hacker weet php code in template te krijgen alla include('/etc/passwd');


edit: Ik merk dat ik weer rijkelijk traag ben :D

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 16:36
Brakkie schreef op donderdag 03 april 2008 @ 10:38:waarin je de output buffert en de juiste template include. Je template wordt dan gewoon door php geparsed.
Uit een database kun je vrij lastig includen. De enige manier om PHP-code uit een variabele uitgevoerd te krijgen is eval (of iets smerigs met een tijdelijk bestand).

Als er een goede reden is om de templates in de database op te slaan is een eval() hier best te verdedigen. Ik kan me alleen niet voorstellen dat er een goede reden is om templates in een database op te slaan.

[edit]Alhoewel ik de str_replace-methode elegant vind zit er wel een nadeeltje aan: je verliest de mogelijkheid om op template-niveau de weergavefuncties van PHP te gebruiken: ucfirst(), strtolower(), number_format() om maar wat te noemen. Om nog maar te zwijgen over loop-constructies...

[ Voor 19% gewijzigd door T-MOB op 03-04-2008 10:54 ]

Regeren is vooruitschuiven


Acties:
  • 0 Henk 'm!

  • Brakkie
  • Registratie: Maart 2001
  • Niet online

Brakkie

blaat

T-MOB schreef op donderdag 03 april 2008 @ 10:44:
[...]

Uit een database kun je vrij lastig includen. De enige manier om PHP-code uit een variabele uitgevoerd te krijgen is eval (of iets smerigs met een tijdelijk bestand).
Het gaat in mijn post om de template handling. Wanneer je templates in de db staan kan je natuurlijk vrij makkelijk je template na opslaan in de db ook op het filesystem wegschrijven.

Systeem | Strava


Acties:
  • 0 Henk 'm!

Verwijderd

De mantra eval = vies is erg kortzichtig. Er zullen best moeilijkere / tijdroverndere maar elegantere manieren zijn, zonder twijfel.

Maar je kunt eval best gebruiken als:
- Code nooit maar dan ook nooit userinput bevat.
- Je je php proccess (ja op OS niveau) ondere een limited user draait. Zodat mocht het ergste zich voordoen de impact maar klein is.

Wat je met eval toestaat is dat er variable code word uitgevoerd. Maak ook niet de klassieke fout door database data als "veilig" te beschouwen, een sql injection attack is makkelijker dan een webserver hacken. En bij jou zou de hacker door SQL injectie ook toegang krijgen tot php.

Probeer te kijken of het de bovenstaande risico's waard is. Ik denk het niet.

[ Voor 5% gewijzigd door Verwijderd op 03-04-2008 10:55 ]


Acties:
  • 0 Henk 'm!

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Aangezien je dus nu eigenlijk nog geen template systeem hebt, zou je eens naar smarty kunnen kijken. Smarty heeft ook de mogelijkheid om templates uit de database te halen

http://www.smarty.net/manual/en/template.resources.php, zie code voorbeeld Example 15-9. Using custom resources.

If it isn't broken, fix it until it is..


Acties:
  • 0 Henk 'm!

Verwijderd

T-MOB schreef op donderdag 03 april 2008 @ 10:44:
[...]

[edit]Alhoewel ik de str_replace-methode elegant vind zit er wel een nadeeltje aan: je verliest de mogelijkheid om op template-niveau de weergavefuncties van PHP te gebruiken: ucfirst(), strtolower(), number_format() om maar wat te noemen. Om nog maar te zwijgen over loop-constructies...
Als de TS gebruik zou maken van array(key,value) als input voor z'n template-replace-functie, dan kan ie natuurlijk ook input[key] = strtolower(value) gebruiken. En mocht het niet de bedoeling zijn dat dit soort weergave-dingen niet in phpcode geregeld worden, dan kan ie ook nog andere template-tags gaan gebruiken, dus niet $username, maar bijvoorbeeld {username:flag} of wat voor combinatie dan ook, zolang de template-class er maar mee om kan gaan en niet een 'simpele' str_replace doet, maar ook de evt. extra parameters voor die key controleert.

Wbt loop-constructies, dit gaat wel een beetje verder dan een str-replace, maar een loop-constructie is eigenlijk niets meer dan een str_replace welke meerdere malen uitgevoerd wordt met als input een multidimensionale array, waarbij elk element de eerder genoemde array(key, value) bevat.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

PHP is een template taal. Gewoon je templates includen als files geeft dan ook de meeste flexibiliteit imho.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

Verwijderd schreef op donderdag 03 april 2008 @ 10:54:
De mantra eval = vies is erg kortzichtig. Er zullen best moeilijkere / tijdroverndere maar elegantere manieren zijn, zonder twijfel.

Maar je kunt eval best gebruiken als:
- Code nooit maar dan ook nooit userinput bevat.
- Je je php proccess (ja op OS niveau) ondere een limited user draait. Zodat mocht het ergste zich voordoen de impact maar klein is.
Sorry, ik moet hier even op reageren. Ik denk namelijk eerder dat jij hier degene bent die kortzichtig is omdat je compleet voorbij gaat aan de maintainability en testability van je ontwikkelde software.
Wat je met eval toestaat is dat er variable code word uitgevoerd. Maak ook niet de klassieke fout door database data als "veilig" te beschouwen, een sql injection attack is makkelijker dan een webserver hacken. En bij jou zou de hacker door SQL injectie ook toegang krijgen tot php.
Hiermee kan ik het niet meer dan eens zijn.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 16:36
Verwijderd schreef op donderdag 03 april 2008 @ 11:04:
[...]
Als de TS gebruik zou maken van array(key,value) als input voor z'n template-replace-functie, dan kan ie natuurlijk ook input[key] = strtolower(value) gebruiken. En mocht het niet de bedoeling zijn dat dit soort weergave-dingen niet in phpcode geregeld worden, dan kan ie ook nog andere template-tags gaan gebruiken, dus niet $username, maar bijvoorbeeld {username:flag} of wat voor combinatie dan ook, zolang de template-class er maar mee om kan gaan en niet een 'simpele' str_replace doet, maar ook de evt. extra parameters voor die key controleert.

Wbt loop-constructies, dit gaat wel een beetje verder dan een str-replace, maar een loop-constructie is eigenlijk niets meer dan een str_replace welke meerdere malen uitgevoerd wordt met als input een multidimensionale array, waarbij elk element de eerder genoemde array(key, value) bevat.
En dan krijg je dus de jungle van replace-functies waar de TS het over heeft. Volgens mij kun je dan beter kijken naar een bewezen template-oplossing als smarty. Maar nogmaals: ik zie niet zo waarom je templates in een database zou willen plaatsen.

Regeren is vooruitschuiven


Acties:
  • 0 Henk 'm!

Verwijderd

Janoz schreef op donderdag 03 april 2008 @ 11:26:
[...]

Sorry, ik moet hier even op reageren. Ik denk namelijk eerder dat jij hier degene bent die kortzichtig is omdat je compleet voorbij gaat aan de maintainability en testability van je ontwikkelde software.
Er zijn meer dan genoeg usecases waar eval gewoon goed word gebruikt. Je moet je alleen bewust zijn van de impact die het heeft. Neem drupal bijvoorbeeld, gebruikt met regelmaat eval.

Dat testen uiteraard moeilijker word was mij ook wel duidelijk. Maar dat heb je bij alle systemen waarbij je zo dynamisch wilt zijn. Over maintainen en testen heef iedereen zijn eigen iedeën. Ik zou persoonlijk mij hier ook niet aan wagen.

Acties:
  • 0 Henk 'm!

Verwijderd

T-MOB schreef op donderdag 03 april 2008 @ 11:27:
[...]

En dan krijg je dus de jungle van replace-functies waar de TS het over heeft. Volgens mij kun je dan beter kijken naar een bewezen template-oplossing als smarty.
Als de TS die functionaliteit in een template class oid zou stoppen, dan hoeft dat helemaal geen jungle aan code op te leveren, en dan kan ie in z'n php-scripts voldoen met een template->maaklijstje(array).
Maar nogmaals: ik zie niet zo waarom je templates in een database zou willen plaatsen.
Dat is een andere discussie imo, waarin ik het met je eens bent. Ik zie zelf ook niet zo snel de voordelen van het plaatsen van templates in een db ipv op een filesystem.

Acties:
  • 0 Henk 'm!

  • Zyppora
  • Registratie: December 2005
  • Laatst online: 12-09 10:59

Zyppora

155/50 Warlock

Topicstarter
Man, jullie reageren snel :D

@Cartman!:
Ik heb deze methode geleerd vanuit een bestaande template engine, en wel degene die in de vBulletin software zit (of zat, ik geloof dat het v2.x was). Daarin was het gebruik van eval() echter een gigantisch groot zooitje. Dat heb ik ahw. geforked en ben ik gaan optimaliseren. Wat bedoel je precies met 'het parsen van blokken'? Ik heb een tabel met 200+ templates opgeslagen, varierend in lengte van het voorbeeld (of nog erger: enkel een parsable variabele) tot complete HTML paginas.

@Brakkie:
Da's inderdaad het meest mooie waar ik aan zat te denken, maar dan zit ik nog steeds met het bijhouden van de parsable variabelen. Daarnaast zal ik deze variabelen dan ook nog eens door moeten geven aan de class omdat ze standaard buiten de scope vallen. Is in principe geen probleem, maar maakt het er allemaal niet overzichtelijker op. Ook zit ik dan met het probleem dat mocht ik een extra (al in de page scope bestaande) variabele willen introduceren in een template, ik alsnog de PHP code zal moeten aanpassen, en dat is eigenlijk mijn grootste probleem hiermee.

Ik heb overigens de link bekeken en afgezien van het feit dat ik mijn templates in een database heb staan, en niet in remote files, vind ik het gebruik van output buffering voor zoiets eigenlijk net zo smerig als het gebruik van eval() ;) Maar daar kan uiteraard wel iets netters voor verzonnen worden.

@DarthRaider:
Zie ook mijn reply op Brakkie. Ik geef toe dat het eleganter is (en dan met name wanneer het gebakken wordt als object), maar het brengt extra handelingen met zich mee wanneer er aanpassingen gedaan worden.

@Janoz:
Je geeft heel goed weer wat de pijnpunten zijn, en met mijn neus op de feiten (db is niet by default veilig) gedrukt worden doet pijn :) Uiteraard probeer ik zoveel mogelijk vanuit een security-standpunt mijn code te schrijven, maar 100% hackerproof is het waarschijnlijk nooit. Ik zal dit advies zeer ter harte nemen.

@T-MOB:
De redenen waarom ik mijn templates in de database zet, en niet in remote files, zijn onder meer het aanpassen vanuit de admin panel, extra metadata die toegevoegd kan worden, en het schoonhouden van het filesysteem (200+ .tpl bestanden is ook maar zo-zo). Daarnaast kun je met een database statistische informatie weergeven wat je met remote files niet of relatief moeilijk voor elkaar krijgt.

@j.ostie:
Code die ge-eval()ed wordt, bevat -nooit- user input ;) In elk geval geen user input die niet eerst door tal van checks getrokken is en in de database beland is (username bijvoorbeeld). PHP code onder een limited user account laten draaien lijkt me ook zeer lucratief, maar ik ga ervan uit dat (zeker bij een externe hosting provider) dit zonder meer zo is (als de hosting provider eval() uberhaupt wel toestaat, ik dacht dat je dat in php.ini kon disablen).

@Niemand_Anders:
De Smarty code die jij aangeeft, geeft me niet erg veel informatie. Het lijkt me daarentegen goed eens tegen de totale code van Smarty aan te kijken, waarschijnlijk leer ik daar weer van ;)

@DarthRaider:
Nee, het gebruik van extra tags of opties in de dynamische onderdelen van de templates wil ik zoveel mogelijk ondervangen en dit heb ik dus ook niet geimplementeerd. Wanneer dat toch nodig is zal ik dat (evt. conditioneel) met de values in de PHP code zelf doen, voordat de template ge-eval()ed wordt.

Phenom II X4 945 \\ 8GB DDR3 \\ Crosshair IV Formula \\ R9 290


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Verwijderd schreef op donderdag 03 april 2008 @ 11:31:
[...]
Er zijn meer dan genoeg usecases waar eval gewoon goed word gebruikt. Je moet je alleen bewust zijn van de impact die het heeft.
Dus eval() == evil is gewoon een uitstekend uitgangspunt. Als iemand zoveel inzicht heeft dat hij de gehele impact overziet1 kan deze persoon pas besluiten om met deze regel te breken2.

1: En dat zijn er te weinig. :P
2: En dat zijn er weer te veel. :+

{signature}


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Wil je eigenlijk per se het resultaat in een variabele? Want je zegt dat je output buffering vies vind, maar ik zie eigenljik geen reden om de output überhaupt tegen te houden :)
Zyppora schreef op donderdag 03 april 2008 @ 11:41:
@T-MOB:
De redenen waarom ik mijn templates in de database zet, en niet in remote files, zijn onder meer het aanpassen vanuit de admin panel, extra metadata die toegevoegd kan worden, en het schoonhouden van het filesysteem (200+ .tpl bestanden is ook maar zo-zo). Daarnaast kun je met een database statistische informatie weergeven wat je met remote files niet of relatief moeilijk voor elkaar krijgt.
Het feit dat je extra informatie in de database over templates op wilt slaan wil nog niet zeggen dat je die templates zelf ook per se in de database op wilt slaan :). Maar ik krijg hier wel het idee dat je de templates in veel kleinere stukken opdeelt dan ik zelf doe. Ik heb gewoon een template per pagina die je opvraagt. Natuurlijk heb ik zaken als standaard header en footer e.d. in aparte files, maar een template kan dat zelf regelen door gewoon weer andere files te includen. En ik heb ook template informatie in een database (welke er zijn, waar ze staan, etc.), maar de templates zelf zijn gewoon losse files (in een dir die niet geexposed wordt op de webserver natuurlijk ;)).

Het voordeel hiermee is ten eerste dat het snel is, en ten tweede dat je enorm flexibel bent aangezien je in je templates gewoon PHP code kwijt kunt (zo kun je in de template bijvoorbeeld date formatting doen terwijl je systeem alleen een timestamp oid aanlevert, of data anders rangschikken)

[ Voor 86% gewijzigd door .oisyn op 03-04-2008 12:54 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

@T-MOB:
De redenen waarom ik mijn templates in de database zet, en niet in remote files, zijn onder meer het aanpassen vanuit de admin panel..
en
@j.ostie:
Code die ge-eval()ed wordt, bevat -nooit- user input ;)
Dat rijmt niet met elkaar ;).

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

Zyppora schreef op donderdag 03 april 2008 @ 11:41:
@Brakkie:
Da's inderdaad het meest mooie waar ik aan zat te denken, maar dan zit ik nog steeds met het bijhouden van de parsable variabelen.
Het is juist erg goed dat je exact weet welke variabelen wel en welke niet gebruikt kunnen worden. Daarnaast hoeft het nauwlijks extra werk op te leveren. Of je nu een variabele declareert of in een map zet verschilt nauwlijks, behalve dan dat bij de tweede manier duidelijk aangegeven wordt dat deze binnen templates gebruikt kan worden
Daarnaast zal ik deze variabelen dan ook nog eens door moeten geven aan de class omdat ze standaard buiten de scope vallen. Is in principe geen probleem, maar maakt het er allemaal niet overzichtelijker op.
Je hoeft alleen de map door te geven en imho is dat juist overzichtelijker.
Ook zit ik dan met het probleem dat mocht ik een extra (al in de page scope bestaande) variabele willen introduceren in een template, ik alsnog de PHP code zal moeten aanpassen, en dat is eigenlijk mijn grootste probleem hiermee.
Als je een variabele toevoegt ben je sowieso de source al aan het aanpassen (hoe komt de variabele er immers anders in?). En als hij blijkbaar al beschikbaar was, en bruikbaar voor in de templates dan had je deze waarschijnlijk ook al gelijk in je map op kunnen nemen.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Zyppora
  • Registratie: December 2005
  • Laatst online: 12-09 10:59

Zyppora

155/50 Warlock

Topicstarter
@.iosyn:
Soms mag de output gewoon rechtstreeks ge-echo-ed worden, soms wil ik die op deze manier gebruiken:

PHP:
1
2
3
4
5
6
7
8
9
10
11
<?php

$myRows = "";

while ($data = mysql_fetch_assoc($resultset)) {
  eval('$myRows .= "'.getTemplate('tablerows').'";');
}

eval('echo "'.getTemplate('table').'";');

?>


Waarbij de template 'table' dus de variabele $myRows gebruikt.

@Janoz:
Waarom zou dat niet rijmen? Met 'user input' bedoel ik dus $_GET/POST/COOKIE/etc. data die vanaf de anonieme gebruiker binnenkomt op willekeurige paginas, niet de input van mij (en een paar betrouwbare admins) die binnen een afgeschermd gedeelte van mijn web applicatie aan de templates kunnen.

In je tweede post geef je aan dat een variabele al aan de map toegevoegd had kunnen/moeten zijn, mocht ik hem al beschikbaar hebben. Da's natuurlijk slechts waar wanneer ik een enkel object aanmaak voor alle templates, en dus een grote ongeordende verzamelmap krijg (wat de overzichtelijkheid m.i. ook niet ten goede komt), of met static variables ga werken.

Variabelen hoeven trouwens niet expliciet gedeclareerd te worden, denk maar eens aan een resultatenset van een query. Op user info paginas bijvoorbeeld komt dat uitstekend van pas, SELECT * FROM users WHERE userid=$userid en je hebt impliciet alle informatie van de user, zonder daar extra declaraties bij te moeten zetten (dus ook niet bij een uitbreiding van de users tabel). Dan kun je die volledige array wel in je map zetten, maar daar wordt het ook niet echt eleganter mee. Daarnaast hoeven variabelen natuurlijk niet per se gebruikt te zijn in templates om beschikbaar te zijn op de pagina ;)

Ik geef grif toe dat het over het algemeen wel goed is om te weten welke variabelen in een template gebruikt kunnen worden, en anderen niet toe te laten; security-puntje ;)

Phenom II X4 945 \\ 8GB DDR3 \\ Crosshair IV Formula \\ R9 290


Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
Omdat je php direct als template kan gebruiken, heb ik een kleine template engine geschreven, waarbij in een klasse de variabelen worden opgeslagen en gepushed naar de template. Deze wordt dan gebuffered en opgeslagen. Verder is nog caching mogelijk en is qua "api" op eenzelfde lijn getrokken als smarty.

Check http://qwik-cms.nl/node/q-works/template-engine voor meer info :)

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

Zyppora schreef op donderdag 03 april 2008 @ 13:48:
@Janoz:
Waarom zou dat niet rijmen? Met 'user input' bedoel ik dus $_GET/POST/COOKIE/etc. data die vanaf de anonieme gebruiker binnenkomt op willekeurige paginas, niet de input van mij (en een paar betrouwbare admins) die binnen een afgeschermd gedeelte van mijn web applicatie aan de templates kunnen.
Gebruikers kunnen gegevens in de database krijgen. Ze hebben rechtstreeks invloed op wat er in de tabellen komt. Eval laat je los op de inhoud van die tabellen.

Dat je userinput als tussenstop even in de database heeft gestaan maakt het niet ineens geen userinput meer. Dat je admins betrouwbaar zijn doet daar niks aan af. Dat het vanaf betrouwbare personen via een beveiligd gedeelte binnenkomt maakt het niet ineens geen userinput meer.
In je tweede post geef je aan dat een variabele al aan de map toegevoegd had kunnen/moeten zijn, mocht ik hem al beschikbaar hebben. Da's natuurlijk slechts waar wanneer ik een enkel object aanmaak voor alle templates, en dus een grote ongeordende verzamelmap krijg (wat de overzichtelijkheid m.i. ook niet ten goede komt), of met static variables ga werken.
Ik neem aan dat je nu ook specifieke code hebt die de variabelen klaarstoomt voor je pagina. Wat maakt het dan uit dat je die variabelen in een map zat ipv in de scope laat? Ik begrijp niet waarom je, wanneer je een map wilt gebruiken, je ineens over static vars begint. Je kunt nu toch ook al gewoon bij de variabelen? Waarom zou dat anders worden wanneer je ze in een map zet?
Variabelen hoeven trouwens niet expliciet gedeclareerd te worden, denk maar eens aan een resultatenset van een query. Op user info paginas bijvoorbeeld komt dat uitstekend van pas, SELECT * FROM users WHERE userid=$userid en je hebt impliciet alle informatie van de user, zonder daar extra declaraties bij te moeten zetten (dus ook niet bij een uitbreiding van de users tabel). Dan kun je die volledige array wel in je map zetten, maar daar wordt het ook niet echt eleganter mee. Daarnaast hoeven variabelen natuurlijk niet per se gebruikt te zijn in templates om beschikbaar te zijn op de pagina ;)
Waarom zou die array opslaan minder elegant zijn? Dat begrijp ik niet. Goed, in mijn voorstel heb ik nog geen rekening met lusjes gehouden dus in die implementatie kun je nog geen array toevoegen, maar daarvoor zou je je template-engine uit kunnen breiden. Wat je expliciet niet wil doen is je resultset uit gaan lezen terwijl je je output al aan het genereren bent. Dat maakt de foutafhandeling alleen maar ingewikkelder (of levert erg slordige pagina's op met halverwege foutmeldingen)

Sowieso zou ik in een dergelijk geval eigen domein objecten gebruiken waarin ik een gebruiker opsla, maar dat is weer een heel ander verhaal.

[ Voor 57% gewijzigd door Janoz op 03-04-2008 14:14 ]

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Zyppora schreef op donderdag 03 april 2008 @ 13:48:

Waarom zou dat niet rijmen? ... niet de input van mij (en een paar betrouwbare admins) die binnen een afgeschermd gedeelte van mijn web applicatie aan de templates kunnen.
Die admins zijn nog geen programmeurs (cq. hoeven dat op dat moment niet te zijn) dus ze moeten gewoon de mogelijkheid tot het invoeren van generieke PHP code niet hebben.
Punt.
Bedenk eens waarom CMS software bestaat. Waarom zou men een uitgebreid CMS maken als een script met een sql select, insert en update functie erin al alles kan? ;)


Verder maak je een gevaarlijke aanname door alles dat niet GET, POST of COOKIE is te vertrouwen. Dankzij dergelijke aannames heb je of direct een lek, of een veel groter probleem zodra je ergens een miniem checkje achterwege laat.

[ Voor 10% gewijzigd door Voutloos op 03-04-2008 14:13 ]

{signature}


Acties:
  • 0 Henk 'm!

  • Zyppora
  • Registratie: December 2005
  • Laatst online: 12-09 10:59

Zyppora

155/50 Warlock

Topicstarter
@Mithras:
Jouw code (en die van Smarty trouwens ook, heb ik zojuist onderzocht) bevat wederom het mijns inziens 'smerige' output buffering truukje. Ik zou daar graag een alternatief op zien.
Janoz schreef op donderdag 03 april 2008 @ 14:05:
[...]

Gebruikers kunnen gegevens in de database krijgen. Ze hebben rechtstreeks invloed op wat er in de tabellen komt. Eval laat je los op de inhoud van die tabellen.
Nee, eval() laat ik los op inhoud van tabellen waar (gewone) gebruikers niet bij kunnen, en variabelen die daarin staan laat ik parsen naar inhoud die de gebruiker heeft ingevoerd, en welke ook nog eens gechecked is. Ik ben met eval() de user input dus eigenlijk een stap voor. Helaas geldt dat dus niet voor templates die output teruggeven die daarna weer in een ge-eval()de template gebruikt wordt.
Janoz schreef op donderdag 03 april 2008 @ 14:05:
Dat je userinput als tussenstop even in de database heeft gestaan maakt het niet ineens geen userinput meer. Dat je admins betrouwbaar zijn doet daar niks aan af. Dat het vanaf betrouwbare personen via een beveiligd gedeelte binnenkomt maakt het niet ineens geen userinput meer.
Het minimaliseert daarentegen wel het risico ;) Ik snap je punt overigens wel.
Janoz schreef op donderdag 03 april 2008 @ 14:05:
[...]

Ik neem aan dat je nu ook specifieke code hebt die de variabelen klaarstoomt voor je pagina. Wat maakt het dan uit dat je die variabelen in een map zat ipv in de scope laat? Ik begrijp niet waarom je, wanneer je een map wilt gebruiken, je ineens over static vars begint. Je kunt nu toch ook al gewoon bij de variabelen? Waarom zou dat anders worden wanneer je ze in een map zet?
Niet zozeer vanwege het in een map zetten, maar de template afhandeling in een class zetten is waar het static op sloeg. Wanneer je een object per template aanmaakt, zul je je map variabele static moeten maken, anders wordt een aanpassing in de map niet doorgegeven aan de rest van de objecten.
Janoz schreef op donderdag 03 april 2008 @ 14:05:
[...]

Waarom zou die array opslaan minder elegant zijn? Dat begrijp ik niet. Goed, in mijn voorstel heb ik nog geen rekening met lusjes gehouden dus in die implementatie kun je nog geen array toevoegen, maar daarvoor zou je je template-engine uit kunnen breiden. Wat je expliciet niet wil doen is je resultset uit gaan lezen terwijl je je output al aan het genereren bent. Dat maakt de foutafhandeling alleen maar ingewikkelder (of levert erg slordige pagina's op met halverwege foutmeldingen)

Sowieso zou ik in een dergelijk geval eigen domein objecten gebruiken waarin ik een gebruiker opsla, maar dat is weer een heel ander verhaal.
Uiteraard kun je dan voor alle verschillende mogelijke situaties wel je engine uit gaan breiden, maar waar het dan op neerkomt is de cleanup, en niet waar het eigenlijk om draait: een template parsen. Als je weet wat voor values je krijgt, kun je daar efficienter omheen programmeren.
Voutloos schreef op donderdag 03 april 2008 @ 14:06:
[...]
Die admins zijn nog geen programmeurs (cq. hoeven dat op dat moment niet te zijn) dus ze moeten gewoon de mogelijkheid tot het invoeren van generieke PHP code niet hebben.
Punt.
Bedenk eens waarom CMS software bestaat. Waarom zou men een uitgebreid CMS maken als een script met een sql select, insert en update functie erin al alles kan? ;)
Admins die toegang krijgen tot het template gedeelte van de admin panel (en ook een directe SELECT executer), zijn wel degelijk ingelezen in het hoe en wat ;) Anders mogen ze slechts user management doen, bij wijze van spreken.
Voutloos schreef op donderdag 03 april 2008 @ 14:06:
Verder maak je een gevaarlijke aanname door alles dat niet GET, POST of COOKIE is te vertrouwen. Dankzij dergelijke aannames heb je of direct een lek, of een veel groter probleem zodra je ergens een miniem checkje achterwege laat.
Als je je eigen code (op de superglobals na) al niet kunt vertrouwen, dan hebben veel mensen in de IT wereld een groot probleem ;) Wat er niet te vertrouwen is, is door users ingevoerde data in de database. En laat ik die zut nu net een beetje gescheiden houden van wat er zoal door eval() getrokken wordt.

Phenom II X4 945 \\ 8GB DDR3 \\ Crosshair IV Formula \\ R9 290


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Zyppora schreef op donderdag 03 april 2008 @ 13:48:
@.iosyn:
Soms mag de output gewoon rechtstreeks ge-echo-ed worden, soms wil ik die op deze manier gebruiken:

PHP:
1
2
3
4
5
6
7
8
9
<?php

$myRows = "";

while ($data = mysql_fetch_assoc($resultset)) {
  eval('$myRows .= "'.getTemplate('tablerows').'";');
}

eval('echo "'.getTemplate('table').'";');
Waarom wil je dat je code de flow van de output bepaalt dan? Misschien wil de template de data wel helemaal niet formatteren in een table, of juist ondersteboven weergeven. Wat dan?

Ook ontgaat me compleet waarom output buffering smerig is. Of je nou steeds data achter een string plakt of naar een buffer output, het resultaat is hetzelfde.
Voutloos schreef op donderdag 03 april 2008 @ 14:06:
[...]
Die admins zijn nog geen programmeurs (cq. hoeven dat op dat moment niet te zijn) dus ze moeten gewoon de mogelijkheid tot het invoeren van generieke PHP code niet hebben.
Punt.
Ah ja, maar admins, die geen programmeurs waren, mogen wel HTML code met javascript produceren? En als ze dat kunnen (en er dus verantwoordelijk voor zijn), denk je dan ook niet dat ze PHP kunnen (leren) gebruiken?
Bedenk eens waarom CMS software bestaat. Waarom zou men een uitgebreid CMS maken als een script met een sql select, insert en update functie erin al alles kan? ;)
Niet om de reden die jij zojuist genoemd hebt, maar om het toevoegen en aanpassen van content op je site te vergemakkelijken. Of edit jij liever direct jouw website's content in phpmyadmin (je bent immers competent genoeg, dus volgens je eigen redenatie heb jij geen CMS nodig)? Een CMS managed content (hence de naam), geen templates waarin die content getoond wordt. Jan- en alleman kan content toevoegen, daarvoor hoef je geen "ICT'er" te zijn. Maar Jan- en alleman hoeven geen templates te maken, en de persoon die daar wél voor verantwoordelijk is kan ook wel wat PHP'en :).

[ Voor 60% gewijzigd door .oisyn op 03-04-2008 15:03 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
.oisyn schreef op donderdag 03 april 2008 @ 14:51:
Ah ja, maar admins, die geen programmeurs waren, mogen wel HTML code met javascript produceren? En als ze dat kunnen (en er dus verantwoordelijk voor zijn), denk je dan ook niet dat ze PHP kunnen (leren) gebruiken?
Ik denk dat ze de mogelijkheden/rechten niet hoeven te hebben. :)
Niet om de reden die jij zojuist genoemd hebt, maar om het toevoegen en aanpassen van content op je site te vergemakkelijken.
En enkel content (!= alle mogelijke scripts).
Of edit jij liever direct jouw website's content in phpmyadmin (je bent immers competent genoeg, dus volgens je eigen redenatie heb jij geen CMS nodig)?
Dank je. :P En nee, ik heb reeds gezegd dat iemand die kan programmeren niet de rol van programmeur heeft als hij wat content in klopt.
Maar Jan- en alleman hoeven geen templates te maken, en de persoon die daar wél voor verantwoordelijk is kan ook wel wat PHP'en
Of wellicht prima uit de voeten met een geschikt setje bouwstenen. :)

{signature}


Acties:
  • 0 Henk 'm!

  • Zyppora
  • Registratie: December 2005
  • Laatst online: 12-09 10:59

Zyppora

155/50 Warlock

Topicstarter
.oisyn schreef op donderdag 03 april 2008 @ 14:51:
[...]

Waarom wil je dat je code de flow van de output bepaalt dan? Misschien wil de template de data wel helemaal niet formatteren in een table, of juist ondersteboven weergeven. Wat dan?
Dan zal ik inderdaad de PHP code aan moeten passen. Maar zo dynamisch als jij het hier stelt krijg je volgens mij geen enkel templating systeem.
Rekcor schreef op donderdag 03 april 2008 @ 14:39:
Ook ontgaat me compleet waarom output buffering smerig is. Of je nou steeds data achter een string plakt of naar een buffer output, het resultaat is hetzelfde.
Tja, daar heb ik niet echt een antwoord op. Het voelt gewoon aan als een workaround. Ik gebruik het bijvoorbeeld ook niet als ik ergens headers of cookies moet versturen.

Phenom II X4 945 \\ 8GB DDR3 \\ Crosshair IV Formula \\ R9 290


Acties:
  • 0 Henk 'm!

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 16:36
Zyppora schreef op donderdag 03 april 2008 @ 15:33:
Tja, daar heb ik niet echt een antwoord op. Het voelt gewoon aan als een workaround. Ik gebruik het bijvoorbeeld ook niet als ik ergens headers of cookies moet versturen.
Ik gebruik ook geen eval om headers en cookies te sturen...

Wat is hier nou smerig aan?
PHP:
1
2
3
ob_start();
  include 'template.php';
$content = ob_get_clean();

Regeren is vooruitschuiven


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Voutloos schreef op donderdag 03 april 2008 @ 15:17:
[...]
Ik denk dat ze de mogelijkheden/rechten niet hoeven te hebben. :)
[...]
En enkel content (!= alle mogelijke scripts).
Exact. En ook templates != content, dat was een beetje het hele punt waarvan ik nu het idee krijg dat dat niet overkomt :). PHP code in content mag uiteraard niet uitgevoerd worden. Voor PHP code in templates vind ik dat echter wel prima.
Of wellicht prima uit de voeten met een geschikt setje bouwstenen. :)
Uiteraard. Begrijp me niet verkeerd, er is best wat te zeggen voor een sandbox (want dat is waar het uiteindelijk om draait), maar het systeem hoeft voor de mensen die over de templates gaan niet dermate idiot-proof te zijn (uiteraard wél voor de mensen die enkel content editten, maar die mogen dan ook geen templates editten)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Zyppora
  • Registratie: December 2005
  • Laatst online: 12-09 10:59

Zyppora

155/50 Warlock

Topicstarter
T-MOB schreef op donderdag 03 april 2008 @ 15:54:
[...]

Ik gebruik ook geen eval om headers en cookies te sturen...
maar output buffering wel, en veelal 'om die vervelende 'headers already sent' errors weg te krijgen' ;)
T-MOB schreef op donderdag 03 april 2008 @ 15:54:
Wat is hier nou smerig aan?
PHP:
1
2
3
ob_start();
  include 'template.php';
$content = ob_get_clean();
Het is een 'extern' (tussen quotes, aangezien het wel degelijk in de PHP core zit, maar niet in je script) mechanisme dat je aanroept, en wat je iets laat doen waar het naar mijn idee niet voor bedoeld is. Zoals ik al zei: het is niet echt uit te leggen, maar het voelt gewoon als een cheapass workaround aan :)

Phenom II X4 945 \\ 8GB DDR3 \\ Crosshair IV Formula \\ R9 290


Acties:
  • 0 Henk 'm!

  • Brakkie
  • Registratie: Maart 2001
  • Niet online

Brakkie

blaat

PHP is 1 grote aaneenknoping van externe zaken die dingen voor je regelen, of wilde je ook zelf een library gaan bouwen in php die met mysql communiceert. Daar gebruik je toch ook de ingebouwde functies voor, of snap ik je nou verkeerd.

En output buffering is hier zeker wel voor bedoeld, namelijk het opvangen van de output zodat je er daarna zelf nog filtering, caching, enz enz enz op kan toepassen.

[ Voor 26% gewijzigd door Brakkie op 03-04-2008 16:37 ]

Systeem | Strava


Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
Zyppora schreef op donderdag 03 april 2008 @ 16:24:
[...]


maar output buffering wel, en veelal 'om die vervelende 'headers already sent' errors weg te krijgen' ;)


[...]


Het is een 'extern' (tussen quotes, aangezien het wel degelijk in de PHP core zit, maar niet in je script) mechanisme dat je aanroept, en wat je iets laat doen waar het naar mijn idee niet voor bedoeld is. Zoals ik al zei: het is niet echt uit te leggen, maar het voelt gewoon als een cheapass workaround aan :)
Ik denk dat je eerst moet kijken naar de definitie van een template systeem. Het punt is dat jij imho iets anders voor je ziet dan dat wij zien. Ik denk dat je het moet omschrijven als:
Een mechanisme waarmee je de inhoud van het resultaat koppelt aan het uiterlijk van je resultaat
Dit betekent dat je dus content stuurt naar je engine en die bakt er een resultaat van, door er bepaalde code omheen of tussen te plaatsen (die zelf dus het uiterlijk / structuur e.d. bepaalt). Wat dat impliceert is dat je het resultaat terug wil krijgen. Hoe je het terugkrijgt, bepaal je vervolgens zelf. Het hulpmiddel van buffering is dus alleszins geen vies foefje, maar ligt ingebakken in de functieomschrijving.
Doordat jij uiteindelijk wil bepalen hoe je het resultaat verder afhandelt, moet je wel bufferen. En daar is imho niets vies mee en brengt ook geen (veiligheids)risico's met zich mee.

Wat jij bijvoorbeeld met eval() wilde doen, is een uitstekend geval van hoe je juist je content (wat in principe geen php mag zijn) en je template (waar wel language constructs e.d. in kunnen zitten) niet meer kan scheiden. En dan gaat je hele template systeem over de kop ;) Je hebt opzich wel een manier gevonden om dit te minimaliseren, maar de bruikbaarheid, onderhoudbaarheid en veiligheid zijn echt in het geding.

Oftwel: luister naar dit advies en die hier allemaal boven staan: gebruik een buffer en schrap dat eval() uit je plan :)

Acties:
  • 0 Henk 'm!

  • PrisonerOfPain
  • Registratie: Januari 2003
  • Laatst online: 26-05 17:08
T-MOB schreef op donderdag 03 april 2008 @ 10:44:
[...]

Uit een database kun je vrij lastig includen. De enige manier om PHP-code uit een variabele uitgevoerd te krijgen is eval (of iets smerigs met een tijdelijk bestand).
Het is technisch eigenlijk vrij goed te doen om vanuit een database te includen, met stream_wrapper_register() kun je een stream wrapper maken die de databasse raadpleegt in plaats van het bestandssysteem waarna je met require_once gewoon bestanden uit de database kunt includen. Dat je daarmee verder de ogen van iedere weldenkende software ontwikkelaar uitsteekt is een tweede ;)

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Idd :P. Dat is net zoiets als het gedeelte wat je wilt evallen in een bestand zetten en dat includen, want dan hoef je dat vieze eval() niet te gebruiken :+

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

Verwijderd

Zyppora schreef op donderdag 03 april 2008 @ 15:33:
[...]

Dan zal ik inderdaad de PHP code aan moeten passen. Maar zo dynamisch als jij het hier stelt krijg je volgens mij geen enkel templating systeem.
Een template-systeem is imo domweg een systeem wat van input output maakt, en dan wel zo dat de input geen invloed heeft op de output. Dus in het voorbeeld van het omgekeerd afbeelden van een lijst, dan zou je in een goed template-systeem enkel hoeven aangeven dat je de input voor lijst x achterstevoren in moet lezen. En ja, zo dynamisch is het wel degelijk mogelijk in templating systems.
Tja, daar heb ik niet echt een antwoord op. Het voelt gewoon aan als een workaround. Ik gebruik het bijvoorbeeld ook niet als ik ergens headers of cookies moet versturen.
Stelje wilt op php nivo je output niet meer ongecomprimeerd verzenden. Dan is een ob_start("my_gz_function") toch verrekte handig. En dit is nog maar 1 voorbeeld...

Acties:
  • 0 Henk 'm!

  • Zyppora
  • Registratie: December 2005
  • Laatst online: 12-09 10:59

Zyppora

155/50 Warlock

Topicstarter
mithras schreef op donderdag 03 april 2008 @ 16:52:
[...]
Ik denk dat je eerst moet kijken naar de definitie van een template systeem. Het punt is dat jij imho iets anders voor je ziet dan dat wij zien. Ik denk dat je het moet omschrijven als:
De definitie van een template systeem is niet het probleem denk ik, maar jusit de definitie van output buffering. Dat is volgens mij namelijk een opslagbak voor output die al klaar is gestoomd om naar de clientside gestuurd te worden. Vandaar ook de naam 'output buffering'. Vanaf dit buffer gaat data (normaliter) alleen nog maar richting client, en niet meer terug naar het (PHP) script. Da's ook de reden dat ik het terug laten vloeien van data uit de output buffer naar het script 'lelijk' vind. Het voelt aan als het misbruiken van het mechanisme. Zit ik zo verkeerd met hoe ik over output buffering denk?

@PrisonerofPain & .iosyn:
Volgens mij verdienen die suggesties de term 'zo omslachtig mogelijk' ;)

@DarthRaider:
Ja, dat kan wel, maar dan zul je voor alle mogelijke manieren van presentatie afzonderlijke PHP code moeten implementeren. Het ging er juist om dat je presentatie en logica gescheiden van elkaar wilt houden.

Phenom II X4 945 \\ 8GB DDR3 \\ Crosshair IV Formula \\ R9 290


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Zyppora schreef op vrijdag 04 april 2008 @ 10:03:
[...]


De definitie van een template systeem is niet het probleem denk ik, maar jusit de definitie van output buffering. Dat is volgens mij namelijk een opslagbak voor output die al klaar is gestoomd om naar de clientside gestuurd te worden. Vandaar ook de naam 'output buffering'.
Het heet output buffering. Het heet niet output-that's-ready-to-be-sent-to-the-client-buffering. Je template systeem heeft een output. Of ie dat nou als string of naar stdout stuurt, het is en blijft output.

Maar goed, de vraag blijft waarom je de output überhaupt weer wil verwerken. In een degelijk template systeem laat je de template voor de output zorgen en lever je slechts je data aan. De template is dan een algehele pagina die al die data verwerkt.
Ja, dat kan wel, maar dan zul je voor alle mogelijke manieren van presentatie afzonderlijke PHP code moeten implementeren. Het ging er juist om dat je presentatie en logica gescheiden van elkaar wilt houden.
Onzin, je trekt het te ver door. In de presentatie mag best logica zitten. Het is daarentegen wel zo netjes om business logica en presentatie logica te scheiden. Wat jij aan het doen bent is in feite al presentatie-logica, want je legt in je PHP code immers al op hoe de presentatie eruit moet zien (de globale flow dan, niet de letterlijke output).

[ Voor 24% gewijzigd door .oisyn op 04-04-2008 11:32 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Zyppora
  • Registratie: December 2005
  • Laatst online: 12-09 10:59

Zyppora

155/50 Warlock

Topicstarter
.oisyn schreef op vrijdag 04 april 2008 @ 11:28:
[...]

Het heet output buffering. Het heet niet output-that's-ready-to-be-sent-to-the-client-buffering. Je template systeem heeft een output. Of ie dat nou als string of naar stdout stuurt, het is en blijft output.

Maar goed, de vraag blijft waarom je de output überhaupt weer wil verwerken. In een degelijk template systeem laat je de template voor de output zorgen en lever je slechts je data aan. De template is dan een algehele pagina die al die data verwerkt.
Inderdaad (@ tweede alinea): waarom zou je output van data + presentatielayout nog een keer willen verwerken? Da's het hele punt. Het maakt het terug (kunnen) laten vloeien vanuit de output buffer naar het script overbodig m.i. De output buffer is daar niet voor bedoeld.
.oisyn schreef op vrijdag 04 april 2008 @ 11:28:
[...]

Onzin, je trekt het te ver door. In de presentatie mag best logica zitten. Het is daarentegen wel zo netjes om business logica en presentatie logica te scheiden. Wat jij aan het doen bent is in feite al presentatie-logica, want je legt in je PHP code immers al op hoe de presentatie eruit moet zien (de globale flow dan, niet de letterlijke output).
Je bedoelt dat je de manier van querien (want daar wordt de eigenlijke volgorde van repeterende data bepaald) beinvloed moet worden door de template? Ik heb eerder gezegd dat ik het geen goed plan vind om logica in de templates vast te leggen. Het dynamische moet vanuit het script komen, als je dat gaat verweven met de template krijg je een woekering aan logica die niet te overzien is. Daarnaast: hoe bepaal je wat 'business logica' is en wat 'presentatie logica' wanneer je het hebt over een template engine?

Phenom II X4 945 \\ 8GB DDR3 \\ Crosshair IV Formula \\ R9 290


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Zyppora schreef op vrijdag 04 april 2008 @ 11:59:
[...]


Inderdaad (@ tweede alinea): waarom zou je output van data + presentatielayout nog een keer willen verwerken? Da's het hele punt. Het maakt het terug (kunnen) laten vloeien vanuit de output buffer naar het script overbodig m.i. De output buffer is daar niet voor bedoeld.
Nou is het daar wel voor bedoeld, maar ik zet me vraagtekens bij of jij dat wel nodig hebt, want dat is imho niet zo :)
Je bedoelt dat je de manier van querien (want daar wordt de eigenlijke volgorde van repeterende data bepaald) beinvloed moet worden door de template?
Nee. Je hebt data, en je hebt presentatie van de data. Die data kun je presenteren als een enkele tabel. Of als een tabel met bijv. N kolommen. Of in omgekeerde volgorde. Of in een andere sortering. Dit is allemaal onafhankelijk van hoe de data is opgevraagd en database queries hebben er dus ook niets mee van doen. Maar met jouw bedachte systeem is alleen maar de eerste variant mogelijk.

In de meeste gevallen zul je in je template gewoon doen:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<html>
<body>
    ...etc...
<table>
<? foreach($row in $data_rows): ?>
    <tr>
        <td><?=$row["aap"]?></td>
        <td><?=$row["noot"]?></td>
    </tr>
<? endforeach; ?>
</table>
... etc...
</body>
</html>


Hiermee ben je ten eerste veel flexibeler dan voor elk element een template te definieren, dus als je een wat uitgebreidere formatting wil dan gewoon de data sec weergeven dan is die mogelijkheid er. En het is ook een stuk makkelijker te authoren omdat je in 1 bestand een overzicht hebt van hoe je pagina eruit ziet, ipv dat je op allemaal verschillende plekken kleine losse deeltjes moet gaan zitten editten. De "woekering van logica" waar jij het over hebt zie ik hier totaal niet in.
Ik heb eerder gezegd dat ik het geen goed plan vind om logica in de templates vast te leggen. Het dynamische moet vanuit het script komen, als je dat gaat verweven met de template krijg je een woekering aan logica die niet te overzien is. Daarnaast: hoe bepaal je wat 'business logica' is en wat 'presentatie logica' wanneer je het hebt over een template engine?
business logic zit niet in een template engine. Business logic is de laag in je applicatie die alle regels handhaaft. Denk aan het checken en verwerken van input, user rechten management, etc.

[ Voor 18% gewijzigd door .oisyn op 04-04-2008 12:29 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Zyppora
  • Registratie: December 2005
  • Laatst online: 12-09 10:59

Zyppora

155/50 Warlock

Topicstarter
.oisyn schreef op vrijdag 04 april 2008 @ 12:08:
[...]

Nou is het daar wel voor bedoeld, maar ik zet me vraagtekens bij of jij dat wel nodig hebt, want dat is imho niet zo :)
Nee, ik was inderdaad niet van plan om daadwerkelijke PHP code te parsen vanuit een template, dat gaat mij eigenlijk te ver. Het gaat puur om variabelen die gerenderd moeten worden.
.oisyn schreef op vrijdag 04 april 2008 @ 12:08:
[...]
[...]

Nee. Je hebt data, en je hebt presentatie van de data. Die data kun je presenteren als een enkele tabel. Of als een tabel met bijv. N kolommen. Of in omgekeerde volgorde. Of in een andere sortering. Dit is allemaal onafhankelijk van hoe de data is opgevraagd en database queries hebben er dus ook niets mee van doen. Maar met jouw bedachte systeem is alleen maar de eerste variant mogelijk.

In de meeste gevallen zul je in je template gewoon doen:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<html>
<body>
    ...etc...
<table>
<? foreach($row in $data_rows): ?>
    <tr>
        <td><?=$row["aap"]?></td>
        <td><?=$row["noot"]?></td>
    </tr>
<? endforeach; ?>
</table>
... etc...
</body>
</html>


Hiermee ben je ten eerste veel flexibeler dan voor elk element een template te definieren, dus als je een wat uitgebreidere formatting wil dan gewoon de data sec weergeven dan is die mogelijkheid er. En het is ook een stuk makkelijker te authoren omdat je in 1 bestand een overzicht hebt van hoe je pagina eruit ziet, ipv dat je op allemaal verschillende plekken kleine losse deeltjes moet gaan zitten editten. De "woekering van logica" waar jij het over hebt zie ik hier totaal niet in.
Ik snap wat je bedoelt, en hoe je 'in 1 bestand een overzicht hebt', maar het riskante dat ik hieraan zie is dat je PHP code op twee verschillende plaatsen gaat zetten, zowel in de template als in het script. Kan niet goed zijn voor de onderhoudbaarheid. Misschien dat ik een storm in een glas water zie hoor, maar zo kijk ik er tegenaan.
.oisyn schreef op vrijdag 04 april 2008 @ 12:08:
[...]

business logic zit niet in een template engine. Business logic is de laag in je applicatie die alle regels handhaaft. Denk aan het checken en verwerken van input, user rechten management, etc.
Het lijkt me niet dat code die bijv. de template parst of ophaalt uit de remote location onder presentation logic valt. Een template engine is in die zin ook business logic.

Ik denk dat ik het beste aan de slag kan gaan met een template engine (OOP) zoals in het alternatief dat ik gaf. Het output buffering verhaal staat me nog steeds tegen (nog afgezien van het feit dat ik geen remote files gebruik), zal wel gevoelsmatig zijn, maar ik begrijp dat ook in dit geval het gebruik van eval() zeer ongewenst en onveilig is. Bedankt! :)

Phenom II X4 945 \\ 8GB DDR3 \\ Crosshair IV Formula \\ R9 290


Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
Zyppora schreef op vrijdag 04 april 2008 @ 14:06:
[...]
Ik snap wat je bedoelt, en hoe je 'in 1 bestand een overzicht hebt', maar het riskante dat ik hieraan zie is dat je PHP code op twee verschillende plaatsen gaat zetten, zowel in de template als in het script. Kan niet goed zijn voor de onderhoudbaarheid. Misschien dat ik een storm in een glas water zie hoor, maar zo kijk ik er tegenaan.
Idealiter heb je zelfs op drie plaatsen je php code zitten! Ooit gehoord van MVC? Zo niet: Wikipedia: Model-View-Controller-model.

Je beschrijft dan in php een model. Vervolgens maak je een controller die dat model kan aansturen, en alle informatie uit dat model kan doorpompen naar je view. Voor dat laatste kan je templates gebruiken. Dus heb je eigenlijk 3x php :)
Het lijkt me niet dat code die bijv. de template parst of ophaalt uit de remote location onder presentation logic valt. Een template engine is in die zin ook business logic.
Dat klopt, maar je kan php ook inzetten als template taal ;) Weer een vergelijking met Smarty: die heeft zelf bepaalde constructs gedefinieerd. Makkelijker is om daarvoor gewoon php te gebruiken, want dan heb je die overhead gewoon niet :)
Ik denk dat ik het beste aan de slag kan gaan met een template engine (OOP) zoals in het alternatief dat ik gaf. Het output buffering verhaal staat me nog steeds tegen (nog afgezien van het feit dat ik geen remote files gebruik), zal wel gevoelsmatig zijn, maar ik begrijp dat ook in dit geval het gebruik van eval() zeer ongewenst en onveilig is. Bedankt! :)
Je maakt nu een beetje halve oplossing voor je template engine. Kijk naar Smarty of bijvoorbeeld mijn geval. Daarmee vergroot je de bruikbaarheid en onderhoudbaarheid aanzienlijk, ten opzichte van jouw voorstel.

Acties:
  • 0 Henk 'm!

  • Brakkie
  • Registratie: Maart 2001
  • Niet online

Brakkie

blaat

Zyppora schreef op vrijdag 04 april 2008 @ 14:06:Ik snap wat je bedoelt, en hoe je 'in 1 bestand een overzicht hebt', maar het riskante dat ik hieraan zie is dat je PHP code op twee verschillende plaatsen gaat zetten, zowel in de template als in het script. Kan niet goed zijn voor de onderhoudbaarheid. Misschien dat ik een storm in een glas water zie hoor, maar zo kijk ik er tegenaan.
Wanneer je je template include in een method van een klasse of een functie heb je een aparte scope voor je template en is dat probleem van php code op 2 plaatsen geen probleem meer lijkt me. Voor de rest is het een kwestie van zelf kritisch zijn en er voor zorgen dat je niet allerlei niet-layout gerelateerde logica gaat programmeren in de template.

Systeem | Strava


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Zyppora schreef op vrijdag 04 april 2008 @ 14:06:
Ik snap wat je bedoelt, en hoe je 'in 1 bestand een overzicht hebt', maar het riskante dat ik hieraan zie is dat je PHP code op twee verschillende plaatsen gaat zetten, zowel in de template als in het script. Kan niet goed zijn voor de onderhoudbaarheid. Misschien dat ik een storm in een glas water zie hoor, maar zo kijk ik er tegenaan.
Je ziet het verkeerd. De template is in feite geen onderdeel van je systeem, en wordt dus ook door andere rollen onderhouden (de webdeveloper, ipv de systeemdeveloper). Daarnaast heb je exact hetzelfde probleem met het systeem dat jij voorstelt. Want als iets dermate verandert dat de template ook gewijzigd moet worden, dan moet in het systeem zoals jij het wilt opzetten óók wijzigingen worden aangebracht. Moot point dus.
Het lijkt me niet dat code die bijv. de template parst of ophaalt uit de remote location onder presentation logic valt.
Het is toch echt zo. Het zojuist aangehaalde MVC pattern is hier een goed voorbeeld van.

[ Voor 5% gewijzigd door .oisyn op 04-04-2008 14:22 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.

Pagina: 1