代码之家  ›  专栏  ›  技术社区  ›  ryeguy

模板系统范围问题

  •  3
  • ryeguy  · 技术社区  · 17 年前

    查看类

    class View
    {
        private $_vars=array();
        private $_file;
    
        public function __construct($file)
        {
            $this->_file='views/'.$file.'.php';
        }
    
        public function set($var, $value=null)
        {
            if (is_array($var))
            {
                $this->_vars=array_merge($var, $this->_vars);
            }
            else
                $this->_vars[$var]=$value;
    
            return $this;
        }
    
        public function output()
        {
            if (count($this->_vars))
                extract($this->_vars,  EXTR_REFS);
            require($this->_file);
            exit;
        }
    
        public static function factory($file)
        {
            return new self($file);
        }
    }
    

    <html>
        <body>
            Hey <?=$name?>! This is <?=$adj?>!
            <?=View::factory('embed')->output()?>
        </body>
    </html>
    

    <html>
        <body>
            Hey <?=$name?>! This is an embedded view file!!
        </body>
    </html>
    

    $vars=array(
        'name' => 'ryan',
        'adj' => 'cool'
    );
    View::factory('test')->set($vars)->output();
    

    Hey ryan! This is cool! Hey [error for $name not being defined] 
    this is an embedded view file!!
    

    4 回复  |  直到 13 年前
        1
  •  1
  •   Sean Clark Hess    17 年前

    // Usage
    $main = new SimpleTemplate("templating/html.php");
    $main->extract($someObject);
    $main->extract($someArray);
    $main->name = "my name";
    $subTemplate = new SimpleTemplate("templating/another.php");
    $subTemplate->parent($main);
    $main->placeholderForAnotherTemplate = $subTemplate->run();
    echo $main; // or $main->run(); 
    
    // html.php
    <html><body><h1>Title <?= $name ?></h1><p><?= $placeHolderForAnotherTemplate ?></p></body></html>
    
        <?php
    // SimpleTemplate.php
    function object_to_array($object)
    {
        $array = array();
        foreach($object as $property => $value)
        {
            $array[$property] = $value;
        }
    
        return $array;
    }
    
    class SimpleTemplate
    {
        public $source;
        public $path;
        public $result;
        public $parent;
    
        public function SimpleTemplate($path=false, $source=false)
        {
            $this->source = array();
            $this->extract($source);
            $this->path($path);
        }
    
        public function __toString()
        {
            return $this->run();
        }
    
        public function extract($source)
        {
            if ($source)
            {
                foreach ($source as $property => $value)
                {
                    $this->source[$property] = $value;
                }
            }
        }
    
        public function parent($parent)
        {
            $this->parent = $parent;
        }
    
        public function path($path)
        {
            $this->path = $path;
        }
    
        public function __set($name, $value)
        {
            $this->source[$name] = $value;
        }
    
        public function __get($name)
        {
            return isset($this->source[$name]) ? $this->source[$name] : "";
        }
    
        public function mergeSource()
        {
            if (isset($this->parent))
                return array_merge($this->parent->mergeSource(), $this->source);
            else
                return $this->source;
        }
    
        public function run()
        {
            ob_start();
            extract ($this->mergeSource());
            include $this->path;
            $this->result = ob_get_contents();
            ob_end_clean();
            return $this->result;
        }
    }
    
        2
  •  0
  •   smoove    17 年前

    编辑:我说的是工厂方法

        3
  •  0
  •   zombat    17 年前

    <?=View::factory('embed')->output()?>
    

    通过使嵌入的模板成为父模板的“子模板”,您可以允许它们访问父模板的变量 output()

    $pView = new View_Parent_Class();
    $cView = new View_Child_Class();
    $pView->addView($cView);
    

    $pview->render()

    这种方法可能需要您进行大量的重构,因此我将省略肮脏的细节,并进入第二种方法。

    public function output($extra_vars = null)
    {
        if (count($this->_vars))
            extract($this->_vars,  EXTR_REFS);
        if (is_array($extra_vars)) extract($extra_vars, EXTR_REFS);
        require($this->_file);
        exit;
    }
    

    如果你也添加一个简单的getter方法:

    public function get_vars()
    {
        return $this->_vars;
    }
    

    <?=View::factory('embed')->output($this->get_vars())?>
    

    $this 将引用当前模板,即父模板。请注意,由于以下两个原因,您可能会通过此方法发生变量名冲突 extract

        4
  •  0
  •   Mario    17 年前

    推荐文章