Include innerhalb von Funktionen oder Methoden nutzen

xtramen01

Erfahrenes Mitglied
Hallo Leute,
ich binde Template Dateien (phtml) derzeit über den include() Befehl ein.
Die Dateien beinhalten auch PHP Code. Aus Performance Gründen möchte ich auf Smarty oder ähnliche Engines verzichten.

Das sieht momentan so aus:

include(tpl('includes/template_top'));

Die Funktion tpl() beinhaltet lediglich den absoluten Pfad zum aktuell verwendeten Template.
Nun habe ich mich gefragt, ob es irgendwie möglich wäre das ganze auch komplett in eine Funktion zu Packen.
Also z.b. so:

PHP:
  function tpl($tpl){
    $template_include = DIR_FS_CATALOG . TEMPLATE_DIR . DIRECTORY_SEPARATOR . TEMPLATE_CURRENT . DIRECTORY_SEPARATOR . $tpl . '.phtml';

    return include($template_include);
  }

Leider funktioniert das nicht so richtig, da ich dann Probleme mit Variablen habe die nicht als GLOBALS deklariert sind.
Gibt es da irgend eine andere Möglichkeit, das mit einer Funktion zu lösen? Danke und Gruß
 
Z.b.

<b>Fatal error</b>: Call to a member function getTitle() on a non-object in <b>/var/www/vhosts/xxx/templates/default/includes/template_top.phtml</b> on line <b>5</b><br />

Erzeugt durch: $sfTemplate->getTitle();

Aber nur wenn ich es so mache, das innerhalb der Funktion, die Templatedatei eingebunden wird.

P.S. Habe es auch schon so probiert, mit selbem Ergebnis:

PHP:
    class template{

        public function display($tpl){

        $template_include = DIR_FS_CATALOG . TEMPLATE_DIR . DIRECTORY_SEPARATOR . TEMPLATE_CURRENT . DIRECTORY_SEPARATOR . $tpl . '.tpl';

            ob_start();
            include($template_include);
            $content = ob_get_contents();
            ob_end_clean();
           
            echo $content;

        } 

    }
 
Zuletzt bearbeitet:
Jou das ist eigentlich klar :)
Aber wenn ich jede Variable die in einem Template verwendet wird extra der Funktion übergeben muss, kann ich ja gleich darauf verzichten. Gibt es da nicht eine andere Möglichkeit?

Bei Smarty oder anderen Engines ist es z.b. so:

$tpl->assign('sfTemplate', $sfTemplate);

Und schon kann ich die Variable im Template benutzen.
Ich habe aber keine Ahnung wie die das genau lösen.

Allerdings wollte ich das ursprünglich extra nur mittels include machen, da ich so auf bereits vorhandene Variablen zugreifen kann und diese nicht extra noch einmal übergeben muss.
 
Also, ich glaube nicht, dass es irgendeine Magic gibt, mit der du auf die Variablen aus dem aufrufenden Scope zugreifen kannst.

Ich halte es aber ohnehin für sinnvoller, diesen expliziten Schritt zur Übergabe von Werten an Templates zu haben, weil dann im Code ersichtlich ist, welche Variablen im Template genutzt werden oder genutzt werden können.

Du kannst etwa alles, was nachher im Template genutzt werden soll, in der aufrufenden Funktion/Methode in ein assoziatives Array $vars oder so speichern und dann zum Beispiel so was machen:

PHP:
$t = new Template();
$html = $t->render('template.phtml', $vars);

Das ist nicht so wahnsinnig umständlich.

Ausführliches Beispiel:

PHP:
class Template
{
    private $assignedVars;

    public function __construct()
    {
        $this->clear();
    }

    public function assign(array $pairs)
    {
        foreach ($pairs as $key => $value) {
            $this->assignedVars[$key] = $value;
        }
    }

    public function clear()
    {
        $this->assignedVars = array();
    }

    public function render($tplFile, array $assignments = array())
    {
        $this->assign($assignments);

        $closure = function ($__tplFile, array $__vars) {
            extract($__vars);
            require $__tplFile;
        };

        // Will make $this unavailable in included code
        $contextlessClosure = $closure->bindTo(null);

        ob_start();

        $contextlessClosure($tplFile, $this->assignedVars);

        return ob_get_clean();
    }
}

demo.phtml:

PHP:
<h1><?=$name?></h1>

<p>Folgende Variablen sind hier gesetzt:</p>

<pre><?php print_r(get_defined_vars()); ?></pre>

Aufruf:

PHP:
$t = new Template();

$t->assign(array('age' => 30));

echo $t->render(__DIR__ . '/demo.phtml', array(
    'name' => 'Lucas Barrios'
));

Ausgabe:

Code:
<h1>Lucas Barrios</h1>

<p>Folgende Variablen sind hier gesetzt:</p>

<pre>Array
(
    [__tplFile] => /home/marc/www/fiddle/demo.phtml
    [__vars] => Array
        (
            [age] => 30
            [name] => Lucas Barrios
        )

    [age] => 30
    [name] => Lucas Barrios
)
</pre>

PS: Es hat definitiv auch Vorteile, $this zu nutzen (siehe render-Methode). Du kannst etwa eine allgemeine escape-Methode (htmlspecialchars) in der Template-Klasse ablegen, auf die dann im Template mit $this->escape() zugegriffen werden kann. Ich habe das $this nur mal rausgeworfen, um zu zeigen, dass das möglich ist, und weil ich das gerade teilweise aus einem Projekt rauskopiert habe, in dem ich das so brauchte. (Da habe ich in jedes Template explizit ein Objekt/eine Variable $api reingereicht, über die dann auf allgemeine Funktionen zugegriffen werden kann.)
 
Zuletzt bearbeitet:

Neue Beiträge

Zurück