如何将参数传递给CodeIgniter中的钩子?

时间:2018-07-26 17:21:09

标签: php codeigniter hook codeigniter-3

在CodeIgniter中,如何从调用该钩子的上下文中传递参数?

示例:

File_Where_Hook_is_Called.php:

$this->hooks = load_class('Hooks', 'core');

$filename = 'example.zip';

$this->hooks->call_hook('site_export_before_delete');

config / hooks.php:

$hook['site_export_before_delete'][] = array(
        'class'    => 'Foo',
        'function' => 'export_site',
        'filename' => 'Foo.php',
        'filepath' => 'modules/foo/controllers',
        'params'   => [''] # Should be $filename from File_Where_Hook_is_Called.php
);

application / modules / foo / controllers / Foo.php:

public function export_site($filename) {
    echo $filename); # Should print $filename from File_Where_Hook_is_Called.php
}

2 个答案:

答案 0 :(得分:1)

很烂,但是使用global范围变量。

由于CI_Hook类下的函数call_hook不采用其他参数:

public function call_hook($which = '') {
   #...
}

由于我不想直接从CodeIgniter修改核心文件,因此我最终使用了全局变量作用域:

File_Where_Hook_is_Called.php:

# A variable with global scope should have an unique name,
# to avoid conflict with any other one in your entire application.
# Choose it carefully.

global $foo_hook_file_name;
$foo_hook_file_name = $file_name;

application / modules / foo / controllers / Foo.php:

public function export_site() {
    global $foo_hook_file_name;
    echo $foo_hook_file_name;
}

请确保为全局变量添加唯一名称(例如钩子的名称),以免与其他变量发生冲突。

答案 1 :(得分:1)

我知道可能有点晚了,但是由于我有同样的需求,我偶然发现了你的问题,并且我以正确的方式解决了这个问题。

根据CodeIgniter documentation,您可以通过实现自己的MY_Hooks类来覆盖默认的CI_Hooks类行为,通常在application/core/MY_Hooks.php

<?php

defined('BASEPATH') OR exit('No direct script access allowed');

class MY_Hooks extends CI_Hooks{

    protected function _call_single_hook($data, $params) {
        if($params) {
            if(!isset($data['params'])) {
                $data['params'] = [];
            }
            $data['params'] = array_merge($data['params'], $params);
        }

        $this->_run_hook($data);
    }

    /**
     * Call Hook
     *
     * Calls a particular hook. Called by CodeIgniter.php.
     *
     * @uses    CI_Hooks::_run_hook()
     *
     * @param   string  $which  Hook name
     * @param   array   $params  Extra (dynamic) parameters array
     * @return  bool    TRUE on success or FALSE on failure
     */
    public function call_hook($which = '', $params=null)
    {
        if ( ! $this->enabled OR ! isset($this->hooks[$which]))
        {
            return FALSE;
        }

        if (is_array($this->hooks[$which]) && ! isset($this->hooks[$which]['function']))
        {
            foreach ($this->hooks[$which] as $val)
            {
                $this->_call_single_hook($val, $params);
            }
        }
        else
        {
            $this->_call_single_hook($this->hooks[$which], $params);
        }

        return TRUE;
    }
}

在我的情况下,我扩展了CI_Hooks类,只是覆盖了call_hook方法,该方法是将额外的参数附加到hooks数组的允许的“ params”键中。

之后,您可以从控制器中调用该挂钩。 根据您的示例,代码将为:

$this->hooks->call_hook('site_export_before_delete', ['filename' => $filename]);

从我的角度来看,这是解决该问题的好方法,并且对我有用。