[PHP] code uit een string halen en uitvoeren

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • plakbandrol
  • Registratie: Juni 2002
  • Laatst online: 16-09 09:35
Ik ben bezig met een soort template engine, en nou wil ik de gebruiker de mogelijkheid geven eenvoudige stukjes php code in de template te stoppen, deze moet dan worden uitgevoerd bij het uitlezen

voor het invoegen van php code moeten de tags [php.] en [./php] worden gebruikt (maar dan zonder punten) zodat de code makkelijk uit de string kan worden gefilterd

het probleem is dat ik geen goede methode kan vinden om dit aan te pakken, mijn idee was om door middel van explode() eerst de stukken php en de rest te scheiden, de aangemaakte array kan dan in een loopje worden uitgelezen waarbij php delen mbv eval() worden uitgevoerd, hiervoor had ik dit bedacht:

$string = explode("/\\[php\](.*?)\\[\/php\]/is",$string);

maar explode ondersteunt geen regexp, via preg_split werkt het ook niet, dan wordt de code tussen [.php] en [./php] gewoon weggelaten uit het resultaat.

Op welke manier kan ik dit het beste aanpakken?

[ Voor 13% gewijzigd door plakbandrol op 03-04-2006 21:19 ]


Acties:
  • 0 Henk 'm!

  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

Je split nu met preg_split juist op je delimiter, en in dit geval split je dus op
code:
1
[php](*?)[/php]
, ofwel stel je zou dit hebben:
code:
1
Blablabla[php]<?="hoi"?>[/php]blabla.

Als je nu hier gaat splitten op je pattern, dan wordt er dus gesplit op
code:
1
[php]<?="hoi"?>[/php]

, ofwel op de delimiter, i.e. de delimiter wordt dan niet meegenomen in de matches; je splitst er alleen op. Je zult een preg_match moeten doen. Ah, mea culpa, what NME said, preg_match_all ;)

[ Voor 33% gewijzigd door prototype op 03-04-2006 21:39 ]


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

preg_match_all zelfs. :)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • plakbandrol
  • Registratie: Juni 2002
  • Laatst online: 16-09 09:35
Ik denk dat ik hem heb..

$string = preg_split("/\\[php\](.*?)\\[\/php\]/is",$string,-1,PREG_SPLIT_DELIM_CAPTURE);

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Waarom gebruik je nu toch preg_split? Het kàn wel, maar is er niet voor bedoeld. :)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • plakbandrol
  • Registratie: Juni 2002
  • Laatst online: 16-09 09:35
-NMe- schreef op maandag 03 april 2006 @ 21:54:
Waarom gebruik je nu toch preg_split? Het kàn wel, maar is er niet voor bedoeld. :)
met preg_match kreeg ik hem niet draaiend, met deze wel :+


mijn code tot nu toe (even er een functie van gemaakt)


[code=php]function php_tags_parser($string)
{
$string = preg_split("/\\[php\](.*?)\\[\/php\]/is",$string,-1,PREG_SPLIT_DELIM_CAPTURE);

if (substr(strtolower($string),0,5)=='
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
') 
    {
        $a = 0; 
    } 
    else 
    { 
        $a = 1; 
    }
    
    for($i=0;$i<count($string);$i++)
    {
        if ($i%2==$a)
        { 
            eval($string[$i]);
        }
        else
        {
            echo $string[$i];
        }
    }
}

edit:
Ik heb even code-tags toegevoegd. Wil je dat de volgende keer zelf doen? :)

[ Voor 97% gewijzigd door NMe op 04-04-2006 01:21 ]


Acties:
  • 0 Henk 'm!

  • orf
  • Registratie: Augustus 2005
  • Nu online

orf

Is een preg_replace_callback juist niet de mooiste methode?
http://nl2.php.net/manual...preg-replace-callback.php

Acties:
  • 0 Henk 'm!

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 16:36
Dit probleem oplossen met een regex is vragen om problemen... In "een stukje php" kun je namelijk van alles typen waardoor de hele boel in het honderd loopt.
code:
1
2
<p>[_php]if ($condition) 
echo '[_/php] is de sluittag in onze template parser!!11';[_/php]

Als je het goed wil doen zul je dus de context van elke "sluittag" in acht moeten nemen. Staat deze binnen een php string of comment dan zul je hem moeten negeren. En dat is onmogelijk met een regex.

Een nette implementatie van wat je wil bereiken doet ongeveer het volgende:
  • Met behulp van strpos zoek je naar openingstags
  • Vanaf je openingstag itereer je door je tekens tot je of een string of een commentaar tegenkomt.
  • Kom je een quote of dubbelquote tegen dan ga je over in "string modus"
    • [b]string modus[/b]
    • Negeer alle tekens behalve het teken waarmee de string gestart is
    • Negeer ueberhaupt elk teken als het direct volgt op een backslash (==escape char)
  • Kom je een comment tegen dan negeer je alles tot het einde van het commentaar. Start het comment met # of // dan kun je strpos-en naar een line-break. Begint het comment met /* dan kun je strpos-en op */
En dan kent PHP nog heredoc syntax, de backtick operator om een syteemcommando door te geven en niet te vergeten is er de mogelijkheid om "uit php" te stappen:
code:
1
2
[_php]if ($condition)?>
  [_/php] is de sluittag in <?=$userName?>'s template parser!!11[_/php]

Regeren is vooruitschuiven

Pagina: 1