[PHP] Vervangen van tekst door waarde van variabel

Pagina: 1
Acties:
  • 471 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Hallo schoonheden,


Ik ben bezig een systeem aan het maken waarbij de PHP code gescheiden wordt van de HTML / client side code. De opmaak zelf staat dus zegmaar in een template bestand. Je hebt dus straks twee bestanden voor één pagina. Bijv: "/php/pagina.php" en "/templates/pagina.html". Eerst wordt de code uit "/php/pagina.php" en daarna wordt "/templates/pagina.html" geladen en moeten de juiste variabelen hierin komen.

Om een waarde van een variabel van PHP weer te geven in het HTML template bestand heb ik het volgende bedacht:

In het template bestand ("/templates/pagina.html") staat bijv. %NaamVanString%. Dat moet vervangen worden met de PHP variabel $NaamVanString.

Om alle matches uit het template bestand te vinden gebruik ik de volgende code. Alles wat tussen % en % staat wordt dus in principe gezien als een variabel. Of deze twee tekens echt verstandig zijn moet nog blijken, maar dat is later altijd makkelijk aan het passen.

code:
1
2
3
4
5
6
<?php
   
   // $pageContent bevat de inhoud van het template bestand ("/templates/pagina.html"), alle matches komen als een array terecht in $matches
   preg_match_all('/%[a-zA-Z](.*)%/', $pageContent, $matches);
   
?>


Deze code werkt goed en geeft alle matches uit het template bestand weer. Voorbeeld van output:

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

// Output van: print_r($matches[0]);
Array
(
    [0] => %bosbessentaart%
    [1] => %paardVanSinterklaas%
    [2] => %NaamVanString%
)

?>


Nu moet %bosbessentaart% dus vervangen worden met de waarde van de PHP variabel $bosbessentaart, %paardVanSinterklaas% moet vervangen worden met de waarde van de PHP variabel $paardVanSinterklaas, en %NaamVanString% moet vervangen worden met de variabel $NaamVanString. Zeg maar.

Maar nu is mijn vraag hoe ik dit het makkelijkste kan doen. Misschien is het zelfs nog makkelijker om de PHP function preg_replace() te gebruiken ipv eerst preg_match_all te gebruiken en daarna de boel te gaan vervangen.

Ik kom er echter niet helemaal uit. Als iemand mij hier een beetje mee kan helpen en mijn hoofd weer in de goede richting te zetten dan zou dat geweldig zijn. :)

Alvast bedankt.

Acties:
  • 0 Henk 'm!

Verwijderd

Wat is er mis met str_replace?

Die slikt nog array's ook, ben je helemaal gelijk klaar.

Als ik het goed begrijp wil je opzoeken in de template welke vars hierin zitten en deze dan gaan vervangen. Dat is een beetje omgekeerde logica, je kunt gemakkelijker alleen de vars vervangen die je ook daadwerkelijk hebt toegewezen aan de template.

Dus $templateObjectInstance->voegVarretjeToe("%foo%", "BAR!");

Dan een simpele str_replace en je bent klaar.

[ Voor 67% gewijzigd door Verwijderd op 01-09-2007 15:33 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Daarin heb je helemaal gelijk. Maar het is de bedoeling dat ik straks meerdere template bestanden heb en van te voren niet weet welke variabelen daarin staan. Daarom wil ik ze ook eerst opzoeken.

Als ik het van te voren wist (wat nu nog wel zo is, maar met het oog de nabije toekomst) dan was str_replace() veel makkelijker, en sneller, geweest.

En nu kan ik ze eerst wel gaan toevoegen aan een lijst (via je voegVarretjeToe voorbeeld), dat is ook wel een oplossing. Maar het moet toch mooier kunnen (in mijn ogen)?

Acties:
  • 0 Henk 'm!

Verwijderd

Wat heeft het voor nut te weten welke variabelen er in de template staan als je toch ergens in je script een waarde moet toekennen?

Stel ik weet dat %foobar% is opgenomen in de template, maar jouw script heeft nergens $foobar een waarde toegekend, wat heb ik er dan nog aan te weten dat er %foobar% staat?

Sterker nog, het is beter %foobar% dan gewoon helemaal niet te verwerken aangezien $foobar misschien wel eens van buitenaf geset kan zijn met alle gevolgen van dien.

Daarom is het handig om je script gewoon de waardes door te laten geven aan de template engine op het moment dat ie ze heeft. Dit kun je met 1 functieaanroep per variabele doen, maar je kunt natuurlijk ook gelijk een hele array naar je template engine gooien.

Acties:
  • 0 Henk 'm!

  • mjax
  • Registratie: September 2000
  • Laatst online: 20:52
Is een simple regex replace niet voldoende? Uit het hoofd en niet gecontroleerd:
code:
1
$content = preg_replace('/%(.*?)%/e', '$\\1', $content);

Acties:
  • 0 Henk 'm!

Verwijderd

mjax schreef op zaterdag 01 september 2007 @ 15:44:
Is een simple regex replace niet voldoende? Uit het hoofd en niet gecontroleerd:
code:
1
$content = preg_replace('/%(.*?)%/e', '$\\1', $content);
Daarmee vervang je '%foobar%' door '$foobar', maar '%foobar%' moet vervangen worden door $foobar, dus de waarde van de variabele foobar.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Verwijderd schreef op zaterdag 01 september 2007 @ 15:41:
Wat heeft het voor nut te weten welke variabelen er in de template staan als je toch ergens in je script een waarde moet toekennen?

Stel ik weet dat %foobar% is opgenomen in de template, maar jouw script heeft nergens $foobar een waarde toegekend, wat heb ik er dan nog aan te weten dat er %foobar% staat?

Sterker nog, het is beter %foobar% dan gewoon helemaal niet te verwerken aangezien $foobar misschien wel eens van buitenaf geset kan zijn met alle gevolgen van dien.

Daarom is het handig om je script gewoon de waardes door te laten geven aan de template engine op het moment dat ie ze heeft. Dit kun je met 1 functieaanroep per variabele doen, maar je kunt natuurlijk ook gelijk een hele array naar je template engine gooien.
Die methode is stukken veiliger als wat ik wil doen en zal ik misschien later zeker ook gaan gebruiken. Op dit moment is echter alles in mijn beheer en weet ik wat ik doe, dus zolang ik mijn hoofd erbij hou vindt ik het veilig genoeg.

Acties:
  • 0 Henk 'm!

  • Icey
  • Registratie: November 2001
  • Laatst online: 17-09 16:46
Even een copy-past uit iets wat ik toevallig toch voor mij neus had;

PHP:
1
2
3
4
$before  = array('%timer%','%number%');
$after   = array($timer,$number);
   
echo '<p>'.str_replace($before,$after, $_LANG['general']['footer']).'</p>';


Ben je er dan niet? Gewoon 2 array's maken met een 'before' en 'after' en vervangen die handel.

Acties:
  • 0 Henk 'm!

Verwijderd

Icey schreef op zaterdag 01 september 2007 @ 16:06:
Even een copy-past uit iets wat ik toevallig toch voor mij neus had;

PHP:
1
2
3
4
$before  = array('%timer%','%number%');
$after   = array($timer,$number);
   
echo '<p>'.str_replace($before,$after, $_LANG['general']['footer']).'</p>';


Ben je er dan niet? Gewoon 2 array's maken met een 'before' en 'after' en vervangen die handel.
Jup, dat is ook wat ik zei. Maar hij wil dus opzoeken in de template wat er in $before moet komen, probleem is dan alleen dat je moeilijk je $after array in elkaar kunt zetten (je weet immers niet wat erin moet).

Op zich kun je wel $after vullen met behulp van $before, maar waarom zou je dat willen? Het geeft brakke code die nog eens potentieel beveiliginglekken heeft ook.

Acties:
  • 0 Henk 'm!

  • GlowMouse
  • Registratie: November 2002
  • Niet online
Als je in de templates geen beperkingen hebt op de variabelen die je kunt gebruiken, waarom zou je dan met %var% werken en niet met <?=$var?> ? Aan het eind van pagina.php include je pagina.html en je hebt er geen omkijken meer naar.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
(Snipet van mjax):
code:
1
$content = preg_replace('/%(.*?)%/e', '$\\1', $content);


Werkt goed, het doet zijn werk (bedankt). Maar als het ongecontroleerd gebruikt wordt kan het gevaarlijk zijn. Wat in mijn geval niet zo is, dus mijn probleem is in principe opgelost. Bedankt!

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
GlowMouse schreef op zaterdag 01 september 2007 @ 16:09:
Als je in de templates geen beperkingen hebt op de variabelen die je kunt gebruiken, waarom zou je dan met %var% werken en niet met <?=$var?> ? Aan het eind van pagina.php include je pagina.html en je hebt er geen omkijken meer naar.
Ik wil dat de template bestanden absoluut geen PHP code bevatten. Ook niet het simpel echo en van een variabel.

Acties:
  • 0 Henk 'm!

  • Icey
  • Registratie: November 2001
  • Laatst online: 17-09 16:46
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
//Even vanuit gaande dat $strings een lijst van die %blabla% dingen zijn die je uit de template gehaald hebt.
$before  = array();
$after = array();

foreach($strings as $string)
{
 //Kijken of er een variabele is met die stringnaam
 if(isset($$string) && !empty($$string))
 {
  array_push($before,$string);
  array_push($after,$$string);
 }
}


Het kan zijn dat ik nu talen door elkaar ga halen, maar ik geloof dat je met 2 dollartekens zulke dingen kunt maken. Ik geef echter totaal geen garantie hiervoor, bovenstaande is een idee wat door mijn hoofd spookte :+.

Acties:
  • 0 Henk 'm!

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

Niemand_Anders

Dat was ik niet..

Niet echt een antwoord op je vraag, maar waarom maak je niet gebruik van een kant- en klaar template zoals smarty of xtemplates? Dergelijke systemen zijn simpel in gebruik en kennen al een heleboel mogelijken zoals het doorlopen van arrays of een database resultaat. Sommige kennen zelfs skins (volledig andere opbouw van html code, niet beperkt dus tot css).

De grote vraag is heb je tijd genoeg om je bestaande systeem te voltooien of zou je die tijd beter kunnen besteden aan de functionaliteit van de website zelf?

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


Acties:
  • 0 Henk 'm!

Verwijderd

Verwijderd schreef op zaterdag 01 september 2007 @ 16:11:
(Snipet van mjax):
code:
1
$content = preg_replace('/%(.*?)%/e', '$\\1', $content);


Werkt goed, het doet zijn werk (bedankt). Maar als het ongecontroleerd gebruikt wordt kan het gevaarlijk zijn. Wat in mijn geval niet zo is, dus mijn probleem is in principe opgelost. Bedankt!
Inderdaad, de e modifier, was ik niet mee bekend eigenlijk, is een PHP eigen iets:

e (PREG_REPLACE_EVAL)
If this modifier is set, preg_replace() does normal substitution of backreferences in the replacement string, evaluates it as PHP code, and uses the result for replacing the search string. Single quotes, double quotes, backslashes and NULL chars will be escaped by backslashes in substituted backreferences.

Only preg_replace() uses this modifier; it is ignored by other PCRE functions.

Note: This modifier was not available in PHP 3.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Niemand_Anders schreef op zaterdag 01 september 2007 @ 16:19:
Niet echt een antwoord op je vraag, maar waarom maak je niet gebruik van een kant- en klaar template zoals smarty of xtemplates? Dergelijke systemen zijn simpel in gebruik en kennen al een heleboel mogelijken zoals het doorlopen van arrays of een database resultaat. Sommige kennen zelfs skins (volledig andere opbouw van html code, niet beperkt dus tot css).

De grote vraag is heb je tijd genoeg om je bestaande systeem te voltooien of zou je die tijd beter kunnen besteden aan de functionaliteit van de website zelf?
Goeie vraag. Opzich heb ik tijd genoeg om het systeem te voltooien. Het is gewoon mijn eigen script voor mijn eigen website en ik ben niet afhankelijk van deadlines of kosten. Ik wil het zelf doen omdat ik ervan wil leren. En natuurlijk had ik een bestaande template engine kunnen pakken, maar gek genoeg wil ik nu het wiel opnieuw uitvinden en er ervaring van opdoen.
Pagina: 1