[PHP] templateParser conditionals van binnen naar buiten

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • GandalfTheGrey
  • Registratie: Juli 2001
  • Laatst online: 01-12-2024

GandalfTheGrey

Remember, Remember..

Topicstarter
Ik heb momenteel een probleem met mijn php templateParser. Ik denk dat ik weet wat het probleem is, maar ik weet niet hoe ik het moet oplossen. Nu weet ik dat er mensen zijn die zeggen over conditionals en loops in je templates: dat moet je in de code oplossen => je view moet geen conditionals kennen. Deze discussie wil ik laten voor wat het is. Graag wil ik kijken hoe mijn probleem opgelost kan worden. Dus van binnen naar buiten mijn conditionals uitlezen.

Huidige situatie
Ik heb voor mijn templateParser een bestaand conditionals script (CodeIgniter voor PHP) omgebouwd.

Mijn templateParser herkent nu dit soort statements:
code:
1
2
3
4
5
6
{if {var1} == {var2}}
blablalbalblabla 
{/if} of 
{if {var2}!=""}
badfaasd
{/if}.


Het probleem is wanneer ik het volgende doe:

{if {var1} == {var2}}
asdasdsad
{if {a}=={b}}
asdasd
{/if}
asdddddddddd
{/if}
in dit geval wordt de EERSTE stopif {/if} gematched aan mijn eerste if expressie (De dikgedrukte worden gematched), terwijl hij van binnen naar buiten zou moeten lezen...

Wie weet hoe ik de reguliere expressies zo aanpas dat ik van binnen naar buiten mijn conditionals kan uitlezen?

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
 /**
     *  Parse conditional statments
     * Note: This function will ignore no matched or conditional statments with errors
     *
     * @access    public
     * @param    string
     * @param    bool
     * @return    string
     */
    function conditionals($template, $show_errors)
    {
        if (preg_match_all('#'.$this->l_delim.'if (.+)'.$this->r_delim.'(.+)'.$this->l_delim.'/if'.$this->r_delim.'#sU', $template, $conditionals, PREG_SET_ORDER))
        {            
            if(count($conditionals) > 0)
            {
                foreach($conditionals AS $condition)
                {
                    $raw_code = (isset($condition[0])) ? $condition[0] : FALSE;
                    $cond_str = (isset($condition[1])) ? $condition[1] : FALSE;
                    $insert = (isset($condition[2])) ? $condition[2] : '';
                    
                    if(!preg_match('/('.$this->l_delim.'|'.$this->r_delim.')/', $cond_str, $problem_cond))
                    {
                        // If the the conditional statment is formated right, lets procoess it!
                        if(!empty($raw_code) OR $cond_str != FALSE OR !empty($insert))
                        {
                            // Get the two values
                            $cond = preg_split("/(\!=|==|<=|>=|<>|<|>|AND|XOR|OR|&&)/", $cond_str);
                            // Do we have a valid if statment?
                            if(count($cond) == 2)
                            {
                                // Get condition
                                preg_match("/(\!=|==|<=|>=|<>|<|>|AND|XOR|OR|&&)/", $cond_str, $cond_m);
                                array_push($cond, $cond_m[0]);
                                
                                // Remove quotes - they cause to many problems!                            
                                $cond[0] = preg_replace("/[^a-zA-Z0-9s]/", "", $cond[0]);    
                                $cond[1] = preg_replace("/[^a-zA-Z0-9s]/", "", $cond[1]);    
                                
                                // Test condition                            
                                eval("\$result = (\"".$cond[0]."\" ".$cond[2]." \"".$cond[1]."\") ? TRUE : FALSE;");
                            }
                            else
                            {
                                $result = (isset($data[$cond_str])) ? TRUE : FALSE;
                            }
                        }
                        
                        // If the condition is TRUE then show the text block
                        $insert = preg_split('#'.$this->l_delim.'else'.$this->r_delim.'#sU', $insert);
                        if($result == TRUE)
                        {
                            $template = str_replace($raw_code, $insert[0], $template);    
                        }
                        else
                        {
                            // Do we have an else statment?
                            if(is_array($insert))
                            {
                                $insert = (isset($insert[1])) ? $insert[1] : '';
                                $template = str_replace($raw_code, $insert, $template);    
                            }
                            else
                            {
                                $template = str_replace($raw_code, '', $template);        
                            }
                        }
                    }
                    elseif(!$show_errors)
                    {
                        // Remove any if statments we can't process
                        $template = str_replace($raw_code, '', $template);            
                    }
                }    
            }
        }
        return $template;    
    }

Computer Specs


Acties:
  • 0 Henk 'm!

  • MueR
  • Registratie: Januari 2004
  • Laatst online: 20:57

MueR

Admin Tweakers Discord

is niet lief

Je zoekt naar stack-based parsing.

Anyone who gets in between me and my morning coffee should be insecure.


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Idd, ik heb niet je hele code doorgelezen, maar het viel me meteen op dat je reguliere expresies gebruikt. Voor dit soort nesting problemen wil je inderdaad een stack-based parser gaan gebruiken, en geen regexes.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • TeeDee
  • Registratie: Februari 2001
  • Laatst online: 20:25

TeeDee

CQB 241

Even naast de reacties van mijn 2 voorgangers maar waarom zou je voor
code:
1
2
3
4
5
6
{if {var1} == {var2}}
blablalbalblabla 
{/if} of 
{if {var2}!=""}
badfaasd
{/if}.
überhaupt een templateparser gebruiken. Is gewoon plain/simple PHP geen betere en overzichtelijker oplossing?

Heart..pumps blood.Has nothing to do with emotion! Bored


Acties:
  • 0 Henk 'm!

  • GandalfTheGrey
  • Registratie: Juli 2001
  • Laatst online: 01-12-2024

GandalfTheGrey

Remember, Remember..

Topicstarter
TeeDee schreef op dinsdag 25 augustus 2009 @ 15:25:
Even naast de reacties van mijn 2 voorgangers maar waarom zou je voor
code:
1
2
3
4
5
6
{if {var1} == {var2}}
blablalbalblabla 
{/if} of 
{if {var2}!=""}
badfaasd
{/if}.
überhaupt een templateparser gebruiken. Is gewoon plain/simple PHP geen betere en overzichtelijker oplossing?
Nee, want ik werk met mensen die alleen HTML kunnen (en dit pseudo code taaltje).

Computer Specs


Acties:
  • 0 Henk 'm!

  • MueR
  • Registratie: Januari 2004
  • Laatst online: 20:57

MueR

Admin Tweakers Discord

is niet lief

Misschien een heel domme vraag, maar waarom download je dan niet gewoon een kant en klare engine die dit doet? Smarty bijvoorbeeld?

Anyone who gets in between me and my morning coffee should be insecure.


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
MueR schreef op dinsdag 25 augustus 2009 @ 15:53:
Misschien een heel domme vraag, maar waarom download je dan niet gewoon een kant en klare engine die dit doet? Smarty bijvoorbeeld?
Wikipedia: Not Invented Here >:)

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • GandalfTheGrey
  • Registratie: Juli 2001
  • Laatst online: 01-12-2024

GandalfTheGrey

Remember, Remember..

Topicstarter
Hahahaha sterk :D NIH-syndroom is cool :p


Kijk.. het is begonnen als een simpele parser (< 100 lines). Maar naar verloop van tijd moet je je in zoveel hoeken en bochten gaan wringen dat het vervelend wordt en je gaat uitbreiden :) Bij SMARTY en veel andere pakketten zit er zoveel zooi (compiling, caching bij) die je eigenlijk niet nodig hebt (Daar issie NIH-syndroom ;)). Maar op dit moment is het een terechte vraag inderdaad. Ik kijk even hoe makkelijk ik dit omschrijf :) (tips zijn welkom!)

[ Voor 5% gewijzigd door GandalfTheGrey op 25-08-2009 16:12 ]

Computer Specs


Acties:
  • 0 Henk 'm!

  • MueR
  • Registratie: Januari 2004
  • Laatst online: 20:57

MueR

Admin Tweakers Discord

is niet lief

Niet om je af te zeiken (echt niet!), maar dit soort verhalen zie ik vaak op TheDailyWTF. Begonnen met een simpele applicatie, vervolgens uitgebreid en uitgebreid en uitgebreid naar een enorme logge kolos die niet te onderhouden is. En toch blijven proberen. Af en toe is het echt beter om de boel er uit te gooien en opnieuw te beginnen.

Caching is in Smarty gewoon uit te schakelen, maar of je dat wil is maar de vraag. Als je niet cached, moet er elke keer een parser overheen om je logica te parsen. Dat is per saldo minder efficient. Die parser doet feitelijk niks anders dan je template compilen.

Probeer het gewoon eens.

Anyone who gets in between me and my morning coffee should be insecure.

Pagina: 1