Fatal error: Using $this when not in object context

MsWord

Mitglied
Hallo,

ich habe Probleme mit meinem Template System.

Er gibt folgenden Fehler aus:
Fatal error: Using $this when not in object context in [...]/template.class.php on line 255

Hier mal die komplette Klasse:
PHP:
<?php
class Template {
    /**
     * Der Ordner in dem sich die Templates befinden.
     *
     * @access    private
     * @var       string
     */
    private $templateDir = "styles/default/tpl/";

    /**
     * Der Ordner in dem sich die Sprach-Dateien befinden.
     *
     * @access    private
     * @var       string
     */
    private $languageDir = "expand/litetemplate/languages/";

    /**
     * Der linke Delimter für einen Standard-Platzhalter.
     *
     * @access    private
     * @var       string
     */
    private $leftDelimiter = '{$';

    /**
     * Der rechte Delimter für einen Standard-Platzhalter.
     *
     * @access    private
     * @var       string
     */
    private $rightDelimiter = '}';

    /**
     * Der linke Delimter für eine Funktion.
     *
     * @access    private
     * @var       string
     */
    private $leftDelimiterF = '{';

    /**
     * Der rechte Delimter für eine Funktion.
     *
     * @access    private
     * @var       string
     */
    private $rightDelimiterF = '}';

    /**
     * Der linke Delimter für ein Kommentar.
     * Sonderzeichen müssen escapt werden, weil der Delimter in einem regulärem
     * Ausdruck verwendet wird.
     *
     * @access    private
     * @var       string
     */
    private $leftDelimiterC = '\{\*';

    /**
     * Der rechte Delimter für ein Kommentar.
     * Sonderzeichen müssen escapt werden, weil der Delimter in einem regulärem
     * Ausdruck verwendet wird.
     *
     * @access    private
     * @var       string
     */
    private $rightDelimiterC = '\*\}';

    /**
     * Der linke Delimter für eine Sprachvariable
     * Sonderzeichen müssen escapt werden, weil der Delimter in einem regulärem
     * Ausdruck verwendet wird.
     *
     * @access    private
     * @var       string
     */
    private $leftDelimiterL = '\{L_';

    /**
     * Der rechte Delimter für eine Sprachvariable
     * Sonderzeichen müssen escapt werden, weil der Delimter in einem regulärem
     * Ausdruck verwendet wird.
     *
     * @access    private
     * @var       string
     */
    private $rightDelimiterL = '\}';

    /**
     * Der komplette Pfad der Templatedatei.
     *
     * @access    private
     * @var       string
     */
    private $templateFile = "";

    /**
     * Der komplette Pfad der Sprachdatei.
     *
     * @access    private
     * @var       string
     */
    private $languageFile = "";

    /**
     * Der Dateiname der Templatedatei.
     *
     * @access    private
     * @var       string
     */
    private $templateName = "";

    /**
     * Der Inhalt des Templates.
     *
     * @access    private
     * @var       string
     */
    private $template = "";


    /**
     * Die Pfade festlegen.
     *
     * @access    public
     */
    public function __construct($tpl_dir = "", $lang_dir = "") {
        // Template Ordner
        if ( !empty($tpl_dir) ) {
            $this->templateDir = $tpl_dir;
        }

        // Sprachdatei Ordner
        if ( !empty($lang_dir) ) {
            $this->languageDir = $lang_dir;
        }
    }

    /**
     * Eine Templatedatei öffnen.
     *
     * @access    public
     * @param     string $file Dateiname des Templates.
     * @uses      $templateName
     * @uses      $templateFile
     * @uses      $templateDir
     * @uses      parseFunctions()
     * @return    boolean
     */
    public function load($file)    {
        // 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( file_exists($this->templateFile) ) {
                $this->template = file_get_contents($this->templateFile);
            } else {
                return false;
            }
        } else {
           return false;
        }

        // Funktionen parsen
        $this->parseFunctions();
    }

    /**
     * Einen Standard-Platzhalter ersetzen.
     *
     * @access    public
     * @param     string $replace     Name des Platzhalters.
     * @param     string $replacement Der Text, mit dem der Platzhalter ersetzt
     *                                werden soll.
     * @uses      $leftDelimiter
     * @uses      $rightDelimiter
     * @uses      $template
     */
    public function assign($replace, $replacement) {
        $this->template = str_replace( $this->leftDelimiter .$replace.$this->rightDelimiter,
                                       $replacement, $this->template );
    }

    /**
     * Die Sprachdateien öffnen und Sprachvariablem im Template ersetzen.
     *
     * @access    public
     * @param     array $files Dateinamen der Sprachdateien.
     * @uses      $languageFiles
     * @uses      $languageDir
     * @uses      replaceLangVars()
     * @return    array
     */
    public function loadLanguage($files) {
        $this->languageFiles = $files;

        // Versuchen, alle Sprachdateien einzubinden
        for( $i = 0; $i < count( $this->languageFiles ); $i++ ) {
            if ( !file_exists( $this->languageDir .$this->languageFiles[$i] ) ) {
                return false;
            } else {
                 include_once( $this->languageDir .$this->languageFiles[$i] );
                 // Jetzt steht das Array $lang zur Verfügung
            }
        }

        // Die Sprachvariablen mit dem Text ersetzen
        $this->replaceLangVars($lang);

        // $lang zurückgeben, damit $lang auch im PHP-Code verwendet werden kann
        return $lang;
    }

    /**
     * Sprachvariablen im Template ersetzen.
     *
     * @access    private
     * @param     string $lang Die Sprachvariablen.
     * @uses      $template
     */
    private function replaceLangVars($lang) {
        $this->template = preg_replace("/\{L_(.*)\}/isU", "\$lang[strtolower('\\1')]", $this->template);
    }

    /**
     * Includes parsen und Kommentare aus dem Template entfernen.
     *
     * @access    private
     * @uses      $leftDelimiterF
     * @uses      $rightDelimiterF
     * @uses      $template
     * @uses      $leftDelimiterC
     * @uses      $rightDelimiterC
     */
    private function parseFunctions() {
        // Includes ersetzen ( {include file="..."} )
        while( preg_match( "/" .$this->leftDelimiterF ."include file=\"(.*)\.(.*)\""
                           .$this->rightDelimiterF ."/isU", $this->template) )
        {
            function my_callback($a) { 
                return file_get_contents($this->templateDir.$a[1]); 
            } 
            $this->template = preg_replace_callback('/\{include file="([^\"]*)"\}/isU', 'my_callback', $this->template); 
        }


        // Kommentare löschen
        $this->template = preg_replace( "/" .$this->leftDelimiterC ."(.*)" .$this->rightDelimiterC ."/isU", "", $this->template );
    }

    /**
     * Das "fertige Template" ausgeben.
     *
     * @access    public
     * @uses      $template
     */
    public function display() {
        echo $this->template;
    }
}


?>

Wenn ich das richtig verstanden habe, kann er nicht auf $this->templateDir zugreifen oder?
Wann ja, was muss ich anders machen?
 
Ich würde darauf tippen, dass es diese Zeilen hier sind, die den Fehler verursachen:
PHP:
while( preg_match( "/" .$this->leftDelimiterF ."include file=\"(.*)\.(.*)\"" .$this->rightDelimiterF ."/isU", $this->template) )
{
  function my_callback($a) {
    return file_get_contents($this->templateDir.$a[1]);
  }
  $this->template = preg_replace_callback('/\{include file="([^\"]*)"\}/isU', 'my_callback', $this->template);
}
Das Problem ist, dass Du die Funktion my_callback zwar im Klassenkontext definierst, es aber dennoch eine stinknormale Funktion (nicht Methode!) bleibt. Die Lösung wäre, wenn Du den Wert der Instanzenvariablen in eine andere Variable schreibst und dann auf diese zugreifst. Außerdem solltest Du Dir noch einmal überlegen, ob Du die eine Funktion immer und immer wieder definieren willst, denn spätestens beim zweiten Aufruf erzeugt auch das einen Fehler. Besser wäre es so:
PHP:
$pattern1  = '/' . $this->leftDelimiterF . 'include file="(.*)\.(.*)"' . $this->rightDelimiterF . '/isU';
$pattern2  = '/\{include file="([^"]*)"\}/isU';
$directory = $this->templateDir;
$callback  = function ( $a ) use ( $directory ) {
  return file_get_contents( $directory . $a[ 1 ] );
};

while ( preg_match( $pattern1, $this->template ) ) {
  $this->template = preg_replace_callback( $pattern2, $callback, $this->template );
}
 
Zuletzt bearbeitet:
Danke dir.

Leider kommt jetzt folgende Meldung:
Warning: file_get_contents(styles/default/tpl/ Header einbinden ): failed to open stream: No such file or directory in [...]/expand/litetemplate/template.class.php on line 254

Warning: file_get_contents(styles/default/tpl/ Body einbinden ): failed to open stream: No such file or directory in [...]/expand/litetemplate/template.class.php on line 254

Warning: file_get_contents(styles/default/tpl/ Footern einbinden ): failed to open stream: No such file or directory in [...]/expand/litetemplate/template.class.php on line 254

Fatal error: Maximum execution time of 15 seconds exceeded in [...]/expand/litetemplate/template.class.php on line 257
 
Zurück