-1

Question 1) Why is the Variable/variable $this->$template not visible to parse_and_return(), lines 42-50, but visible to $this->fetch, lines 456-472. I thought parse_and_return and $this->fetch belong to the same object, therefore $this->$template should be visible to both functions.
Question 2) Where is $this->$template initialized?

bar.tpl & foo.tpl are separate files

    <!-- bar.tpl -->
    <HTML>
    <HEAD><TITLE>Feature world - {PAGETITLE}</TITLE></HEAD>
    <BODY BGCOLOR=BLACK TEXT=WHITE>
    <H1>{PAGETITLE}</H1>
    {PAGECONTENT}
    </BODY>
    </HTML> 
    -->

    <!--
    foo.tpl 

    This does not do anything obvious. Please look at {NAME}.
    demo.php3
    -->

index.php file

<?php

include "FastTemplate.php";

$tpl = new FastTemplate(".");
$tpl->define(array(foo => "foo.tpl", bar => "bar.tpl"));

$tpl->assign(NAME, "me");
$tpl->assign(PAGETITLE, "Welcome!");


$tpl->parse(PAGECONTENT, "foo"); 

echo $tpl->parse_and_return("bar");

?>

The FastTemplate Class / FastTemplate.php file

        <?php

        class FastTemplate {

                var $start;

                var $ERROR = "";

                var $LAST = "";

                var $ROOT = "";

                var $FILELIST = array ( );

                var $PARSEVARS = array ( );

                var $LOADED = array ( );

                var $HANDLE = array ( );

                var $UPDT_TIME = '60';

                var $COMMENTS_START = "{*";

                var $COMMENTS_END = "*}";

                var $PATTERN_VARS_VARIABLE = array ( );

                var $PATTERN_VARS_DEFINE = array ( );

                FUNCTION FastTemplate($pathToTemplates = "") {

                    if (! empty ( $pathToTemplates )) {

                         $this->set_root ( $pathToTemplates );

                    }

                    $this->start = $this->utime (); 
                } 

                FUNCTION parse_and_return($tpl_name) {

                    $HREF = 'TPL';
                    $this->parse ( $HREF, $tpl_name );
                    $result = trim ( $this->fetch ( $HREF ) );
                    $this->clear_href ( $HREF );
                    RETURN $result;

                }

                FUNCTION set_root($root) {

                    $trailer = substr ( $root, - 1 );

                         if ((ord ( $trailer )) != 47) {
                             $root = "$root" . chr ( 47 );
                         }

                         if (is_dir ( $root )) {
                             $this->ROOT = $root;
                         } else {
                             $this->ROOT = "";
                             $this->error ( "dir [$root] is not a directory" );
                         }

                } 

                FUNCTION get_root() {

                    RETURN $this->ROOT;

                } 

                FUNCTION utime() {
                    $time = explode ( " ", microtime () );
                    $usec = ( double ) $time [0];
                    $sec = ( double ) $time [1];
                    RETURN $sec + $usec;
                } 

                FUNCTION get_template($template) {

                    if (empty ( $this->ROOT )) {
                     $this->error ( "Root not valid.", 1 );
                     RETURN FALSE;
                    }
                    if (empty ( $template )) {
                     $this->error ( "Template name is empty.", 1 );
                     RETURN FALSE;
                    };
                    $filename = "$this->ROOT" . "$template";

                    $contents = ((function_exists ( 'file_get_contents' ))) ? file_get_contents ( $filename ) : implode ( "\n", file ( $filename ) );

                     RETURN trim ( $contents );

                } 

                FUNCTION parseParamString($string) {

                            $matches=array();
                            if (preg_match_all ( '/\{([a-z0-9_]+)\}/i', $string, $matches )) {

                                    FOR($i = 0; $i < count ( $matches [0] ); $i ++) {
                                            $string = str_replace ( $matches [0] [$i], $this->PARSEVARS [$matches [1] [$i]], $string );
                                    }

                            }
                            RETURN $string;
                }

                FUNCTION value_defined($value, $field = '', $params = '') {

                    $var = $this->PARSEVARS [$value];

                    if ($field {0} == '.') {

                         $field = substr ( $field, 1 );

                    }

                    # echo "$value, $field, $params <BR>";
                    if (is_object ( $var )) {

                         if (method_exists ( $var, $field )) {

                             eval ( '$return = $var->' . $field . '(' . $this->parseParamString ( $params ) . ');' );
                             RETURN ((! empty ( $return )) || ($return === TRUE));

                         } ELSEif ((strcasecmp ( $field, 'id' ) != 0) && method_exists ( $var, 'get' )) {

                             $result = $var->get ( $field );
                             RETURN (! empty ( $result ) || $result === TRUE);

                         } ELSEif ((strcasecmp ( $field, 'id' ) == 0) && method_exists ( $var, 'getId' )) {

                             $result = $var->getId ();
                             RETURN (! empty ( $result ) || $result === TRUE);

                         }

                    } else {

                     RETURN (! empty ( $var ) || $var === TRUE);

                    }

                }

                FUNCTION parse_defined($template) {

                    $lines = split ( "\n", $template );
                    $newTemplate = "";
                    $ifdefs = FALSE;
                    $depth = 0;
                    $needparsedef [$depth] ["defs"] = FALSE;
                    $needparsedef [$depth] ["parse"] = TRUE;

                    WHILE ( list ( $num, $line ) = each ( $lines ) ) {

                         if (((! $needparsedef [$depth] ["defs"]) || ($needparsedef [$depth] ["parse"])) && (strpos ( $line, "IFDEF:" ) === FALSE) && (strpos ( $line, "IFNDEF:" ) === FALSE) && (strpos ( $line, "ELSE" ) === FALSE) && (strpos ( $line, "ENDIF" ) === FALSE)) {

                         $newTemplate .= trim ( $line ) . "\n";

                         }

                         if (preg_match ( "/<!--\s*IFDEF:\s*([a-zA-Z_][a-zA-Z0-9_]+)(\.|\-\>)?([a-zA-Z_][a-zA-Z0-9_]+)?\(?(\s*\,?\".*\"\s*\,?|\s*\,?[a-z0-9\_]*\s*\,?)\)?\s*-->/i", $line, $regs )) {

                                 $depth ++;
                                 $needparsedef [$depth] ["defs"] = TRUE;

                                 if ($this->value_defined ( $regs [1], $regs [3], $regs [4] )){

                                     $needparsedef [$depth] ["parse"] = $needparsedef [$depth - 1] ["parse"]; 

                                 }else{

                                     $needparsedef [$depth] ["parse"] = FALSE;

                                 }

                         }

                         if (preg_match ( "/<!--\s*IFNDEF:\s*([a-zA-Z_][a-zA-Z0-9_]+)(\.|\-\>)?([a-zA-Z_][a-zA-Z0-9_]+)?\(?(\s*\,?\".*\"\s*\,?|\s*\,?[a-z0-9\_]*\s*\,?)\)?\s*-->/i", $line, $regs )) {

                             $depth ++;
                             $needparsedef [$depth] ["defs"] = TRUE;

                         }
                         if (! $this->value_defined ( $regs [1], $regs [3], $regs [4] )){

                             $needparsedef [$depth] ["parse"] = $needparsedef [$depth - 1] ["parse"]; 

                         }else{

                             $needparsedef [$depth] ["parse"] = FALSE;}

                         }

                        // ELSE block
                        if (preg_match ( "/<!--\s*ELSE\s*-->/i", $line )) {

                             if ($needparsedef [$depth] ["defs"]){

                                 $needparsedef [$depth] ["parse"] = (! ($needparsedef [$depth] ["parse"]) & $needparsedef [$depth - 1] ["parse"]);

                             }

                             if (preg_match ( "/<!--\s*ENDIF\s*-->/i", $line )) {

                                 $needparsedef [$depth] ["defs"] = FALSE;
                                 $depth --;

                             }
                        }

                    if ($depth){

                     $this->error ( 'Some nonclosed IDEFS blocks', 0 );

                    }
                    RETURN $newTemplate;
                }

                FUNCTION parse_template($template, $ft_array) {

                    $matches=array();

                    if (preg_match_all ( '/\{([a-zA-Z_][a-zA-Z0-9_]+)(\.|\-\>)([a-zA-Z_][a-zA-Z0-9_]+)\(?(\s*\,?\".*?\"\s*\,?|\s*\,?[a-z0-9\_]*\s*\,?)\)?\}/i', $template, $matches )) {

                         FOR($i = 0; $i < count ( $matches [0] ); ++ $i) {

                             $obj = $ft_array [$matches [1] [$i]];

                             if ((is_object ( $obj ) && method_exists ( $obj, $matches [3] [$i] ))) {

                                 eval ( '$return = $obj->' . $matches [3] [$i] . '(' . $this->parseParamString ( $matches [4] [$i] ) . ');' );
                                 $template = str_replace ( $matches [0] [$i], $return, $template );

                             } else if (is_object ( $obj ) && ($matches [3] [$i] == 'id') && method_exists ( $obj, 'getId' )){

                                 $template = str_replace ( $matches [0] [$i], $obj->getId (), $template ); 

                             }else if (is_object ( $obj ) && method_exists ( $obj, 'get' )){

                             $template = str_replace ( $matches [0] [$i], $obj->get ( $matches [3] [$i] ), $template ); }else if (! is_object ( $obj )){
                                 $template = str_replace ( $matches [0] [$i], '', $template );

                             }

                         } //end for loop
                    } //end if 


                    if (preg_match_all ( '/<\!\-\-\s*#include\s+file="([\{\}a-zA-Z0-9_\.\-\/]+)"\s*\\-\->/i', $template, $matches )) {

                         FOR($i = 0; $i < count ( $matches [0] ); $i ++) {

                             $file_path = $matches [1] [$i];

                             FOREACH ( $ft_array as $key => $value ) {

                                 if (! empty ( $key )) {

                                     $key = '{' . "$key" . '}';
                                     $file_path = str_replace ( "$key", "$value", "$file_path" );

                                 }

                             } //foreach

                             $content = '';

                             if (! isset ( $ft_array [$file_path] )) {

                                 if (! file_exists ( $file_path )){

                                    $file_path = $this->ROOT . $file_path;

                                 }

                                 if (! file_exists ( $file_path )){

                                    $file_path = $this->ROOT . basename ( $file_path );

                                 }

                                 if (file_exists ( $file_path )) {

                                    $content = ((function_exists ( 'file_get_contents' ))) ? file_get_contents ( $file_path ) : implode ( "\n", file ( $file_path ) );

                                 } else {

                                    $content = '';

                                 }
                             } else {

                                 $content = $ft_array [$file_path];
                                 $template = str_replace ( $matches [0] [$i], $content, $template );

                             }
                         } //for
                    } //end preg_match_all

                    reset ( $ft_array );

                    WHILE ( list ( $key, $val ) = each ( $ft_array ) ) {

                         if (! (empty ( $key ))) {

                             if (gettype ( $val ) != "string") {

                                 settype ( $val, "string" );

                             }

                             $key = '{' . "$key" . '}'; 
                             $template = str_replace ( "$key", "$val", "$template" ); 

                         }

                    }


                    $template = ereg_replace ( "{([A-Za-z0-9_\.]+)}", "", $template ); 

                    $template = preg_replace ( "/(<!--\s*IFDEF:\s*([a-zA-Z_][a-zA-Z0-9_]+)(\.|\-\>)?([a-zA-Z_][a-zA-Z0-9_]+)?\(?(\s*\,?\".*?\"\s*\,?|\s*\,?[a-z0-9\_]*\s*\,?)\)?\s*-->)/i", "\n$0\n", $template );
                    $template = preg_replace ( "/(<!--\s*IFNDEF:\s*([a-zA-Z_][a-zA-Z0-9_]+)(\.|\-\>)?([a-zA-Z_][a-zA-Z0-9_]+)?\(?(\s*\,?\".*?\"\s*\,?|\s*\,?[a-z0-9\_]*\s*\,?)\)?\s*-->)/i", "\n$0\n", $template );
                    $template = preg_replace ( "/(<!--\s*ELSE\s*-->)/i", "\n\\0\n", $template );
                    $template = preg_replace ( "/(<!--\s*ENDIF\s*-->)/i", "\n\\0\n", $template );

                     WHILE ( list ( $num, $line ) = each ( $lines ) ) {

                        if (! $inside_block) {

                            $template .= "$line\n";

                        }

                    }
                    $template = $this->parse_defined ( $template );

                    RETURN $template;
                } 

                FUNCTION parse($ReturnVar, $FileTags) {

                    FOREACH ( $this->PATTERN_VARS_DEFINE as $value ){

                         $this->multiple_assign_define ( "$value" );

                    }

                    FOREACH ( $this->PATTERN_VARS_VARIABLE as $value ){

                         $this->multiple_assign ( "$value" );

                    }

                    $append = FALSE;
                    $this->LAST = $ReturnVar;
                    $this->HANDLE [$ReturnVar] = 1;

                    if (gettype ( $FileTags ) == "array") {

                         unset ( $this->$ReturnVar ); 

                         WHILE ( list ( $key, $val ) = each ( $FileTags ) ) {

                             if ((! isset ( $this->$val )) || (empty ( $this->$val ))) {

                                 $this->LOADED ["$val"] = 1;
                                 $fileName = $this->FILELIST ["$val"];
                                 $this->$val = $this->get_template ( $fileName );

                             }

                             $this->$ReturnVar = $this->parse_template ( $this->$val, $this->PARSEVARS );
                             //  For recursive calls.
                             $this->assign ( array ($ReturnVar => $this->$ReturnVar ) );
                         }

                    } else {

                        $val = $FileTags;

                        if ((substr ( $val, 0, 1 )) == '.') {

                            $append = TRUE;
                            $val = substr ( $val, 1 );

                        }

                        if ((! isset ( $this->$val )) || (empty ( $this->$val ))) {

                            $this->LOADED ["$val"] = 1;
                            $fileName = $this->FILELIST ["$val"];
                            $this->$val = $this->get_template ( $fileName );

                        }

                        if ($append) {

                            if (isset ( $this->$ReturnVar )) {

                                $this->$ReturnVar .= $this->parse_template ( $this->$val, $this->PARSEVARS );

                            } else {

                                $this->$ReturnVar = $this->parse_template ( $this->$val, $this->PARSEVARS );

                            }

                        } else {

                            $this->$ReturnVar = $this->parse_template ( $this->$val, $this->PARSEVARS );

                        }

                        $this->assign ( array ($ReturnVar => $this->$ReturnVar ) );

                    }
                    RETURN;
                }

                FUNCTION getfast($template = "") {

                    if (empty ( $template )) {

                        $template = $this->LAST;

                    }

                    // "$this->$template" not initialize here!
                    if ((! (isset ( $this->$template ))) || (empty ( $this->$template ))) {

                         $this->error ( "Nothing parsed, nothing printed", 0 );

                         RETURN;

                    } else {

                         if (! get_magic_quotes_gpc ()){

                             $this->$template = stripslashes ( $this->$template );

                         }

                         RETURN $this->$template;

                    }
                } 

                FUNCTION fetch($template = "") {

                    if (empty ( $template )) {

                         $template = $this->LAST;

                    }

                    if ((! (isset ( $this->$template ))) || (empty ( $this->$template ))) {

                         $this->error ( "Nothing parsed, nothing printed", 0 );
                         RETURN "";

                    }

                    RETURN ($this->$template);
                }

                FUNCTION define($fileList, $value = null) {

                    if ((gettype ( $fileList ) != "array") && ! is_null ( $value )){

                     $fileList = array ($fileList => $value );

                    }

                    WHILE ( list ( $FileTag, $FileName ) = each ( $fileList ) ) {

                         $this->FILELIST ["$FileTag"] = $FileName;

                    }
                    RETURN TRUE;
                }

                FUNCTION clear_href($href) {

                    if (! empty ( $href )) {

                         if ((gettype ( $href )) != "array") {

                                 unset ( $this->PARSEVARS [$href] );
                                 RETURN;

                         } else {

                            FOREACH ( $href as $value ){

                                    unset ( $this->PARSEVARS [$value] );
                                    RETURN;

                            }

                         }

                    } else {

                         // Empty - clear them all
                         $this->clear_assign ();

                    }

                    RETURN;
                }

                FUNCTION clear_assign() {

        if (! (empty ( $this->PARSEVARS ))) {

            WHILE ( list ( $Ref, $Val ) = each ( $this->PARSEVARS ) ) {

                unset ( $this->PARSEVARS ["$Ref"] );

            }
        }

                }

                FUNCTION assign_from_array($Arr, $Keys) {

                    if (gettype ( $Arr ) == "array") {

                         foreach ( $Keys as $k ){

                            if (! empty ( $k )){

                               $this->PARSEVARS [strtoupper ( $k )] = str_replace ( '&amp;#', '&#', $Arr [$k] );

                            }

                         }
                    }
                }

                FUNCTION assign($ft_array, $trailer = "") {

                    if (gettype ( $ft_array ) == "array") {

                         WHILE ( list ( $key, $val ) = each ( $ft_array ) ) {

                             if (! (empty ( $key ))) {

                                 if (! is_object ( $val )){

                                     $this->PARSEVARS ["$key"] = str_replace ( '&amp;#', '&#', $val );

                                 } else{

                                     $this->PARSEVARS ["$key"] = $val; 

                                 }

                            }

                         }

                    } else {

                         if (! empty ( $ft_array )) {

                             if (! is_object ( $trailer )){

                                $this->PARSEVARS ["$ft_array"] = str_replace ( '&amp;#', '&#', $trailer ); 

                             }else{

                                $this->PARSEVARS ["$ft_array"] = $trailer; 

                             }
                         }

                    }
                }

                FUNCTION get_assigned($ft_name = "") {

                    if (empty ( $ft_name )) {

                        RETURN FALSE;

                    }

                    if (isset ( $this->PARSEVARS ["$ft_name"] )) {

                        RETURN ($this->PARSEVARS ["$ft_name"]);

                    } else {

                     RETURN FALSE;

                    }

                }

                FUNCTION error($errorMsg, $die = 0) {

                        $this->ERROR = $errorMsg;
                        echo "ERROR: $this->ERROR <BR> \n";

                    if ($die == 1) {

                        exit ();

                    }
                    RETURN;
                } 

                FUNCTION multiple_assign($pattern) {

                    WHILE ( list ( $key, $value ) = each ( $GLOBALS ) ) {

                        if (substr ( $key, 0, strlen ( $pattern ) ) == $pattern) {

                           $this->assign ( strtoupper ( $key ), $value );

                        }
                    }
                    reset ( $GLOBALS );

                } 

                FUNCTION multiple_assign_define($pattern) {

                    $ar = get_defined_constants ();

                    FOREACH ( $ar as $key => $def ){

                         if (substr ( $key, 0, strlen ( $pattern ) ) == $pattern){

                             $this->assign ( strtoupper ( $key ), $def );

                         }

                    }

                } 

        } // End Class

    ?>
mmtalon
  • 47
  • 7
  • please fix question subject –  Mar 03 '16 at 04:02
  • Dagon, Please help. What is needed to fix the question subject? All I really want is for someone to tell me why the variable "$this->$template" is not visible from the caller function(parse_and_return) and is visible to the called function(fetch). – mmtalon Mar 04 '16 at 05:26

1 Answers1

0

Answer to my first question:

There are two reasons why the variable “$this->$template” is not visible to the parse_and_return();

Reason 1: The “$this->$template” variable points to an instance variable $TPL of the FastTemplate class that does not exist until parse() is called. The parse() function parses the bar.tpl file and resolves this file's FastTemplate {VARS}. An instance variable $TPL is created in a FastTemplate object and assigned the bar.tpl file’s contents. The $TPL variable will not be visible to any member function until it is created.

Reason 2: $template is a local variable and $this->$template is a local variable variable; local only to the fetch() function. Because the scope of these variables are local they will generate and error if you try to use them in other member functions. However, once the $TPL instance variable is created you can access its data value from any member function by simply using $this->TPL.

Answer to my second question:

As stated above, “$this->$template” is a local variable variable and refers to the instance variable $TPL that is initialized with the value of the bar.tpl file’s contents. This $TPL variable is initialized near or on lines 382-388, inside the parse() function. The following expression was used to initialize $TPL: “$this->$ReturnVar = $this->parse_template ($this->$val, $this->PARSEVARS )”.

The $ReturnVar variable was the first parameter in parse() function's definition, e.g. FUNCTION parse($ReturnVar, $FileTags). The $ReturnVar variable was passed an argument with a string value of “TPL”. You can now use a variable variable to access a variable’s address, in this case the address of the string “TPL” by using $$ReturnVar. Because “TPL” is an instance variable of a FastTemplate object you must use the pseudo variable “$this->” to access it. Therefore the variable variable is structured as $this->$ReturnVar. This will create the $TPL variable and access its address and assign the address the contents of the bar.tpl file.

Coincidentally in this this example the object is named $tpl but any name could have been used.

Closing comment - It will be my objective to simplify this code by excluding all the variable variables and using a more direct coding approach. It is my opinion that the over use of variable variables (pointers) makes your code convoluted and hard to follow.

mmtalon
  • 47
  • 7