Portal > Foren > PHP > PHP-Programmierung > PHP template und schleifen
Antwort
 
Themen-Optionen
Alt 17.09.2007, 16:39 Nach oben    #1
Benutzer
 
Registriert seit: 16.09.2007
Beiträge: 63
Standard PHP template und schleifen

Hallo,

Ich versuche gerade meine eigne template class zu schreiben. Es läuft auch so weit, aber ich steh nun seid 2 tagen auf dem schlauch und komm einfach nicht mehr weiter. Einfache Platzhalter kann es schon gut ersetzten, aber ich möchte auch das daten aus einer Datenbank einliest und ausgibt. Dies wolllte ich mit einer foreach schleife lösen.

template.cls.php
PHP-Code:
    function assign_array($replace$replacement_array) {
        
$matches = array ();
        
preg_match('/\{foreach \$'.$replace.'\}(.*?)\{\/foreach\}/si'$this->template$matches);
        
$keys array_keys($replacement_array['0']);
        
$row '';
        foreach (
$replacement_array as $array) {
            
$items $matches['1'];
            foreach (
$keys as $key) {
                
$items str_replace($this->leftDelimiter.$key.$this->rightDelimiter$array[$key], $items);
            }
            
$row .= str_replace($matches['1'], $row$items);
            
$row rtrim($row);
        }
        
$all_rows preg_replace('/\r\n/si'''rtrim($row), 1);
        
$this->template str_replace($matches['0'], $all_rows$this->template);
        } 
index.php
PHP-Code:
$test = array(
        
"news" => $data,
        );

$tpl->assign_array("news" $test); 
news.tpl
PHP-Code:
{foreach $news}
<
a href='viewtopic.php?t={$topic_id}'>{$topic_title}</a>
{/foreach} 
Es kommt aber nur fehler raus.
Notice: Undefined index: 0 in /is/htdocs/wp1009673_FMKUCXMAF1/www/php/cls/template.class.php on line 165

Warning: array_keys() [function.array-keys]: The first argument should be an array in /is/htdocs/wp1009673_FMKUCXMAF1/www/php/cls/template.class.php on line 165

Warning: Invalid argument supplied for foreach() in /is/htdocs/wp1009673_FMKUCXMAF1/www/php/cls/template.class.php on line 169

Geändert von Victorious (17.09.2007 um 16:43 Uhr).
Victorious ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 17.09.2007, 17:24 Nach oben    #2
Erfahrener Benutzer
 
Registriert seit: 30.10.2005
Beiträge: 279
Standard

Ich denke du brauchst ein assoziatives Array wie es aus einem ResultSet gefetched wird.

$test = array(
array(
"news" => 1
),
array(
"news" => 2
)
);


Find ich ja ok das du meinen schlampigen Schnipsel nimmst, allerdings würd ich davon abraten und eher auf Smarty oder irgendeine PEAR Template Klasse setzen.
ex³ ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 17.09.2007, 18:20 Nach oben    #3
Benutzer
 
Registriert seit: 16.09.2007
Beiträge: 63
Standard

Hm ich habe schon mit samrty gearbeite finde es auch sehr gut. Nur will mein eigenes haben. Was das erfüllen soll

-Platzhalter ersetzen (funktioniert schon)
-Schleifen
-Cachen

Und aus dem Quellecode von samrty werde ich auch ned ganz schlau.
Daher habe ich hier mal im forum geschaut und nach tutorials gesucht.Wo ich auch fündig wurde.^^ Aber irgendwie klappt das ganze nicht so.

Wenn ich das anwede kommt der fehler:
Notice: Use of undefined constant topic_id - assumed 'topic_id' in /is/htdocs/wp1009673_FMKUCXMAF1/www/php/index2.php on line 27

Notice: Use of undefined constant topic_title - assumed 'topic_title' in /is/htdocs/wp1009673_FMKUCXMAF1/www/php/index2.php on line 30

Der code sieht dazu so aus
PHP-Code:
$test = array(
array(
        
"news" => $data[topic_id]
        ),
array(
"news" => $data[topic_title]
)
); 

Geändert von Victorious (17.09.2007 um 19:01 Uhr).
Victorious ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 17.09.2007, 20:38 Nach oben    #4
Martin Breuer
 
Benutzerbild von WarrenFaith
 
Registriert seit: 17.08.2005
Ort: Berlin
Beiträge: 1.642
Standard

wenn dein Array mit assozierten Indexen arbeitet, so sind diese vom Typ String.
Du solltest also $data['topic_id'] bzw $data["topic_id"] verwenden.
Das wird übrigends auch in der Fehlermeldung erklärt.
__________________
I did it my way - Senseless-Blog
WarrenFaith ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 17.09.2007, 20:52 Nach oben    #5
Christian Schuhmann
 
Benutzerbild von bobby
 
Registriert seit: 09.03.2007
Ort: Nürnberg
Beiträge: 58
Standard

Ergänzend zu Martins Vorschlag: Ich denke dein $test-Array müsste etwas so aussehen:

PHP-Code:
$test = array(
    array(
'topic_id' => 1'topic_title' => 'Title 1'),
    array(
'topic_id' => 2'topic_title' => 'Title 2'),
    array(
'topic_id' => 3'topic_title' => 'Title 3'),
    array(
'topic_id' => 4'topic_title' => 'Title 4'),
); 
bobby.
bobby ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 17.09.2007, 21:17 Nach oben    #6
Benutzer
 
Registriert seit: 16.09.2007
Beiträge: 63
Standard

hm ja so kommt keine fehlermeldung mehr danke. Aber das nächste problem ist das nun nix mehr angezeigt wird sprich die seite bleibt leer.
Victorious ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 18.09.2007, 09:49 Nach oben    #7
Martin Breuer
 
Benutzerbild von WarrenFaith
 
Registriert seit: 17.08.2005
Ort: Berlin
Beiträge: 1.642
Standard

Dann zeig uns bitte nochmal kurz was du genau als Quellcode hast. Ich seh grade nicht mehr so richtig durch
__________________
I did it my way - Senseless-Blog
WarrenFaith ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 18.09.2007, 10:24 Nach oben    #8
Benutzer
 
Registriert seit: 16.09.2007
Beiträge: 63
Standard

Die Template.cls.php
PHP-Code:
<?php
error_reporting
(E_ALL);

class 
tpl
{


       
/**
     * Der Ordner in dem sich die Template-Dateien befinden.
     *
     * @access public
     * @var    string
     */
    
var $templateDir "templates/";
    
    
/**
     * Der linke Delimter für einen Standard-Platzhalter
     *
     * @access public
     * @var    string
     */
    
var $leftDelimiter '{$';
    
    
/**
     * Der rechte Delimter für einen Standard-Platzhalter
     *
     * @access public
     * @var    string
     */
    
var $rightDelimiter '}';

    
/**
     * Der linke Delimter für eine Funktion
     *
     * @access public
     * @var    string
     */
    
var $leftDelimiterF '{';
    
    
/**
     * Der rechte Delimter für eine Funktion
     *
     * @access public
     * @var    string
     */
    
var $rightDelimiterF '}';

    
/**
     * Der linke Delimter für ein Kommentar
     * Sonderzeichen müssen escaped werden, weil der Delimter in einem RegExp
     * verwendet wird.
     *
     * @access public
     * @var    string
     */
    
var $leftDelimiterC '\{\*';
    
    
/**
     * Der rechte Delimter für ein Kommentar
     * Sonderzeichen müssen escaped werden, weil der Delimter in einem RegExp
     * verwendet wird.
     *
     * @access public
     * @var    string
     */
    
var $rightDelimiterC '\*\}';
    
    
/**
     * Der komplette Pfad der Templatedatei.
     *
     * @access var
     * @var    string
     */
    
var $templateFile "";
    
    
/**
     * Der Dateiname der Templatedatei
     *
     * @access var
     * @var    string
     */
    
var $templateName "";
    
    
/**
     * Der Inhalt des Templates.
     *
     * @access var
     * @var    string
     */
    
var $template "";


    
/**
     * Die Templatedatei öffnen
     *
     * @access    public
     * @param     string $file Dateiname des Templates
     * @return    boolean
     */
    
function load($file)
    {
        
// Die Eigenschaften zuweisen
        
$this->templateName $file;
        
$this->templateFile $this->templateDir.$file;

        
// Wenn ein Dateiname übergeben wurde, versuchen, die Datei zu öffnen
        
if(!empty($this->templateFile)) {
            if(
$fp = @fopen($this->templateFile"r")) {
                
// Den Inhalt des Templates einlesen
                
$this->template fread($fpfilesize($this->templateFile)); 
                
fclose ($fp); 
            } else {
                return 
false;
            }
        }

        
// Die methode replaceFuntions() aufrufen
        
$this->replaceFunctions();
        
        return 
true;
    }


    
/**
     * Die Standard-Platzhalter ersetzen
     *
     * @access    public
     * @param     string $replace      Name of var which should be replaced
     * @param     string $replacement  Text with which to replace the var
     * @return    boolean
     */
    
function assign($replace$replacement)
    {
        
$this->template str_replace($this->leftDelimiter.$replace.$this->rightDelimiter$replacement$this->template);
        return  
true;
    }

    
    
/**
     * Die Funktionen ersetzen
     *
     * @access    var
     * @return    boolean
     */
    
function replaceFunctions()
    {
        
// Includes ersetzen ( {include file="..."} )
        
while(preg_match("/".$this->leftDelimiterF."include file=\"(.*)\.(.*)\"".$this->rightDelimiterF."/isUe"$this->template)) {
            
$this->template preg_replace("/".$this->leftDelimiterF."include file=\"(.*)\.(.*)\"".$this->rightDelimiterF."/isUe""file_get_contents(\$this->templateDir.'\\1'.'.'.'\\2')"$this->template);
        }

    
        
// Kommentare löschen
        
$this->template preg_replace("/".$this->leftDelimiterC."(.*)".$this->rightDelimiterC."/isUe"""$this->template);
        
        return  
true;
    }
    
    function 
assign_array($replace$replacement_array) {
        
$matches = array ();
        
preg_match('/\{foreach \$'.$replace.'\}(.*?)\{\/foreach\}/si'$this->template$matches);
        
$keys array_keys($replacement_array['0']);
        
$row '';
        foreach (
$replacement_array as $array) {
            
$items $matches['1'];
            foreach (
$keys as $key) {
                
$items str_replace($this->leftDelimiter.$key.$this->rightDelimiter$array[$key], $items);
            }
            
$row .= str_replace($matches['1'], $row$items);
            
$row rtrim($row);
        }
        
$all_rows preg_replace('/\r\n/si'''rtrim($row), 1);
        
$this->template str_replace($matches['0'], $all_rows$this->template);
        return 
true;
    } 
       
      
        
        
    

      
       
/**
     * Das fertige Template ausgeben
     *
     * @access    public
     * @return    boolean
     */
    
function out()
    {
        echo 
$this->template;
        return 
true;
    }
}
?>
die index.php
PHP-Code:
// Das Templatesystem einbinden
include("cls/template.class.php");

// Eine neue Instanz der Template Klasse erzeugen
$tpl = new tpl();

// Das Template laden
$tpl->load("news.tpl");

//Verbindung zur DB 
mysql_connect($sqlhost,$sqluser,$sqlpass) OR DIE( "Couldn't connect to MySQL server!");
mysql_select_db($database); 

// DB daten auslesen
$result mysql_query("SELECT * FROM roforum_topics  where forum_id='17'  ORDER BY topic_id DESC LIMIT 0,1");
$eintraege = @mysql_num_rows($result);

while (
$data mysql_fetch_array($result)) {

$test = array(
array(
        
"news" => $data["topic_id"]
        ),
array(
"news" => $data["topic_title"]
)
);

$tpl->assign_array("news" $test);

}
// Und das fertige Template ausgeben
$tpl->out(); 
die news.tpl
PHP-Code:
{foreach $news}
<
a href='Forum/viewtopic.php?t={$topic_id}'>{$topic_title}</a>
{/foreach} 
So sieht mein ganze code aus.
Victorious ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 18.09.2007, 10:41 Nach oben    #9
Bastian Fenske
 
Registriert seit: 04.01.2006
Ort: Kassel
Beiträge: 826
Standard

Hi.

Abgesehen davon, dass ich von dieser Template-Strategie immer noch nichts halte und jetzt nicht nach einem konkreten Fehler gesucht habe zwei grundsätzliche Anmerkungen:

Warum führst du die Ersetzungen nicht erst aus, wenn das Template ausgegeben werden soll? Kann doch sein, dass sich in einem eingebetteten Modul ein Fehler zeigt, dann wird am Ende gar nichts ausgegeben, wurden die Ersetzungen also völlig umsonst durchgeführt. Wichtiger noch: Wie überschreibst du eine einmal gemachte Zuweisung wieder (Zum Beispiel den Seitentitel)? Wie hängst du nochmal was an ein Array an? (Zum Beispiel Meta-Tags)?

Und der zweite Punkt: Warum weist du die Werte, die in der Schleife bei den einzelnen Durchläufen gelten nicht einer Variable im Template zu? Wie kann ein Template-Designer innerhalb der Schleife unterscheiden zwischen einem globalen $topic_id und einem $news['topic_id']?

Und zusammen:
Was, wenn du jetzt vor der Zuweisung eines Wertes an $news der Vatiable $topic_id einen Wert zuweist? Werden dann auch die $topic_id in der foreach-Schleife ersetzt?

Da scheint mir schon vor der Umsetzung in der Konzeption einiges unklar zu sein.

Basti
Basti ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 18.09.2007, 12:29 Nach oben    #10
Jann Hendrik Bekaan
 
Benutzerbild von Jann Hendrik
 
Registriert seit: 02.12.2004
Ort: Wildeshausen
Beiträge: 2.211
Standard

Fehlerunterdrückung
Ein @ vor einer Funktion sorgt dafür, dass die Fehler, die man auf andere Weise auffangen sollte, nicht angezeigt werden.

Zum debuggen (also dem Auffinden von Fehlern) ist das absolut destruktiv.

Du schriebst:
Zitat:
Zitat von Victorious Beitrag anzeigen
hm ja so kommt keine fehlermeldung mehr danke. Aber das nächste problem ist das nun nix mehr angezeigt wird sprich die seite bleibt leer.
Somit nehme ich an, dass du Fehler eigentlich angezeigt bekommen möchtest.


Das @ war das erste, was mir auffiel...
Jann Hendrik ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 18.09.2007, 14:06 Nach oben    #11
Benutzer
 
Registriert seit: 16.09.2007
Beiträge: 63
Standard

Was ist den falsch Templates zu benutzen?Ich hab früher alles ohne gemacht,aber mit der zeit wurde alles unübersichtlich da die seiten größer wurden und die scripte.Dann bin ich auf smarty umgestiegen wo ich eigentlich begeistert bin, aber ich möchte nun halt selber eins schreiben.Da smarty viel mehr funktionen hat als ich sie brauche. Und durch Templates ist es für meinen designer und mich leichter gewurden ich kann meine scripte schreiben und er das html+grafiken. Ich muss dann nur noch die Platzhalter einfügen und nicht mehr den gesamten code. Oder habe ich die falsch verstanden @basti?
Victorious ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 18.09.2007, 14:11 Nach oben    #12
Martin Breuer
 
Benutzerbild von WarrenFaith
 
Registriert seit: 17.08.2005
Ort: Berlin
Beiträge: 1.642
Standard

Er meinte nicht die Templateverwendung an sich, sondern wohl eher die Art, wie du es zu lösen versuchst.

Such mal nach "Template" im Forum, es gab dazu schon einige sehr gute Threads die sich zum Teil auch gut der Konzeptionierung gewidmet haben.
__________________
I did it my way - Senseless-Blog
WarrenFaith ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 18.09.2007, 14:11 Nach oben    #13
Ben
Benjamin Klaile
 
Benutzerbild von Ben
 
Registriert seit: 02.12.2004
Ort: Remagen
Beiträge: 4.480
Standard

Die Diskussion über pro und contra von Templates kann man wunderbar an dieser Stelle diskutieren: PHP Templates (Bsp. Wordpress)

Bitte nicht in diesem Thread, da das dann doch etwas am Thema vorbeigeht.
Danke.
Ben ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 18.09.2007, 16:09 Nach oben    #14
Bastian Fenske
 
Registriert seit: 04.01.2006
Ort: Kassel
Beiträge: 826
Standard

Nein, es geht natürlich nicht um die Frage, ob Templates oder nicht (übrigens auch nicht im von Ben verlinkten Thread, denn "PHP-Templates" sind natürlich auch Templates, ist ja klar). Ich halte es einfach für übertrieben aufwändig, Templates von Hand zu parsen, anstatt auf direktem Weg das zu tun, was man da umsetzen will: Man ist der Meinung, PHP sei für einen Template-Designer zu mächtig, von mir aus auch zu aufwändig oder zu fehleranfällig etc., also bietet man ihm eine Template-Umgebung an, die nur bestimmte Optionen zulässt, Fehler selbstständig glattbügelt, einfach ist etc. Man legt also zu einen Filter und Übersetzer zwischen PHP und den Template-Designer, so wie es Smarty und andere Template-Engines machen. Ich weiß nicht, was daran so toll oder gar vorteilhaft sein soll, sich selbst einen Parser zu bauen? …aber, das ist ja nicht so ganz das Thema hier.

Zitat:
Zitat von Victorious Beitrag anzeigen
[…] Dann bin ich auf smarty umgestiegen wo ich eigentlich begeistert bin, aber ich möchte nun halt selber eins schreiben.Da smarty viel mehr funktionen hat als ich sie brauche.
Das ist der Grund? Warum schaust du dir nicht einfach mal Smarty an und löschst die einzelnen Funktionen raus? Es ist doch immer einfach, in einem bereits umfangreichen und praxiserprobten Open-Source-Code ein paar Funktionen rauszustreichen, als den ganzen Mist mit ein paar weniger Funktionen nachzubauen.

Basti

Geändert von Basti (18.09.2007 um 16:12 Uhr).
Basti ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 18.09.2007, 16:47 Nach oben    #15
Martin Breuer
 
Benutzerbild von WarrenFaith
 
Registriert seit: 17.08.2005
Ort: Berlin
Beiträge: 1.642
Standard

Zitat:
aber ich möchte nun halt selber eins schreiben
Rechtfertigung genug. Lerneffekt beim selber machen.
Könnten wir bitte jetzt wieder zurück zum Topic kommen?

@Victorious: Hat der Tipp von JannH geholfen? Wenn nicht, dann bau dir ein paar Debugausgaben und und schau nach was so in den Variablen gespeichert ist.
__________________
I did it my way - Senseless-Blog
WarrenFaith ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 18.09.2007, 18:33 Nach oben    #16
Benutzer
 
Registriert seit: 16.09.2007
Beiträge: 63
Standard

Nein hat er mich nicht. Wie und wo soll ich den das debbuging einbauen. Hab sowas erhlich gesagt noch nie gemacht debbuging.
Victorious ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 18.09.2007, 23:05 Nach oben    #17
Benutzer
 
Registriert seit: 16.09.2007
Beiträge: 63
Standard

Zitat:
Zitat von Basti Beitrag anzeigen



Warum führst du die Ersetzungen nicht erst aus, wenn das Template ausgegeben werden soll?
Wie kann ich das den realisieren?sorry wenn ich dauernt frage aber in solchen sachen bin ich echt noch ein noob.Daher möchte ich das ja lernen.
Victorious ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 19.09.2007, 09:54 Nach oben    #18
Martin Breuer
 
Benutzerbild von WarrenFaith
 
Registriert seit: 17.08.2005
Ort: Berlin
Beiträge: 1.642
Standard

PHP-Code:
<?php
    
function assign_array($replace$replacement_array) {
        
$matches = array ();
        
preg_match('/\{foreach \$'.$replace.'\}(.*?)\{\/foreach\}/si'$this->template$matches);
        
var_dump($matches); // Debugausgabe fuer deine Treffer...
        
$keys array_keys($replacement_array['0']);
        
$row '';
        foreach (
$replacement_array as $array) {
            
var_dump($array); // Debugausgabe fuer $array, was steht da eigentlich drin...
            
$items $matches['1'];
            foreach (
$keys as $key) {
                
$items str_replace($this->leftDelimiter.$key.$this->rightDelimiter$array[$key], $items);
            }
            
$row .= str_replace($matches['1'], $row$items);
            
$row rtrim($row);
        }
        
$all_rows