Template cachen

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Template cachen

    Hallo zusammen,

    inspiriert von folgendem Thread http://www.php-resource.de/forum/sho...threadid=48488 möchte ich in meine Template-Klasse nun auch eine Caching-Funktion einbauen. Das Template unterstützt einfach Variablen und Blöcke (auch verschachtelt).

    Die Variablen sind in $this->vars und werden beim cachen mit
    PHP-Code:
    <?php echo $this->vars[NAME_AUS_PREG_MATCH]; ?>
    erstetzt. Zuvor prüfe ich mit array_key_exists ob die gesuchte Variable vorhanden ist. Wenn nicht, wird der Platzhalter einfach gelöscht.

    Das klappt soweit - nun zu den Blöcken. Ein Block hat bei mir folgende Datenquelle in $this->blocks[NAME_DES_BLOCKS]:
    PHP-Code:
    Array
    (
        [
    0] => Array
            (
                [
    wert] => abc
            
    )

        [
    1] => Array
            (
                [
    wert] => def
            
    )

        [
    2] => Array
            (
                [
    wert] => xyz
            
    )


    Den Block ersetze ich durch [PHP]<?php foreach($data as $line) ... ?>/PHP]
    und jage die Vorlage für den Block durch die Funktion, die die Variablen ersetzt. Jetzt findet die Funktion array_key_exists im obigen Array natürlich nicht den Schlüssel 'wert'. Dadurch werden im Block dann auch keine Variablen ersetzt.

    Außerdem müsste ich die Variable ja auch in der foreach-Schleife bei jedem Durchlauf auf Existenz prüfen für den Fall, dass in einem Satz mal ein Schlüssel fehlt - sonst kommt es bekanntlich zu unschönen Fehlermeldungen ... Und genau da brauche ich mal einen Tipp.

    Wir würdet ihr die Ersetzung von Variablen in Blöcken vornehmen und wir würdet ihr prüfen ob die Variable in der Datenquelle vorhanden ist und bei Fehlen reagieren.

    So, ich hoffe das war nicht zu weit ausgeholt und einigermaßen verständlich ... jetzt schon einmal Danke an alle Helfer!

  • #2
    also in meiner class ist es so, dass blöcke nichts anderes sind, als ein normales template. zumindest vom handling.

    da ich das template erst einlese kurz bevor ich alles ausgebe, weiß ich vorher noch nicht, welche Platzhalter es gibt, und welche nicht. ist mir aber auch egal! Wen interessierts?

    Kommentar


    • #3
      @TobiaZ: welche Variablen im Block definiert sind ist egal - auch ob sie in der Datenquelle entsprechend existieren oder nicht. Da stimme ich dir zu.

      Wichtig ist jedoch was passiert. Angenommen das Template enthält in einem Block die Variable {testausgabe}. Wenn diese im Daten-Array vorhanden ist wird ersetzt und gut. Wenn nicht, tritt bei mir z.Zt. ein Fehler auf
      PHP-Code:
      NoticeUndefined indextest in ... on line 11 
      Wie oben geschrieben umgehe ich das bei den Variable die nicht im Block stehen indem ich zuvor mit array_key_exists prüfe. Das geht im Block nicht, da ich für jede Wiederholung prüfen müsste - die Ausgabe im gecachten Dokument erfolgt ja aber nur einmal innerhalb der Schleife die den Block erstellt - etwa so:
      PHP-Code:
      <?php foreach($dies as $das)
          echo 
      $das['NAME_DER_VARIABLE_IM_BLOCK']
          ...
      ?>
      Dann müsste im Prinziep die array_key_exists-Prüfung mit in das gecachte Dokument eingebaut werden und nicht in die Template-Klasse - oder was passiert bei dir wenn eine Variable im Template vorhanden ist, aber keine entsprechende Datenquelle zur Verfügung steht ? Obige Fehlermeldung wirst du doch sicher nicht in Kauf nehmen ...

      Kommentar


      • #4
        Wie oben geschrieben umgehe ich das bei den Variable die nicht im Block stehen indem ich zuvor mit array_key_exists prüfe. Das geht im Block nicht, da ich für jede Wiederholung prüfen müsste - die Ausgabe im gecachten Dokument erfolgt ja aber nur einmal innerhalb der Schleife die den Block erstellt
        hmm, verstehe zwar nicht ganz, wieso du außerhalb des blocks prüfen kannst, und innerhalb nicht. Wie schon gesagt, in meiner Klasse ist der Block nicht mehr als ein normales Template-Objekt.

        wenn du keine möglichkeit der überprüfung siehst, dann geh anhand des werte-arrays hin und ersetze die platzhalter.

        Kommentar


        • #5
          ok, ist vielleich schlecht erklärt ... die Variablen im Template außerhalb der Blöcke liegen in $this->vars['NAME_DER_VARIABLE'] - wenn die Textmarke jetzt {test} lautet kann ich mit array_key_exists prüfen ob 'test' in $this->vars vorhanden ist und ersetzt bzw. löschen.

          Die Blöcke liegen in $this->blocks['NAME_DES_BLOCK'] und haben die Struktur wie oben - da kann ich natürlich nicht mit array_key_exists prüfen ob ein Schlüssel vorhanden ist, weil der Schlüssel ja für jede Wiederholung des Blocks vorhanden seien muss und nicht nur einmalig. Für jede Blockwiederholung existiert ein Array in $this->blocks und erst darin sind die Daten für die jeweilige Wiederholung enthalten (also zweite Ebene sozusagen).

          Abgesehen davon, dass array_key_exists im obigen Beispiel 'wert' nicht findet habe ich das Problem, dass für jede Wiederholung erneut geprüft werden muss ob ein passende Schlüssel existiert (ein Array pro Wiederholung ...)

          Kommentar


          • #6
            hmm, stecke da jetzt noch immer nicht ganz drin. aber habe ja geschrieben, wie ichs machen würde, bzw. es gemacht habe. dann hast du eigentlich keine großen probleme.

            verstehe halt nur noch nicht, wieso du einen normalen platzhalter prüfen kannst, und den im block nicht.

            Willst du prüfen ob der platzhalter da ist? (wenn ja: warum?)
            Oder willst du Prüfen ob es einen Wert für den Platzhalter gibt? (wenn ja: warum?)

            Kommentar


            • #7
              Guten Morgen TobiaZ,

              frisch ausgeschlafen habe ich jetzt alles noch einmal überdacht - und ich glaube ich hänge immer noch irgendwo fest ...

              Ich möchte prüfen, ob für einen Platzhalter im Template ein Wert im Array vorhanden ist. Falls ein Wert vorhanden ist soll der Platzhalter ersetzt werden. Ist kein Wert vorhanden soll der Platzhalter gelöscht werden. Wird dann ein Wert nicht übergeben ist die Seite zwar unvollständig, aber das finde ich immer noch besser als die Ausgabe von '{title}' o.ä. Teilweise nutze ich das auch für alternative Ausgaben.

              Bei Blöcken habe ich halte die Besonderheit das der Schlüssel für die Platzhalter in Ebene zwei steht und nicht mit array_key_exists geprüft werden kann. Außerdem müsste die Prüfung ja für jede Zeile im Block erfolgen falls die einzelnen Sätze mal abweichen und der Schlüssel für eine Wiederholung vorhanden ist und für die nächste nicht.

              Ein kleines Beispiel:
              das array 'data'
              PHP-Code:
              Array
              (
                  [
              0] => Array
                      (
                          [
              wert] => abc
                          
              [anzahl] => 123
                      
              )

                  [
              1] => Array
                      (
                          [
              wert] => def
                      
              )

                  [
              2] => Array
                      (
                          [
              wert] => xyz
                          
              [anzahl] => 789
                      
              )


              das array auf erste Ebene mit den Schlüsseln 0 bis 2 stellt die Wiederholungen für den Block dar. Für jede Wiederholung der eins der array auf zweiter Ebene in den Block eingesetzt.

              Wenn ich jetzt der Platzhalter '{anzahl}' ersetze kann ich mit array_key_exists('anzahl',$data) ja nicht prüfen, da die Schlüssel ja 0,1,2 sind. Da die Schleife im gecachted Dokument durchgelaufen wird kann die Prüfung m.E. nicht in der Templateklasse erfolgen. Mein Ansatz wäre jetzt im gecachten Dokument den Block durch eine foreach-Schleife zu ersetzen und den Platzhalter durch
              PHP-Code:
              <?php echo (array_key_exists('NAME_DER_VARIABLE',DATENQUELLE)
              ?
              AUSGABE:'');?>
              Oder ist der Aufbau des Datenarray ungünstig? Wie sieht bei dir die Datenquelle für Blöcke aus und wie prüfst du ob die zu ersetzenden Variablen in der Datenquelle versogt sind?

              Ich frage mich halt nur ob ich auf dem richtigen Weg bin ...

              Kommentar


              • #8
                nur kurz:

                Falls ein Wert vorhanden ist soll der Platzhalter ersetzt werden. Ist kein Wert vorhanden soll der Platzhalter gelöscht werden.
                sollte nicht das problem sein:

                [man ]empty[/man] hilft weiter. mache ich genauso. optinal wirds z.b. fürs debuggen ausgeschaltet.

                Bei Blöcken habe ich halte die Besonderheit das der Schlüssel für die Platzhalter in Ebene zwei steht und nicht mit array_key_exists geprüft werden kann. Außerdem müsste die Prüfung ja für jede Zeile im Block erfolgen falls die einzelnen Sätze mal abweichen und der Schlüssel für eine Wiederholung vorhanden ist und für die nächste nicht.
                hmm, wieso kannst du nicht isset($data[$i]['wert']) überprüfen?

                die wiederholung für jede zeile ist übrigens gar nicht mal so dumm, da du ja gar nicht sicher sein kannst, dass bei jedem schleifendurchlauf die gleichen werte zur verfügung stehen. (s. dein beispiel)

                Kommentar


                • #9
                  ja, ich glaube langsam kommen wir auf einem gemeinsamen Nenner ... allerdings ziehe ich array_key_exists vor, denn empty liefert auf true wenn die Variable '0' enthält. Wenn ich dann mal eine '0' einfügen möchte geht mir diese mit empty unter. Daher nehme ich halt array_key_exists.

                  Mein Problem lag schlicht wo die Existenz der Variable ( Wert für den Platzhalter) geprüft wird -> in der Templateklasse oder im gecachten Dokument. Ich habe es jetzt im gecachted Dokument - da die Seite ja jedesmal mit anderen Werten aufgerufen wird.

                  Vielen Dank für die geduldige Unterstützung.

                  Kommentar


                  • #10
                    Mein Problem lag schlicht wo die Existenz der Variable ( Wert für den Platzhalter) geprüft wird -> in der Templateklasse oder im gecachten Dokument. Ich habe es jetzt im gecachted Dokument - da die Seite ja jedesmal mit anderen Werten aufgerufen wird.
                    naja, hatte ja in dem anderen Thread (den du glaube ich eingangs schon genannt hast) bereits gesagt, dass ich diese Cache-Funktion IN der Templateklasse eher fehl am Platze sehe.

                    Aber erzähle mir mal, wie dein gecachtes dokument aussieht. Denn dass man trotzdem noch werte übergeben kann, finde ich etwas ungewöhnlich, wenn auch vielleicht sinnvoller.

                    Kommentar


                    • #11
                      also ich habe in meiner Templateklasse eine Funktion, die Platzhalter und Blöcke durch PHP-Code ersetzt. Als "gecachtes" Dokument wird dann eine php-Datei erstellt jedesmal wenn die Vorlage geändert wird.

                      Ist die gecachte Datei aktueller als die Vorlage, wird einfach die gecachte-Datei per Include in meine Templateklasse geladen und zurück gegeben. Das spart das parsen nach Platzhalteren und Blöcken mit PCRE-Funktionen und das Ersetzen mit str_replace.

                      Aus der Vorlage:
                      PHP-Code:
                      <body >
                      <
                      p>nur ein Test ...</p>
                      <
                      p>{test}</p>
                      <
                      table border="1">
                          <
                      tr>
                              <
                      td>{test2}</td>
                          </
                      tr>
                          <!--
                      Begin zeilen-->
                          <
                      tr>
                              <
                      td>{wert}</td>
                          </
                      tr>
                          <!--
                      End zeilen-->
                      </
                      table>
                      </
                      body
                      wird dann in der Templateklasse folgende Datei erstellt - sofern die Vorlage sich geändert hat -
                      PHP-Code:
                      <body >
                      <p>nur ein Test ...</p>
                      <p><?php echo (array_key_exists('test',$this->vars)?$this->vars['test']:'');?></p>
                      <table border="1">
                          <tr>
                              <td><?php echo (array_key_exists('test2',$this->vars)?$this->vars['test2']:'');?></td>
                          </tr>
                          <?php foreach($this->blocks['zeilen'] as $value){ ?>
                          <tr>
                              <td><?php echo (array_key_exists('wert',$value)?$value['wert']:'');?></td>
                          </tr>
                          <?php ?>
                      </table>
                      </body>
                      Die Variablen $this->vars bzw. blocks['...'] sind die der Templateklasse. Hier erfolgt auch die Datenübergabe. Wenn ich dich in dem o.g. Thread richtig verstanden habe, gehst du genauso vor - oder doch noch anders ?

                      Kommentar

                      Lädt...
                      X