【问题标题】:CodeIgniter, How to modify buffered output before sendingCodeIgniter,如何在发送前修改缓冲输出
【发布时间】:2014-09-05 16:28:14
【问题描述】:

我想更改整个基于 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

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

有没有办法代替钩子?

提前致谢!

【问题讨论】:

  • 一切都可以归结为最少的文件数。您要修改什么,是否有无法在模板控制器中处理的原因?您应该使用特定案例更新您的问题。否则你会被否决,这似乎已经开始了
  • 谢谢你的信息,我刚刚做了

标签: php codeigniter ob-start


【解决方案1】:

如果您打算替换重音字符,那么我建议您查看 wordpress remove_accents 函数 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();

然后你可以随意改变输出...

【讨论】:

  • 钩子绝对是一个完美的方法。在我的情况下,我必须在输出之前覆盖某些 html 标记的内容,通过在发送到客户端之前更改输出使用 CI 挂钩轻松实现。
【解决方案2】:

在应用程序/库文件中,您可以创建一个 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;
       }
    }

然后你可以从任何你想要的库中调用它。

【讨论】:

    【解决方案3】:

    对,所以你可以在加载器类的扩展中写一个替换值,并将它保存为 MY_Loader.php 在 application/core.这是一个例子:

    <?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() 函数中,您可以在评估输出之前影响输出(通常是由 cmets 指示的包含,但根据您的情况更改为字符串)。我没有对此进行测试,因此它并不是一个解决方案,而是一个一般性的提醒,即您可以在一个地方扩展核心类并修改输出。

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

    【讨论】:

    • 我同意,我可能会扩展输出类
    • 是的。我发布这个是因为我在加载器类中做了类似的事情并且代码很方便
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-26
    • 1970-01-01
    • 2013-07-30
    • 1970-01-01
    • 2020-09-02
    • 1970-01-01
    相关资源
    最近更新 更多