亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > PHP > 正文

CI框架源碼閱讀筆記6 擴(kuò)展鉤子 Hook.php

2020-03-22 20:26:22
字體:
供稿:網(wǎng)友
  •   CI框架允許你在不修改系統(tǒng)核心代碼的基礎(chǔ)上添加或者更改系統(tǒng)的核心功能(如重寫緩存、輸出等)。例如,在系統(tǒng)開啟hook的條件下(config.php中$config['enable_hooks'] = TRUE;),通過添加特定的鉤子,可以讓系統(tǒng)在特定的時(shí)刻觸發(fā)特定的腳本:

    $hook['post_system'] = array(    'html' target='_blank'>class'     => 'frameLog',    'function'  => 'postLog',    'filename'  => 'post_system.php',    'filepath'   => 'hooks',);

    上述鉤子定義了一個(gè)post_system的鉤子,用于在最終的頁面渲染之后的腳本處理(參數(shù)的含義可以參考后面或者手冊,這里暫時(shí)不做更多解釋)。

    那么問題來了:

    鉤子是什么? CI中支持的鉤子有哪些? CI中鉤子是如何實(shí)現(xiàn)的?

    我們一步步來看。

    1.  鉤子是什么

      百度百科上對于鉤子的定義是:

    鉤子實(shí)際上是一個(gè)處理消息的程序段,通過系統(tǒng)調(diào)用,把它掛入系統(tǒng)。每當(dāng)特定的消息發(fā)出,在沒有到達(dá)目的窗口前,鉤子程序就先捕獲該消息,亦即鉤子函數(shù)先得到控制權(quán)。這時(shí)鉤子函數(shù)即可以加工處理(改變)該消息,也可以不作處理而繼續(xù)傳遞該消息,還可以強(qiáng)制結(jié)束消息的傳遞。

      從上述定義我們可以看出幾點(diǎn):

    鉤子是一種事件驅(qū)動模式,它的核心自然是事件(CI中pre_system,pre_controller等都是特定的事件)。 既然是事件驅(qū)動,那么必然要包含最重要的兩個(gè)步驟: (1)、事件注冊。對于Hook而言,就是指Hook鉤子的掛載。(2).事件觸發(fā)。在特定的時(shí)間點(diǎn)call特定的鉤子,執(zhí)行相應(yīng)的鉤子程序。 既然是事件驅(qū)動,那么也應(yīng)該支持統(tǒng)一掛鉤點(diǎn)的多個(gè)注冊事件。 啟動Hook鉤子之后,程序的流程可能會發(fā)生變化,且鉤子之間可能有相互調(diào)用的可能性,如果處理不當(dāng),會有死循環(huán)的可能性。同時(shí),鉤子的啟用使得程序在一定程度上變得復(fù)雜,難以調(diào)試。2.  CI中預(yù)定義鉤子

    CI中提供了7個(gè)可用的預(yù)設(shè)掛鉤點(diǎn),分別是:

      pre_system: 指在系統(tǒng)加載前期的鉤子

      pre_controller:調(diào)用控制器之前的鉤子,路由與安全性檢查已經(jīng)完畢

      post_controller_constructor:控制器實(shí)例化之后,任何方法調(diào)用之前

      post_controller:控制器完全運(yùn)行之后

      display_override:重寫display

      cache_override :重寫緩存

      post_system:最終的頁面發(fā)送到客戶端之后

    3.  CI中鉤子的實(shí)現(xiàn)

      CI中鉤子的核心功能是由Hook組件完成的,先看該組件的類圖:

    其中:

      enabled: 鉤子功能是否開啟的標(biāo)志。

      hooks :保存系統(tǒng)中啟用的鉤子列表

      in_progress:之后我們會看到,這個(gè)標(biāo)志位用于防止鉤子之間的互相調(diào)用而導(dǎo)致的死循環(huán)。

      _construct是Hook組件的構(gòu)造函數(shù),這其中調(diào)用了_initialize來完成初始化的工作

      _call_hook: 調(diào)用_run_hook來call指定的鉤子程序。之前CodeIgniter.php中我們已經(jīng)看到,_call_hook是實(shí)際提供給外部調(diào)用的接口。

      _run_hook: 實(shí)際執(zhí)行鉤子程序的函數(shù)

    在開始之前,我們先貼出預(yù)定義鉤子的結(jié)構(gòu)。這個(gè)結(jié)構(gòu)可能會貫穿在源代碼的始終,因而我們有必要知道該結(jié)構(gòu)的參數(shù)含義。

    $hook['xx'] = array(    'class'     => 'xx', //鉤子調(diào)用的類名,可以為空    'function'  => 'xx',//鉤子調(diào)用的函數(shù)名    'filename'  => 'xx',//該鉤子的文件名    'filepath'   => 'xx',//鉤子的目錄    'params'   => 'xx'//傳遞給鉤子的參數(shù));

    1.  鉤子組件初始化

    _initialize函數(shù)用于鉤子組件的初始化,該函數(shù)主要完成的工作有:

    (1) 檢查配置文件中hook功能是否被啟用,這需要加載Config(配置管理組件):

    $CFG =& load_class('Config', 'core');if ($CFG->item('enable_hooks') == FALSE){	return;}

    (2) 加載定義的hook列表

    同樣,你可以設(shè)定不同的ENVIRONMENT啟用不同的hook,如果有的話,優(yōu)先加載ENVRIONMENT下的hook:

    if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/hooks.php')){    include(APPPATH.'config/'.ENVIRONMENT.'/hooks.php');}elseif (is_file(APPPATH.'config/hooks.php')){	include(APPPATH.'config/hooks.php');}

    (3) Hook的檢查。如果未設(shè)置任何hook,或者設(shè)置的hook格式錯誤,則不作任何處理,直接退出:

    if ( ! isset($hook) OR ! is_array($hook)){	return;}

    經(jīng)過initialize之后,Hook::hooks中存儲了已經(jīng)定義的hook列表:

    $this->hooks =& $hook;

    2.  Call指定的鉤子

    _call_hook是主程序中直接調(diào)用的接口。該接口主要的工作有:

    (1). 檢查鉤子是否被啟用,以及call的鉤子是否被預(yù)定義(如果未啟用或者call的鉤子不存在,則直接返回):

    if ( ! $this->enabled OR ! isset($this->hooks[$which])){	return FALSE;}

    (2). 檢查同一個(gè)掛鉤點(diǎn)是否啟用了多個(gè)鉤子,如果有,則依次執(zhí)行之:

    if (isset($this->hooks[$which][0]) AND is_array($this->hooks[$which][0])){	foreach ($this->hooks[$which] as $val)	{		$this->_run_hook($val);	}}

    (3). 否則,只有一個(gè)鉤子,執(zhí)行它

    else{	$this->_run_hook($this->hooks[$which]);}

    _run_hook是實(shí)際執(zhí)行hook的函數(shù)。

    3.  run執(zhí)行特定的鉤子程序

    _run_hook函數(shù)是hook的實(shí)際執(zhí)行者,該函數(shù)接收一個(gè)預(yù)定義的hook數(shù)組作為參數(shù),實(shí)現(xiàn)如下:

    (1). 如果傳遞的參數(shù)壓根就不是數(shù)組(自然也就不是有效的hook),那么直接返回:

    if ( ! is_array($data)){	return FALSE;}

    (2). 檢查hook執(zhí)行狀態(tài)。

    in_progress用于標(biāo)志當(dāng)前hook的執(zhí)行狀態(tài)。這個(gè)參數(shù)的主要作用,是防止hook之間的相互調(diào)用而導(dǎo)致的死循環(huán)。

    if ($this->in_progress == TRUE){	return;}

    (3). Hook的合法性檢查。

    為了方便講述,我們再次提出一個(gè)預(yù)定義的hook需要的參數(shù):

    $hook['xx'] = array(    'class'     => 'xx', //鉤子調(diào)用的類名,可以為空    'function'  => 'xx',//鉤子調(diào)用的函數(shù)名    'filename'  => 'xx',//該鉤子的文件名    'filepath'   => 'xx',//鉤子的目錄    'params'   => 'xx'//傳遞給鉤子的參數(shù));

    其中class和params是可選參數(shù),其他3個(gè)參數(shù)為必選參數(shù),如果不提供,則由于無法準(zhǔn)確定位到hook程序,只能直接返回:

    if ( ! isset($data['filepath']) OR ! isset($data['filename'])){	return FALSE;}$filepath = APPPATH.$data['filepath'].'/'.$data['filename'];if ( ! file_exists($filepath)){	return FALSE;}

    (4). 到這里,已經(jīng)基本確認(rèn)鉤子程序的位置了,這里有兩種情況:

    a. 預(yù)定義的hook中class參數(shù)為空,表明使用的是過程式的調(diào)用方式,則直接執(zhí)行hook文件中的function xxx

    b. class參數(shù)不為空,提供的是面向?qū)ο?/u>的方式,則實(shí)際的鉤子程序是$class->$function .同樣,如果既沒有設(shè)置class,也沒有設(shè)置function參數(shù),則無法執(zhí)行hook,直接返回:

    $class		= FALSE;$function	= FALSE;$params		= '';/* 獲取 hook class */if (isset($data['class']) AND $data['class'] != ''){	$class = $data['class'];}/* 獲取 hook function */if (isset($data['function'])){	$function = $data['function'];}/* 獲取傳遞的 hook 參數(shù) */if (isset($data['params'])){	$params = $data['params'];}/* 如果class和function都不存在,則無法定位hook程序,直接返回 */if ($class === FALSE AND $function === FALSE){	return FALSE;}

    (5). 設(shè)置執(zhí)行標(biāo)志in_progress,并執(zhí)行上述兩種情況下的hook:

    /* 面向?qū)ο蟮脑O(shè)置方式 */if ($class !== FALSE){	if ( ! class_exists($class))	{		require($filepath);	}	$HOOK = new $class;	$HOOK->$function($params);}/*  過程式的執(zhí)行方式 */else{	if ( ! function_exists($function))	{		require($filepath);	}	$function($params);}

    最后,別忘了在hook執(zhí)行完之后,設(shè)置標(biāo)識位in_progress為false,并返回執(zhí)行成功的標(biāo)志:

    $this->in_progress = FALSE;return TRUE;

    Hook組件的完整源碼:

    <?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');class CI_Hooks {	/**	 * Determines wether hooks are enabled	 *	 * @var bool	 */	var $enabled		= FALSE;	/**	 * List of all hooks set in config/hooks.php	 *	 */	var $hooks			= array();	/**	 * Determines wether hook is in progress, used to prevent infinte loops	 *	 */	var $in_progress	= FALSE;	/**	 * Constructor	 */	function __construct()	{		$this->_initialize();		log_message('debug', 'Hooks Class Initialized');	}	/**	 * Initialize the Hooks Preferences	 *	 * @access	private	 * @return	void	 */	function _initialize()	{		$CFG =& load_class('Config', 'core');		// If hooks are not enabled in the config file		// there is nothing else to do		if ($CFG->item('enable_hooks') == FALSE)		{			return;		}		if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/hooks.php'))		{		    include(APPPATH.'config/'.ENVIRONMENT.'/hooks.php');		}		elseif (is_file(APPPATH.'config/hooks.php'))		{			include(APPPATH.'config/hooks.php');		}		if ( ! isset($hook) OR ! is_array($hook))		{			return;		}		$this->hooks =& $hook;		$this->enabled = TRUE;	}	/**	 * Call Hook	 *	 * Calls a particular hook	 *	 * @access	private	 * @param	string	the hook name	 * @return	mixed	 */	function _call_hook($which = '')	{		if ( ! $this->enabled OR ! isset($this->hooks[$which]))		{			return FALSE;		}		if (isset($this->hooks[$which][0]) AND is_array($this->hooks[$which][0]))		{			foreach ($this->hooks[$which] as $val)			{				$this->_run_hook($val);			}		}		else		{			$this->_run_hook($this->hooks[$which]);		}		return TRUE;	}	/**	 * Run Hook	 *	 * Runs a particular hook	 *	 * @access	private	 * @param	array	the hook details	 * @return	bool	 */	function _run_hook($data)	{		if ( ! is_array($data))		{			return FALSE;		}		// If the script being called happens to have the same hook call within it a loop can happen		if ($this->in_progress == TRUE)		{			return;		}		if ( ! isset($data['filepath']) OR ! isset($data['filename']))		{			return FALSE;		}		$filepath = APPPATH.$data['filepath'].'/'.$data['filename'];		if ( ! file_exists($filepath))		{			return FALSE;		}		$class		= FALSE;		$function	= FALSE;		$params		= '';		if (isset($data['class']) AND $data['class'] != '')		{			$class = $data['class'];		}		if (isset($data['function']))		{			$function = $data['function'];		}		if (isset($data['params']))		{			$params = $data['params'];		}		if ($class === FALSE AND $function === FALSE)		{			return FALSE;		}		$this->in_progress = TRUE;		// Call the requested class and/or function		if ($class !== FALSE)		{			if ( ! class_exists($class))			{				require($filepath);			}			$HOOK = new $class;			$HOOK->$function($params);		}		else		{			if ( ! function_exists($function))			{				require($filepath);			}			$function($params);		}		$this->in_progress = FALSE;		return TRUE;	}}
    PHP編程

    鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時(shí)間聯(lián)系我們修改或刪除,多謝。

  • 發(fā)表評論 共有條評論
    用戶名: 密碼:
    驗(yàn)證碼: 匿名發(fā)表
    樱花草国产18久久久久| 欧美一级鲁丝片| 天堂男人av| 国产欧美一区二区三区不卡高清| 亚洲影视资源网| 欧美午夜精品一区二区三区| 精品亚洲成a人片在线观看| 国产精品wwwww| 稀缺呦国内精品呦| 九九九九九精品| 在线日本视频| 国产精品igao网网址不卡| 欧美黄色免费看| 日韩av二区在线播放| 在线观看免费污视频| 欧美成人免费在线观看视频| 精品国产乱码一区二区| 最近2019年日本中文免费字幕| 翁止熄痒禁伦短文合集免费视频| 精品三级在线观看| 性一爱一乱一交一视频| 美女黄页在线观看| 一区二区中文| 国产91免费在线观看| 国产最顶级的黄色片在线免费观看| 午夜在线观看免费一区| 久久亚区不卡日本| 国产免费一区二区三区在线观看| 99re国产| 亚洲国产精品99久久久久久久久| 蜜桃av在线播放| xf在线a精品一区二区视频网站| 亚洲天堂2017| 麻豆一区二区麻豆免费观看| 日韩电影免费观看高清完整| av在线资源| 国自产拍在线网站网址视频| av日韩在线免费| 能在线观看的av网站| 亚洲综合第一页| 免费成人av在线| 亚洲国产一区二区在线播放| 性伦欧美刺激片在线观看| 国产美女撒尿一区二区| 国产韩日影视精品| 超碰成人在线免费| 欧美日本中文| 成人一二三四区| 一区二区三区精品久久久| 夫妇露脸对白88av| 欧美成人亚洲高清在线观看| 成年网站免费观看| 亚洲中文字幕无码一区二区三区| 日本成人动漫在线观看| 欧美性69xxxx肥| 亚洲春色综合另类校园电影| av手机在线播放| 亚洲天堂免费在线| 中文字幕在线观看视频一区| 男女污污视频网站| 婷婷丁香久久| 一区二区视频免费看| 亚洲va天堂va国产va久| 国产探花精品一区二区| 亚洲综合色视频| 性色av一区二区三区免费| 美乳少妇欧美精品| 动漫3d精品一区二区三区| av一区二区久久| 你懂的网址一区二区三区| 亚洲av成人片色在线观看高潮| 亚洲精品午夜在线观看| 717成人午夜免费福利电影| 成人午夜免费剧场| 精品国产一区二区三区无码| 亚洲一区二区精品在线观看| 成人午夜视频在线| 亚洲中文字幕无码一区二区三区| 欧美一区二区黄| 91丝袜一区二区三区| 日韩动漫一区| 96亚洲精品久久久蜜桃| 99久久久无码国产精品6| 日本最新在线视频| 国产一区二区不卡| 欧美高清日韩| 国产夫绿帽单男3p精品视频| 精品久久中文字幕| 欧美精品videossex变态| 亚洲第一精品在线观看| 久久久久九九九| 国模少妇一区二区三区| 日本免费在线视频观看| 久久久国产精品亚洲一区| 久久无码精品丰满人妻| 成人性色生活片| 欧美大片欧美激情性色a∨久久| 蜜桃视频中文字幕| www日韩在线观看| 亚洲图片小说在线| 国内精品视频一区| 日韩欧美中文一区| 成人全视频高清免费观看| 999久久欧美人妻一区二区| 成人免费直播| 国产欧美日韩综合精品二区| 激情深爱一区二区| 2023国产精品视频| 欧美激情无毛| 亚洲丝袜精品| 91精品国产乱码| 亚洲精品中文在线观看| 久久久精品有限公司| 久久久91精品国产一区二区三区| 性生交免费视频| 精品国产91乱码一区二区三区| 亚洲一级少妇| 国产一级精品aaaaa看| 欧美人妻一区二区三区| 亚洲女人被黑人巨大进入al| 日日狠狠久久偷偷综合色| 国产三级电影在线播放| 狂野欧美激情性xxxx欧美| 成人午夜亚洲| 91精品国产91久久久久久不卡| 一色屋免费视频| 肉色欧美久久久久久久免费看| 天天综合网久久| 成人网址在线观看| 日本黄色免费在线| 97在线视频免费观看| 日韩精品一区二区三区免费观看| 国产精品高潮呻吟久久久| 欧美极品少妇videossex| 91超碰在线电影| 成人亚洲精品777777大片| 欧美一级黑人aaaaaaa做受| 日韩天堂在线观看| 成人资源在线| 国产精品日日摸夜夜摸av| 国产精品久久久久不卡| 一区二区日韩电影| 一道本无吗dⅴd在线播放一区| 欧美艹逼视频| 国产精品99在线观看| 亚洲国产精久久久久久久| 亚洲欧美日韩系列| 国产免费一区二区三区视频| 国产免费一区二区三区网站免费| 中文字幕视频在线免费欧美日韩综合在线看| 日本欧美在线视频免费观看| 国产三级做爰高清在线| av不卡在线观看| 国产黄人亚洲片| 在线观看免费毛片| 自拍偷拍第八页| 九九视频免费看| 成年人在线观看视频| 96精品视频| 成人午夜无人区一区二区| 6—12呦国产精品| 国产精品成人免费一区久久羞羞| 精品久久久三级丝袜| 欧美亚洲国产日本| www.亚洲精品| 亚洲热app| 搡老女人一区二区三区视频tv| 色777狠狠狠综合伊人| 深夜福利免费在线观看| 一区二区三区欧美在线| 日本天堂中文字幕| 狠狠综合久久av一区二区老牛| 一区二区三区视频在线免费观看| 懂色av中文一区二区三区| 亚洲二区免费| 日韩大尺度在线观看| 亚洲第一影院| 亚洲性色视频| 国产高清精品一区二区三区| 久久网站免费视频| 国产www在线观看| 色伊人久久综合中文字幕| 99精品女人在线观看免费视频| 国产99一区视频免费| 四虎影视免费看电影| 久久久久久久久久一区二区三区| 三级视频在线播放| 天天色天天爽| 一区二区三区久久| 天天操天天摸天天舔| www.色香蕉| 香蕉av福利精品导航| 麻豆亚洲精品| 黄色av免费在线播放| 女囚岛在线观看| jvid福利写真一区二区三区| 欧洲女同同性吃奶| 欧美亚洲综合一区| 久久久91精品国产一区二区三区| 伪装者在线观看完整版免费| 日日碰狠狠添天天爽超碰97| 91精品国产91综合久久蜜臀| 国产aⅴ一区二区三区| 欧日韩一区二区三区| 在线免费观看日韩av| 91香蕉视频在线观看视频| 69av影院| 黄色一级视频免费看| 久久亚洲影视婷婷| 日韩美女在线看免费观看| 日韩影院二区| 国产精品九九视频| 中文字幕一区图| 美女网站色精品尤物极品姐弟| 无码少妇一区二区三区| 另类专区亚洲| 黄色av网站在线看| 柠檬在线导航福利| 1pon在线| 亚洲男人天堂2023| 在线视频 91| 色综合天天综合在线视频| 亚洲国产欧美国产第一区| 亚洲aⅴ天堂av在线电影软件| 中文字幕视频在线播放| 亚洲一区欧美激情| 在线你懂的视频| 中文字幕成人乱码在线电影| 日日夜夜精品视频免费观看| 一二三四中文在线| 亚洲国产第一页| 欧美日韩精品久久久免费观看| aaa亚洲精品一二三区| 欧美在线一二三四区| 日韩xxx视频| 亚洲女性喷水在线观看一区| 91精品一区二区| 成人动漫在线播放| 成人在线视频首页| 91蝌蚪精品视频| 国产不卡视频在线播放| 欧美精品与人动性物交免费看| 国产日韩精品一区二区浪潮av| 黄色录像特级片| 国产精品午夜福利| 免费欧美一区| 成人在线观看a| 4438全国亚洲精品观看视频| av成人免费网站| 美女国产一区二区三区| 欧美性xxxx极品hd欧美风情| 丁香啪啪综合成人亚洲小说| 国产偷国产偷精品高清尤物| 国产一级免费| 久久久久久久国产精品影院| 国产精品国产三级国产| 欧美激情亚洲| 日本在线电影一区二区三区| 91av国产在线| 成人av电影免费| 国产精品99免费看| 北条麻妃一区二区三区在线| 亚洲伦理一区二区三区| 国产精品成人免费电影| 色狠狠久久aa北条麻妃| 色先锋影音av| 国内视频自拍在线视频| 日本道在线观看一区二区| 日本一区二区在线视频| 日本aⅴ精品一区二区三区| 羞羞小视频视频| 午夜欧美性电影| 国产一区玩具在线观看| 国产亚洲精品一区二555| jlzzjlzz国产精品久久| 亚洲图片小说综合| 小处雏高清一区二区三区| 丁香激情五月少妇| 精品在线欧美视频| 天天做天天爱天天爽综合网| 欧美性感一类影片在线播放| 日本网站在线免费观看| 午夜一区二区三区免费| 在线国产伦理一区| 搡的我好爽在线观看免费视频| 国产videos| 欧美一级网站| 97久久精品一区二区三区的观看方式| 中文字幕在线观看免费视频| 免费在线观看羞羞视频| www.亚洲免费| 日韩色级片先锋影音| 国产精品亚洲综合久久| 波多野结衣亚洲一区二区| 国产理论电影在线观看| 日韩五码在线| 日韩成人一区二区三区| 日本欧美在线看| 亚洲成人精品一区| 色网站免费观看| 天天躁日日躁aaaxxⅹ| 在线看的网站你懂| 日韩一区在线看| 少妇一级黄色片| 欧美激情乱人伦一区| 国产一区日韩一区| 久在线观看福利视频| 中文字幕在线观看视频免费| 99re视频在线观看| 福利成人导航| 秋霞av国产精品一区| segui88久久综合9999| 国模大尺度一区二区三区| 奇米影视第四狠狠777| 中文字幕在线影视资源| 一区二区不卡在线观看| 国产亚洲欧美日韩在线一区| 欧美色图色综合| 奇米色欧美一区二区三区| 久草综合在线| 欧美在线免费看视频| 国产精品午夜久久久久久| 成人性生交大片免费看视频r| 久久久国产精品黄毛片| 国产高潮失禁喷水爽到抽搐| 自拍一区在线观看| 中文字幕影音在线| 日韩经典在线观看|