Daten ersetzen, allerdings Ausnahmen beachten

Dark Ranger

Erfahrenes Mitglied
Mit folgendem Code ersetze ich in einem Template die Variablen
PHP:
private function replaceValues() {
		foreach ($this->vars as $key => $value) {
			$this->template = str_replace($this->leftDelimiter . $key . $this->rightDelimiter, $value, $this->template);
		}
	}
Allerdings ist nun das Problem, dass die Daten nicht ersetzt werden, wenn die Variable innerhalb von {multiply} {/multiply} stehen.

Wie regele ich das am besten?
 
Das ist eine gute Frage, dazu müßtest du schon ein bisschen mehr verraten. Ich nehme mal an, es handelt sich um eine Template Engine und wie sehen deine Delemiter aus?
 
Also Template sieht wie folgt aus:
HTML:
<div id="test">
    Name: {$name}<br />
    Infos:
    {multiply name="infos}
        $info
    {/multiply}
</div>

PHP Code
PHP:
    $template->assign("name","Dark Ranger");
    $template->addMulitArray("infos",$multiArray);
    $template->display();

Das ganze wird erst beim display() ausgeführt und ersetzt, nun ist das Problem, dass es ja vorkommen kann, dass ich
PHP:
$template->assgin("info","Test");
angebe, so wird bis jetzt noch dass {$info} innerhalb von {multiply} ersetzt. Soll aber nicht so sein.

Delimiter sind:
links = {$
rechts = }
 
Welche template engine ist das denn? Smarty? Prüfe doch einfach einen Flag.

PHP:
$template->assign("flag","true");

HTML:
{if $flag == true}
   {multiply name="infos}
   {$info}
   {/multiply}
{else}
  {$info}
{/if}
 
Ne den größten Teil am Template System habe ich selbst geschrieben, versuche ein bisschen von Smarty wegzukommen, dass habe ich vorher verwendet.

PHP:
private function replaceMultiArray() {
		foreach($this->multiArrays as $key => $value) {
			$pattern = '/\{multiply\sname=[\"\']'.$key.'[\"\']\}(.*)\{\/multiply}/isUe';
			if(preg_match($pattern,$this->template,$subpattern)) {
				$out="";
				foreach($value as $valKey => $valValue) {
					$output=$subpattern[1];
					foreach($valValue as $valvalKey => $valvalValue) {
						$output = str_replace($this->leftDelimiter.$valvalKey.$this->rightDelimiter,$valvalValue,$output);
					}
					$out .= $output;
				}
			}
			$this->template = str_replace($subpattern[0],$out,$this->template);
		}
	}
So werden bei mir die {multiply} ersetzt

Und wie oben schon gesehen, die normalen Variablen.

Auch wenn ich zuerst die multiply ersetze und dann erst die Values, funktioniert es nicht, weil es trotzdem noch vorkommen kann, dass etwas ersetzt wird was nicht erseztzt werden soll

Edit:
Habe das erstmal so gelöst
HTML:
    {multiply name="test"}
        {$test.id} --> {$test.name}
    {/multiply}
Wer ne andere Lösung hat, wo ich das wie oben genannt ausschließen kann, immer her damit.

Nun will ich etwas anderes versuchen.
mit
PHP:
$template->addMultiArray("test",$multiArray);
weise ich ja die Werte zu. Wenn der HTML Code jetzt allerdings komplexer wird und ich ein {multiply} in einem anderen {multiply} habe, dann funktioniert das ganze so nicht, ich.
HTML:
    {multiply name="test"}
        {$test.name}
        {multiply name="infos"} // ODER {multiply name="test.infos"} würde auch gehen
            {$infos.info}
        {/multiply}
    {/multiply}
Und folgender PHP Code
PHP:
    $multiArray = array(array("name"=>"Dark Ranger",
                                         "infos"=>array(array("info"=>"Test"),
                                                               array("info"=>"Test1"))));
    $template->addMultiArray("test",$multiArray);

Nun muss er für das zweite multiply die Daten in dem Array vom ersten multiply suchen, allerdings habe ich keinen Plan wie ich das ganze realisieren soll. Am besten natürlich so, dass es noch ein drittes multiply und ein viertes und fünftes usw. geben kann
 
Zuletzt bearbeitet:
PHP:
private function replaceMultiArray() {
		foreach($this->multiArrays as $key => $value) {
			$pattern = '/\{multiply\sname=[\"\']'.$key.'[\"\']\}(.*)\{\/multiply}/isUe';
			if(preg_match($pattern,$this->template,$subpattern)) {
				$out="";
				foreach($value as $valKey => $valValue) {
					$output=$subpattern[1];
					foreach($valValue as $valvalKey => $valvalValue) {
						$output = str_replace($this->leftDelimiter.$key.'.'.$valvalKey.$this->rightDelimiter,$valvalValue,$output);
					}
					$out .= $output;
				}
				$this->template = str_replace($subpattern[0],$out,$this->template);
			}
		}
		$pattern = '/\{multiply\sname=[\"\'](.*)[\"\']\}(.*)\{\/multiply}/isUe';
		$this->template = preg_replace($pattern,"",$this->template);
	}

Diese Funktion müsste sich sozusagen selber wieder aufrufen, wenn es innerhalb des multiply ein weiteres multiply gibt, allerdings dann nicht mit dem globalen Array arbeiten sondern mit dem was ich brauche.

Allerdings findet diese Funktion ja nur das nächste {/multiply}, müsste aber für jedes offene {multiply} ein schließendes finden. Im moment noch keine Ahnung wie ich da ran gehen soll -.-
 
Warum prüfts du denn nicht nochmal $this->template und wenn $pattern gefunden ruftst du die Funktion rekursiv auf. Also einfach solange wie $pattern gefunden.
 
Naja weil wenn ich den pattern so anwende, dann nimmt er nicht alles was er soll.

Ich müsste erst nach den Anfängen suchen, soviel Anfänge da sind, soviele Enden müssen auch da sein.
Das ganze werde ich morgen mal versuchen umzusetzen, mal schauen was dabei herum kommt ^^

Habe da auf Wikipedia etwas von einem Kellerautomaten gelesen
 
PHP:
private function replaceMultiArray2() {
		$pattern_begin = '/\{multiply\sname\=[\"\'](.*)[\"\']\}/isU';
		$pattern_end = '/\{\/multiply\}/isU';
		$start=0;
		$Begins=array();
		while(preg_match($pattern_begin,$this->template,$subpattern, PREG_OFFSET_CAPTURE,$start)) {
			$start=$subpattern[0][1]+strlen("{multiply name='".$subpattern[1][0]."'}");
			array_push($Begins,array("name"=>$subpattern[1][0],
									 "pos"=>$subpattern[0][1]));
		}
		$countBegins = count($Begins);
		$start=0;
		$Ends=array();
		while(preg_match($pattern_end,$this->template,$subpattern, PREG_OFFSET_CAPTURE,$start)) {
			$start=$subpattern[0][1]+strlen("{/multiply}");
			array_push($Ends,array("pos"=>$subpattern[0][1]));
		}
		$countEnds = count($Ends);
		if($countEnds!=$countBegins) {
			throw new Exception("Fehlermeldung");
		}
	}

Soweit habe ich es jetzt schonmal ^^
Habe erst versucht das ganze gierig zu machen, aber da hat er mir nur Blödsinn ausgegeben, nun mache ich es halt so, dadurch habe ich schonmal die Positionen und den Namen. Nun muss ich das ganze noch irgendwie zuordnen. Wird glaube ich mal der schwierigste Teil, da das ganze am Besten rekursiv aufgebaut werden sollte ^^

Schauen wir mal, wenn irgendwer einen Tip hat, dann bitte posten, würde mich freuen

Edit:
PHP:
	private function replaceMultiArray2() {
		$pattern_begin = '/\{multiply\sname\=[\"\'](.*)[\"\']\}/isU';
		$pattern_end = '/\{\/multiply\}/isU';
		$start=0;
		$index=1;
		$Begins=array();
		while(preg_match($pattern_begin,$this->template,$subpattern, PREG_OFFSET_CAPTURE,$start)) {
			$start=$subpattern[0][1]+strlen("{multiply name='".$subpattern[1][0]."'}");
			array_push($Begins,array("name"=>$subpattern[1][0],
									 "index"=>$index,
									 "pos"=>$subpattern[0][1]));
			$index++;
		}
		$countBegins = count($Begins);
		$start=0;
		$index=$Begins[count($Begins)-1]['index'];
		$Ends=array();
		$belegt=array();
		while(preg_match($pattern_end,$this->template,$subpattern, PREG_OFFSET_CAPTURE,$start)) {
			$start=$subpattern[0][1]+strlen("{/multiply}");
			while($Begins[$index-1]['pos']>$subpattern[0][1] AND $index>1) {
				$index--;
			}
			while(in_array($index,$belegt)) {
				$index--;
			}
			array_push($Ends,array("index"=>$index,
								   "pos"=>$subpattern[0][1]));
			array_push($belegt,$index);
			$index=$Begins[count($Begins)-1]['index'];
		}
		$countEnds = count($Ends);
		if($countEnds!=$countBegins) {
			throw new Exception("Fehlermeldung");
		}
		usort($Begins,array(&$this,"compareMultiArrayIndex"));
		usort($Ends,array(&$this,"compareMultiArrayIndex"));
	}

So ist meine Funktion inzwischen, durch den index lege ich halt fest, welche beiden Teile zusammen gehören.
Am Schluss sortiere ich das ganze noch absteigend, so fange ich sozusagen mit den innersten {multiplys} an denke ich
Stehe aber gerade im Moment aufm Schlauch und weiß nicht wie ich weiter machen soll, muss ja nun irgendwie schauen wie ich das ganze ersetze, da die informationen von dem einen {multiply} ja in dem member des arrays vom anderen {multiply} stehen.
 
Zuletzt bearbeitet:
Zurück