下面的介绍如果想看懂,最好是打开代码一起调试着看,否则很难看明白,因为里面很多地方使用到的函数或者方法,我都只是说明了其位置,而没把代码复制到文章里面来。
从项目入口index.php开始,然后 require './ThinkPHP/ThinkPHP.php';
进入./ThinkPHP/ThinkPHP.php
在定义了一大段常量(见页尾附带数据)之后,最后执行了
Think\Think::start();///代码在"ThinkPHP/Library/Think/Think.class.php"里面
下面的代码是在开启debug配置的时候才会生效
下面查看/ThinkPHP/Library/Think/Think.class.php
,在其48行,导入了初始化配置文件
$mode = include is_file(CONF_PATH.'core.php')?CONF_PATH.'core.php':MODE_PATH.APP_MODE.'.php'; //实际是 $mode = include './ThinkPHP/Mode/common.php';
50~55行,则加载了$mode['core']里面的各个文件。
76~78行,通过Hook::import()把$mode['tags']里面数据导入到Hook::$tags
里,此时通过Hook::get()
,查看Hook::$tags
array(5) { ["app_begin"] => array(1) { [0] => string(22) "Behavior\ReadHtmlCache" } ["app_end"] => array(1) { [0] => string(22) "Behavior\ShowPageTrace" } ["view_parse"] => array(1) { [0] => string(22) "Behavior\ParseTemplate" } ["template_filter"] => array(1) { [0] => string(23) "Behavior\ContentReplace" } ["view_filter"] => array(1) { [0] => string(23) "Behavior\WriteHtmlCache" } }
83行,则又将行为定义导入
Hook::import(include CONF_PATH.'tags.php'); //导入的是'./Application/Common/Conf/tags.php',里面包含的是一个数组 //array( // 'app_init'=>array('Common\Behavior\InitHook') //);
根据Hook::import()可知,此刻就是将新导入的数据与原有的数据做array_merge
,Hook::$tags
的数据为:
array(6) { ["app_begin"] => array(1) { [0] => string(22) "Behavior\ReadHtmlCache" } ["app_end"] => array(1) { [0] => string(22) "Behavior\ShowPageTrace" } ["view_parse"] => array(1) { [0] => string(22) "Behavior\ParseTemplate" } ["template_filter"] => array(1) { [0] => string(23) "Behavior\ContentReplace" } ["view_filter"] => array(1) { [0] => string(23) "Behavior\WriteHtmlCache" } ["app_init"] => array(1) { [0] => string(24) "Common\Behavior\InitHook" } }
117行,则执行了App::run()
,(之前在50~55行导入了./ThinkPHP/Library/Think/App.class.php文件),该方法中最开始就执行了
Hook::listen('app_init');
根据Hook::listen()
代码发现其实也就是执行了
Hook::exec('Common\Behavior\InitHook')
根据Hook::exec()
知道实际就是实例化Common\Behavior\InitHookBehavior()
,然后调用了其中的run()
方法,在该方法中,就可以看到从数据库里取出钩子挂载的数据,并且将其放入Hook::$tags
中。数据为:
array(13) { ["app_begin"] => array(1) { [0] => string(22) "Behavior\ReadHtmlCache" } ["app_end"] => array(1) { [0] => string(22) "Behavior\ShowPageTrace" } ["view_parse"] => array(1) { [0] => string(22) "Behavior\ParseTemplate" } ["template_filter"] => array(1) { [0] => string(23) "Behavior\ContentReplace" } ["view_filter"] => array(1) { [0] => string(23) "Behavior\WriteHtmlCache" } ["app_init"] => array(1) { [0] => string(24) "Common\Behavior\InitHook" } ["documentEditForm"] => array(1) { [0] => string(10) "Attachment" } ["documentDetailAfter"] => array(2) { [0] => string(10) "Attachment" [1] => string(13) "SocialComment" } ["documentSaveComplete"] => array(1) { [0] => string(10) "Attachment" } ["documentEditFormContent"] => array(1) { [0] => string(6) "Editor" } ["adminArticleEdit"] => array(1) { [0] => string(14) "EditorForAdmin" } ["AdminIndex"] => array(3) { [0] => string(8) "SiteStat" [1] => string(10) "SystemInfo" [2] => string(7) "DevTeam" } ["topicComment"] => array(1) { [0] => string(6) "Editor" } }
下面就是使用钩子函数来触发钩子执行了,以后台首页的hook('AdminIndex')
为例。
function hook($hook,$params=array()){ \Think\Hook::listen($hook,$params); }
这样就执行了AdminIndex
钩子,必须配合代码看。笔记完毕。在Thinkphp框架里面不管那些名词离我们多远,功能听起来有多高端,比如路由,钩子,行为等,看完源代码,发现最终要实现,不是函数就是方法,不可能有别的方式,所以没必要感觉很深奥而不敢去学习分析其源代码。
附带下项目自定常量
array(57) { ["APP_PATH"] => string(14) "./Application/" ["RUNTIME_PATH"] => string(10) "./Runtime/" ["MEMORY_LIMIT_ON"] => bool(true) ["THINK_VERSION"] => string(5) "3.2.0" ["URL_COMMON"] => int(0) ["URL_PATHINFO"] => int(1) ["URL_REWRITE"] => int(2) ["URL_COMPAT"] => int(3) ["EXT"] => string(10) ".class.php" ["THINK_PATH"] => string(37) "/mnt/hgfs/code/onethinktest/ThinkPHP/" ["APP_STATUS"] => string(0) "" ["APP_DEBUG"] => bool(false) ["APP_MODE"] => string(6) "common" ["STORAGE_TYPE"] => string(4) "File" ["LIB_PATH"] => string(45) "/mnt/hgfs/code/onethinktest/ThinkPHP/Library/" ["CORE_PATH"] => string(51) "/mnt/hgfs/code/onethinktest/ThinkPHP/Library/Think/" ["BEHAVIOR_PATH"] => string(54) "/mnt/hgfs/code/onethinktest/ThinkPHP/Library/Behavior/" ["MODE_PATH"] => string(42) "/mnt/hgfs/code/onethinktest/ThinkPHP/Mode/" ["VENDOR_PATH"] => string(52) "/mnt/hgfs/code/onethinktest/ThinkPHP/Library/Vendor/" ["COMMON_PATH"] => string(21) "./Application/Common/" ["CONF_PATH"] => string(26) "./Application/Common/Conf/" ["LANG_PATH"] => string(26) "./Application/Common/Lang/" ["HTML_PATH"] => string(19) "./Application/Html/" ["LOG_PATH"] => string(15) "./Runtime/Logs/" ["TEMP_PATH"] => string(15) "./Runtime/Temp/" ["DATA_PATH"] => string(15) "./Runtime/Data/" ["CACHE_PATH"] => string(16) "./Runtime/Cache/" ["MAGIC_QUOTES_GPC"] => bool(false) ["IS_CGI"] => int(0) ["IS_WIN"] => int(0) ["IS_CLI"] => int(0) ["_PHP_FILE_"] => string(23) "/onethinktest/index.php" ["__ROOT__"] => string(13) "/onethinktest" ["ONETHINK_VERSION"] => string(10) "1.0.131218" ["ONETHINK_ADDON_PATH"] => string(9) "./Addons/" ["MODULE_PATHINFO_DEPR"] => string(1) "/" ["__INFO__"] => string(22) "admin/index/index.html" ["__EXT__"] => string(4) "html" ["__SELF__"] => string(49) "/onethinktest/index.php?s=/admin/index/index.html" ["MODULE_NAME"] => string(5) "Admin" ["MODULE_PATH"] => string(20) "./Application/Admin/" ["PHP_FILE"] => string(26) "/onethinktest/index.php?s=" ["__APP__"] => string(26) "/onethinktest/index.php?s=" ["__MODULE__"] => string(32) "/onethinktest/index.php?s=/admin" ["CONTROLLER_NAME"] => string(5) "Index" ["ACTION_NAME"] => string(5) "index" ["__CONTROLLER__"] => string(38) "/onethinktest/index.php?s=/admin/index" ["__ACTION__"] => string(44) "/onethinktest/index.php?s=/admin/index/index" ["NOW_TIME"] => int(1399875697) ["REQUEST_METHOD"] => string(3) "GET" ["IS_GET"] => bool(true) ["IS_POST"] => bool(false) ["IS_PUT"] => bool(false) ["IS_DELETE"] => bool(false) ["IS_AJAX"] => bool(false) ["UID"] => string(1) "1" ["IS_ROOT"] => bool(true) }
错误位置
FILE: C:wampwww hinkcmsThinkPHPLibraryThinkHook.class.php LINE: 123
我在复制onethink的代码,但是出现,找不到这个类,但这个类是存在的。是不是以命名空间找类文件出现了问题啊?