Hey,
K'heb net een template engine geschreven, zoals velen hier, op dit moment is hij zo goed als volledig operationeel, dat is het probleem dan ook niet.
Wanneer ik de tree opbouw die bestaat uit een type en de waarde van de child doet hij hier vrij lang over. Ik maak me nu nog niet meteen zorgen aangezien hij ontwikkeld is voor PHP5 en mogelijk daardoor nog niet zo heel geoptimaliseerd is op sommige punten.
1) De inhoud van een file word aan de functie toTree() gegeven die char per char de tekst afloopt tot hij een START_TOKEN vind dat niet geescaped is. Anders begint hij een nieuwe tag, vind hij een END_TOKEN dan gaat hij controleren wat er in de vorige tag zat.
Code:
2) voor elke END_TOKEN zal hij checken wat er in die tag zat en of hij daar nog iets mee moet aanvangen. Dit gebeurt door erg simpele en voor de hand liggende functie's.
Code:
Is dit een redelijke aanpak?
zoja, wat zou er nog sterk geoptimaliseerd kunnen worden, aangezien hij over het samenstellen van de tree ong 80% van de hele parsetijd mee bezig is.
zoniet, zijn hier "standaard" oplossingen/constructie's voor, of (electronische)lectuur hierrond?
Aangezien dit nogal aso grote lappen code zijn en die er misschien snel afgeschopt zullen worden door een modje is hier een link naar de 2 fragmenten.
K'heb net een template engine geschreven, zoals velen hier, op dit moment is hij zo goed als volledig operationeel, dat is het probleem dan ook niet.
Wanneer ik de tree opbouw die bestaat uit een type en de waarde van de child doet hij hier vrij lang over. Ik maak me nu nog niet meteen zorgen aangezien hij ontwikkeld is voor PHP5 en mogelijk daardoor nog niet zo heel geoptimaliseerd is op sommige punten.
1) De inhoud van een file word aan de functie toTree() gegeven die char per char de tekst afloopt tot hij een START_TOKEN vind dat niet geescaped is. Anders begint hij een nieuwe tag, vind hij een END_TOKEN dan gaat hij controleren wat er in de vorige tag zat.
Code:
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
| private function toTree($templateContent){ $pointer = 0; $openTagCount = 0; $tmpstring = ''; $contentLenght = strlen($templateContent); while ($pointer < $contentLenght) { if ($templateContent[$pointer] == START_TOKEN && ((isset($templateContent[$pointer - 1]) && $templateContent[$pointer - 1] != ESCAPE_CHAR) || $pointer == 0)){ // new tag starts if (trim($tmpstring) != ""){ $tag[TAG_TYPE] = T_TEXT; $tag[TAG_VALUE] = $tmpstring; array_push($this->tplTree, $tag); } $tmpstring = ''; $openTagCount++; } else if ($openTagCount > 0 && $templateContent[$pointer] == END_TOKEN && ((isset($templateContent[$pointer - 1]) && $templateContent[$pointer - 1] != ESCAPE_CHAR) || $pointer == 0)){ // current tag ends $tag = $this->determineTagType($tmpstring, $pointer); if ($tag[TAG_TYPE] != T_DISPOSABLE){ array_push($this->tplTree, $tag); } $tag[TAG_TYPE] = T_TEXT; $tmpstring = ''; $openTagCount--; } else { $tmpstring .= $templateContent[$pointer]; } $pointer++; } // push last value on the stack array_push($this->tplTree, array(T_TEXT, $tmpstring)); if ($openTagCount > 0){ trigger_error('template::toTree(): Some tags did not have a closing tag.', E_USER_WARNING); } } |
2) voor elke END_TOKEN zal hij checken wat er in die tag zat en of hij daar nog iets mee moet aanvangen. Dit gebeurt door erg simpele en voor de hand liggende functie's.
Code:
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
| private function determineTagType($tag, $pointer){ $tagarr[TAG_TYPE] = T_DISPOSABLE; $tagarr[TAG_VALUE] = null; if (substr($tag, 0, 1) != '/'){ // start tags switch (true){ case substr($tag, 0, 3) == 'php': $tagarr[TAG_TYPE] = T_PHP; ob_start(); eval('print('.substr($tag, 4).');'); $tagarr[TAG_VALUE] = ob_get_contents(); ob_end_clean(); break; case substr($tag, 0, 2) == 'if': $tagarr[TAG_TYPE] = T_START_IF; $tagarr[TAG_VALUE] = $this->evaluateIf(substr($tag, 3)); break; case substr($tag, 0, 7) == 'else if': $tagarr[TAG_TYPE] = T_ELSE_IF; $tagarr[TAG_VALUE] = $this->evaluateIf(substr($tag, 8)); break; case substr($tag, 0, 4) == 'else': $tagarr[TAG_TYPE] = T_ELSE; $tagarr[TAG_VALUE] = null; break; case substr($tag, 0, 4) == 'file': //$tagarr[TAG_TYPE] = T_FILE; $tagarr[TAG_TYPE] = T_DISPOSABLE; // get rid of this, it will be added to the tree by toTree() $tmp = substr($tag, 5); if (file_exists($this->skinpath . $tmp)){ $tagarr[TAG_VALUE] = file_get_contents($this->skinpath . $tmp); $this->toTree($tagarr[TAG_VALUE]); } else { trigger_error('The file: '. $this->skinpath . $tmp .' does not excist on the harddrive.', E_USER_ERROR); } break; case substr($tag, 0, 7) == 'varfile': //$tagarr[TAG_TYPE] = T_VARFILE; $tagarr[TAG_TYPE] = T_DISPOSABLE; // get rid of this, it has already been added to the tree $tmp = substr($tag, 8); if (isset($this->tplVarFiles[$tmp])){ if (file_exists($this->skinpath . $this->tplVarFiles[$tmp])){ $tagarr[TAG_VALUE] = file_get_contents($this->skinpath . $this->tplVarFiles[$tmp]); $this->toTree($tagarr[TAG_VALUE]); } else { trigger_error('template::determineTagType(): The varfile: '. $this->skinpath . $this->tplVarFiles[$tmp] .' does not excist on the harddrive.', E_USER_ERROR); } } else { trigger_error('template::determineTagType(): The varfile: '. $tmp .' does not excist in the varfile list.', E_USER_ERROR); } break; case substr($tag, 0, 4) == 'loop': $tagarr[TAG_TYPE] = T_START_LOOP; $tagarr[TAG_VALUE] = $this->evaluateLoop(substr($tag, 5)); break; case substr($tag, 0, 7) == 'foreach': $tagarr[TAG_TYPE] = T_START_FOREACH; $tagarr[TAG_VALUE] = $this->evaluateForEach(substr($tag, 8)); break; default: if (isset($this->tplLoopVars[$tag])){ $tagarr[TAG_TYPE] = T_LOOP_VAR; $tagarr[TAG_VALUE] = '$'.$tag.'['.VAL.']'; for ($i = 0; $i < $this->tplLoopVars[$tag][DIMENSIONS]; $i++){ $tagarr[TAG_VALUE] .= '[$i['.$i.']]'; } } else if (isset($this->tplVars[$tag])){ $tagarr[TAG_TYPE] = T_VAR; // no longer a T_VAR it is now regular text $tagarr[TAG_VALUE] = $this->tplVars[$tag]; } else { $tagarr[TAG_TYPE] = T_VAR; $tagarr[TAG_VALUE] = START_TOKEN . $tag . END_TOKEN; } break; } } else { // end tags switch (true){ case ($tag == "/if"): $tagarr[TAG_TYPE] = T_END_IF; break; case ($tag == "/foreach"): $tagarr[TAG_TYPE] = T_END_FOREACH; break; case ($tag == "/fe"): $tagarr[TAG_TYPE] = T_END_FOREACH; break; case ($tag == "/loop"): $tagarr[TAG_TYPE] = T_END_LOOP; break; } } return $tagarr; } |
Is dit een redelijke aanpak?
zoja, wat zou er nog sterk geoptimaliseerd kunnen worden, aangezien hij over het samenstellen van de tree ong 80% van de hele parsetijd mee bezig is.
zoniet, zijn hier "standaard" oplossingen/constructie's voor, of (electronische)lectuur hierrond?
Aangezien dit nogal aso grote lappen code zijn en die er misschien snel afgeschopt zullen worden door een modje is hier een link naar de 2 fragmenten.
If it ain't broken it doesn't have enough features