经典代码

共同探讨asp,php等好代码搜集

« php 代码优化方法哈哈大家都说今晚6.3号地震 »

php模板解析类很不错

很简单的一个php轻量级模板解析类。速度很快官方网站http://www.phpguru.org/
<?php

    /**
    * This is (yet) another templating class for PHP5. Called Bob. No real reason for the name.
    *
    * $tpl = new Bob('myTemplate.html'); // Defaults to current directory
    * $tpl->debug = 1;
    * $tpl->Display();
    *
    * If you're having trouble, thes first thing to do is turn off caching -
    * it will only confuse you. And at the same time turn on debug messages.
    * You can do these by using:
    *
    * $tpl->useCache = false;
    * $tpl->debug    = true;
    */
   
    /**
    * The template class
    */
    class Bob
    {
        /**
        * Show or hide debug messages
        */
        public $debug = false;
       
        /**
        * Whether to use the cache or not
        */
        public $useCache = true;
       
        /**
        * The path to store cached templates in
        */
        public $cachePath = '/tmp';
       
        /**
        * The variables
        */
        private $variables;

        /**
        * The constructor
        *
        * @param string $template The name of the template to use
        */
        public function __construct($template)
        {
            $this->template = $template;
            $this->timings['start'] = microtime();
            $this->Debug('Template filename: ' . $template);
        }
       
        /**
        * Sets the path to store cached templates
        */
        public function SetCachePath($path)
        {
            $this->cachePath = $path;
            $this->Debug('Using cache path: ' . $path);
        }
       
        /**
        * The callback handler for dynamic {php ...} blocks
        *
        * @param array $matches The matches found by the regex
        */
        public function phpCallbackHandler($matches)
        {
            eval('$result = ' . $matches[1] . ';');
            return $result;
        }

        /**
        * The callback for handling if conditions
        *
        * @param array $matches The matches found by the regex
        */
        public function ifCallbackHandler($matches)
        {//处理模板里的嵌套if结构,只能处理简单的if
    
            if (!empty($this->variables[trim($matches[1])])) {
                  return $matches[2];
             } elseif (!empty($matches[3])) {
     
                return $matches[3];

            } else {
                return '';
            }
        }

        /**
        * The callback for handling inclusions
        *
        * @param array $matches The matches found by the regex
        */
        private function incCallbackHandler($matches)
        {//处理模板里的include结构。把里边的include文件用file_get_contents获得,然后替换
            $filename = trim($matches[1]);
            $output   = file_exists($filename) ? file_get_contents($filename) : '<p style="color: red; font-weight: bold">File does not exist: ' . $filename . '</p>';
           
            return $output;
        }
       
        /**
        * Callback for handling plugin calls. A bit redundant because of the {php ...} tag, but hey ho
        */
        private function pluginCallbackHandler($matches)
        {//处理简单的标签直接返回替换内容
            return $matches[1]();
        }
       
        /**
        * Displays the template
        */
        public function Display()
        {//显示替换内容主要函数是一个替换递归函数preg_replace_callback
            /**
            * Try and get the template from the cache if it's there
            */
            $filename        = str_replace('//', '/', $this->template);
            $cached_filename = $this->getCacheFileName($filename);

            $this->Debug('Cached template filename: ' . $cached_filename);
            $this->Debug('Request cache control header: <span style="color: blue">Cache-Control: ' . @$_SERVER['HTTP_CACHE_CONTROL'] . '</span>');

            /**
            * Show the cached template. Depending on the browser and how the page was requested will control the
            * Cache-Control header that the the browser sends:
            *
            * Internet Explorer
            * =================
            * Normally cached. Hold down the CTRL key and CLICK refresh to get a fresh copy.
            *
            * Firefox
            * =======
            * Normally cached when the page is retrieved by following a link. If you hit refresh, you'll get a fresh copy.
            * Simple as that.
            *
            * Opera
            * =====
            * Seems to always request a fresh copy. Can't figure this browser out. Maybe it's something to do with my settings -
            * just don't know.
            *
            * So the moral is... always use IE :-)
            */
            if (    $this->useCache
                AND file_exists($cached_filename)
                AND filemtime($filename) <= filemtime($cached_filename)
                AND $contents = file_get_contents($cached_filename)
                AND @$_SERVER['HTTP_CACHE_CONTROL'] != 'no-cache'
                AND @$_SERVER['HTTP_CACHE_CONTROL'] != 'max-age=0') {
               
                echo $contents;
                $this->timings['end'] = microtime();
               
                /**
                * And show the amount of time taken
                */
                if ($this->debug) {
                    $this->Debug('Using cached template file: ' . $cached_filename);
                    $this->ShowDebugInformation();
                }

                return;
            }
           
            /**
            * Debug caching information
            */
            $this->Debug('Server side template caching is ' . ($this->useCache ? 'on' : 'off') );
           
            /**
            * Generate the template and show it
            */
            $output = file_get_contents(str_replace('//', '/', $filename));

            /**
            * Handle conditionals (ie if/else) If conditions cannot be nested
            */
            $output = preg_replace_callback('/{if ([^}]*)}(.*)(?:{else}([^}]*))?{\/if}/Uis', array($this, 'ifCallbackHandler'), $output);
            /**
            * This does straight replacement of include calls
            */
            $output = preg_replace_callback('/{include ([^}]+)}/is', array($this, 'incCallbackHandler'), $output);

            /**
            * Handle loops
            */
            foreach ($this->variables as $k => $var) {
                if (is_array($var) OR is_object($var)) {
                    if (preg_match('/{foreach\s+\$?[a-z0-9_]+\s*}(.*){\/foreach}/Uis', $output, $matches)) {

                        $table =  '';

                        foreach ($var as $value) {

                            $replacement = $matches[1];

                            foreach ($value as $a => $b) {
                                $replacement = preg_replace('/{' . $a . '}/i', $b, $replacement);
                            }

                            $table .= $replacement;
                        }

                        $output = str_replace($matches[1], $table, $output);
                    }
                } else {
                    $output = str_replace('{' . $k . '}', $var, $output);
                }
            }
           
            /**
            * Replace any {php: ...} blocks by executing whatever it is and using the return value as the replacement
            */
            $output = preg_replace_callback('/\{php (.*)\}/i', array($this, 'phpCallbackHandler'), $output);

            /**
            * Send the output to the browser
            */
            $output = preg_replace('/[^\\\\]{.*[^\\\\]}/i', '', $output);
            $output = str_replace(array('\\{', '\\}'), array('{', '}'), $output);

            echo $output;
           

            /**
            * Save the generated content to the cache, remembering to set the modified time appropriately
            */
            if ($this->useCache) {
                $filename = $this->getCacheFilename();
                $this->Debug('Saving output to: ' . $filename);
                file_put_contents($filename, $output);
               
                // Update the timestamp
                touch($filename, time());
            }
           
            /**
            * And show the amount of time taken
            */
            if ($this->debug) {
                /**
                * Store the end time
                */
                $this->timings['end'] = microtime();

                $this->ShowDebugInformation();
            }
        }
       
        /**
        * Outputs debug message
        *
        * @param string $msg The debug message
        */
        private function Debug($msg)
        {//显示调试信息
            $this->debugMessages[] = nl2br(str_replace(' ', '&nbsp;', $msg));
        }
       
        /**
        * Returns a cache filename based on the given filename
        */
        private function getCacheFileName()
        {
             return preg_replace('/\/+/', '/', ($this->cachePath ? $this->cachePath . '/template_' : '') . md5($this->template . serialize($this->variables))) . '.html';
        }
       
        /**
        * Reads the template file
        */
        private function readTemplate()
        {
            return file_exists($cached_filename) ? file_get_contents($filename) : false;
        }
       
        /**
        * Sets a variable, be it singular or complex
        *
        * @param string $name  The name of the variable
        * @param mixed  $value The value of the variable
        */
        public function Set($name, $value)
        {
            $this->Debug("Setting variable: {$name}=" . print_r($value, true));
            $this->variables[$name] = $value;
        }
       
        /**
        * Shows the debug information
        */
        public function ShowDebugInformation()
        {
            $this->Debug(sprintf('Time taken: %02.5fs', array_sum(explode(' ', $this->timings['end'])) - array_sum(explode(' ', $this->timings['start']))));
            printf('<div id="template_debug">Debug window<br /><br />%s</div>', implode("<br />\r\n", $this->debugMessages));
        }
    }
?>
下边是调用的例子
<?php
    /**
    * Test the template class
    */
    require_once('bob.class.php');
   
    /**
    * A plugin handler
    */
    function myPlugin()
    {
        return 'This is an example PHP block that returns the title';
    }

    /**
    * This is some example data. It's a 2d array, indexed first numerically, and then by "column name".
    * Just like the structure returned by the PEAR::DB getAll method.
    */
    $fredriko[0]['first']  = 'fred';       $fredriko[1]['first']  = 'barney'; $fredriko[2]['first']  = 'Riko';  $fredriko[3]['first']  = 'Orvill';
    $fredriko[0]['second'] = 'Barney';     $fredriko[1]['second'] = 'Jim';    $fredriko[2]['second'] = 'life';  $fredriko[3]['second'] = 'Juniper';
    $fredriko[0]['third']  = 'time lucky'; $fredriko[1]['third']  = 'Joon';   $fredriko[2]['third']  = 'Hop';   $fredriko[3]['third']  = 'Thing';
    $fredriko[0]['fourth'] = 'Orvill';     $fredriko[1]['fourth'] = 'Joomla'; $fredriko[2]['fourth'] = 'Goa';   $fredriko[3]['fourth'] = 'King';
    $fredriko[0]['fifth']  = 'Loop';       $fredriko[1]['fifth']  = 'Kid';    $fredriko[2]['fifth']  = 'Funky'; $fredriko[3]['fifth']  = 'Flop';

    /**
    * Create the template object
    */
    $tpl = new Bob('example.html');
    $tpl->debug =0;//0是不显示调试信息,1是显示

    /**
    * The cache
    */
    $tpl->useCache = false;
    $tpl->SetCachePath('/tmp');
   
    /**
    * This produces the counter
    */
     $counter=1; 
    /**
    * Set some variables
    */
    $tpl->Set('ifVar', 1); // Used as the if condition value
    $tpl->Set('myVar', 'A simple string');
    $tpl->Set('title', 'The title');
    $tpl->Set('fredriko', $fredriko);
    $tpl->Set('counter', $counter);
   
    /**
    * Display the template
    */
    $tpl->Display();

 


?>

 

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

日历

最新评论及回复

最近发表

Powered By Z-Blog 1.8 Devo Build 80201 Code detection by Codefense

Copyright 2008-2100 www.codemdb.com. Some Rights Reserved.