CodeIgniter,如何在发送之前修改缓冲输出

时间:2014-09-05 16:28:14

标签: php codeigniter ob-start

我想在基于Codeigniter的网站中更改输出。

很简单,我想做

$output = str_replace(
    array('ā','ē','ī','ō','ū','Ā','Ē','Ī','Ō','Ū'),
    array('a','e','i','o','u','A','E','I','O','U'),
    $output
)

如果用户喜欢这样的话。

通过阅读这里的问题和答案,我找到了一个可以提供帮助的链接..

https://www.codeigniter.com/user_guide//general/controllers.html#processing-output

..但它只能按控制器控制器,这将重复内容。

有没有办法制作一个钩子呢?

提前致谢!

3 个答案:

答案 0 :(得分:0)

在application / Libraries文件中,您可以制作一个php文件,您可以在其中编写如下内容:

    <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

     class Letterconverter {

        public function convert($value) {

            $before= array('ā','ē','ī','ō','ū','Ā','Ē','Ī','Ō','Ū');
            $after =array('a','e','i','o','u','A','E','I','O','U');
            $value = str_replace($before, $after, $value);
            return $value;
       }
    }

然后你可以从你想要的任何地方把它作为一个图书馆。

答案 1 :(得分:0)

是的,所以你可以在loader类的扩展中编写一个替换值,并将其保存为application / core中的MY_Loader.php。这是一个例子:

<?php

class MY_Loader extends CI_Loader
{
    public function __construct()
    {
        parent::__construct();
    }

    function view($template, $view, $vars = array(), $return = FALSE, $absolute = false)
    {
        /* This seems inferior, but it's the easiest solution
         * if $view is an array then the function is being called with the default CI params, ie:
         * $this->load->view('some_view', $data)
         */
        if(is_array($view)){
            $vars = $view;
            $view = $template;
            $template = false;
        }

        if($template == false){
            parent::view($view, $vars, $return);
        }else{
            if($absolute === true)
            {
                $template_path =  'templates/' . $template . '/' . $view . EXT;

                if(!file_exists('application/views/'.$template_path))
                {
                    show_error('The requested absolute view does not exist: ' . $template_path);
                }

                $template = 'templates/'.$template.'/';
                $view_path = false;
            }
            else
            {
                $template = 'templates/'.$template.'/';
                $template_path = $template . 'template' . EXT;

                if(!file_exists('application/views/'.$template_path))
                {
                    show_error('The requested template does not exist: ' . $template_path);
                }

                $view_path = $template . $view . EXT;

                if(!file_exists('application/views/'.$view_path))
                {
                    show_error('The requested view does not exist: ' . $view_path);
                }
            }

            $template_vars = array();
            $template_vars['tpl_title'] = 'Title Not Defined';
            $template_vars['tpl_meta'] = array();
            $template_vars['tpl_link'] = array();
            $template_vars['tpl_script'] = array();
            $template_vars['tpl_view'] = $view . EXT;

            foreach($vars as $key => $val)
            {
                $template_vars[$key] = $val;
            }

            //$vars = array_merge($vars, $template_vars);

            //include_once($template.'/template_functions' . EXT);

            return $this->_ci_load(array('_ci_view' => $template_path, '_ci_vars' => $this->_ci_object_to_array($template_vars), '_ci_return' => $return));
        }
    }

    // --------------------------------------------------------------------

    /**
     * Loader
     *
     * This function is used to load views and files.
     * Variables are prefixed with _ci_ to avoid symbol collision with
     * variables made available to view files
     *
     * @access  private
     * @param   array
     * @return  void
     */
    function _ci_load($_ci_data)
    {
        if(substr($_ci_data['_ci_view'], 0, 12) != './templates/'){
            parent::_ci_load($_ci_data);
        }else{
            // Set the default data variables
            foreach (array('_ci_view', '_ci_vars', '_ci_path', '_ci_return') as $_ci_val)
            {
                $$_ci_val = ( ! isset($_ci_data[$_ci_val])) ? FALSE : $_ci_data[$_ci_val];
            }

            // Set the path to the requested file
            if ($_ci_path == '')
            {
                $_ci_ext = pathinfo($_ci_view, PATHINFO_EXTENSION);
                $_ci_file = ($_ci_ext == '') ? $_ci_view.EXT : $_ci_view;
                $_ci_path = $_ci_file;
            }
            else
            {
                $_ci_x = explode('/', $_ci_path);
                $_ci_file = end($_ci_x);
            }

            if ( ! file_exists($_ci_path))
            {
                show_error('Unable to load the requested file: '.$_ci_file);
            }

            // This allows anything loaded using $this->load (views, files, etc.)
            // to become accessible from within the Controller and Model functions.
            // Only needed when running PHP 5

            if ($this->_ci_is_instance())
            {
                $_ci_CI =& get_instance();
                foreach (get_object_vars($_ci_CI) as $_ci_key => $_ci_var)
                {
                    if ( ! isset($this->$_ci_key))
                    {
                        $this->$_ci_key =& $_ci_CI->$_ci_key;
                    }
                }
            }

            /*
             * Extract and cache variables
             *
             * You can either set variables using the dedicated $this->load_vars()
             * function or via the second parameter of this function. We'll merge
             * the two types and cache them so that views that are embedded within
             * other views can have access to these variables.
             */ 
            if (is_array($_ci_vars))
            {
                $this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars);
            }
            extract($this->_ci_cached_vars);

            /*
             * Buffer the output
             *
             * We buffer the output for two reasons:
             * 1. Speed. You get a significant speed boost.
             * 2. So that the final rendered template can be
             * post-processed by the output class.  Why do we
             * need post processing?  For one thing, in order to
             * show the elapsed page load time.  Unless we
             * can intercept the content right before it's sent to
             * the browser and then stop the timer it won't be accurate.
             */
            ob_start();

            // If the PHP installation does not support short tags we'll
            // do a little string replacement, changing the short tags
            // to standard PHP echo statements.


        $content = file_get_contents($_ci_path);

        $content = str_replace(
            array('ā','ē','ī','ō','ū','Ā','Ē','Ī','Ō','Ū'),
            array('a','e','i','o','u','A','E','I','O','U'),
            $content
        );

        if ((bool) @ini_get('short_open_tag') === FALSE AND config_item('rewrite_short_tags') == TRUE)
        {
            echo eval('?>'.preg_replace("/;*\s*\?>/", "; ?>", str_replace('<?=', '<?php echo ', '.$content)));
        }
        else
        {
            echo eval('?>'.$content.'<?php'); // include() vs include_once() allows for multiple views with the same name
        }

            log_message('debug', 'File loaded: '.$_ci_path);

            // Return the file data if requested
            if ($_ci_return === TRUE)
            {       
                $buffer = ob_get_contents();
                @ob_end_clean();
                return $buffer;
            }

            /*
             * Flush the buffer... or buff the flusher?
             *
             * In order to permit views to be nested within
             * other views, we need to flush the content back out whenever
             * we are beyond the first level of output buffering so that
             * it can be seen and included properly by the first included
             * template and any subsequent ones. Oy!
             *
             */ 
            if (ob_get_level() > $this->_ci_ob_level + 1)
            {
                ob_end_flush();
            }
            else
            {
                // PHP 4 requires that we use a global
                global $OUT;
                $OUT->append_output(ob_get_contents());
                @ob_end_clean();
            }
        }
    }
}

您可能不需要所有这些,但我只是从已归档的项目中复制它。请注意,在_ci_load()函数中,您可以在评估输出之前影响输出(通常是注释所指示的包含,但更改为您的情况的字符串)。我没有对此进行测试,因此它并不是一个解决方案,因为它是一般提醒您可以扩展核心类并在一个地方修改输出。

当然,在输出类本身中可能更容易: https://www.codeigniter.com/user_guide/libraries/output.html

答案 2 :(得分:0)

如果您的意图是替换重音字符,那么我建议您查看wordpress remove_accents function here

2)看看codeigniter hooks,有display_override hook

$hook['display_override'] = array(
  'class'    => 'MyClass',
  'function' => 'Myfunction',
  'filename' => 'Myclass.php',
  'filepath' => 'hooks',
  'params'   => array()
);

3)一旦你为这个钩子定义了一个函数/类,你就可以在那里获得输出字符串

$this->CI =& get_instance();
$out = $this->CI->output->get_output();

然后您可以根据需要更改输出...