搜尋
首頁後端開發PHP問題php鉤子原理是什麼

php鉤子原理是什麼

钩子原理很简单,有些人把事情弄的过于发杂,其实就是调用某个目录下的比如/hook目录下注册在hook函数里面和读取hook配置文件里面的类的方法的一个调用类的方法的功能。

目的就是最少改动代码,改动旧功能,或者增加一些新功能,或者简单说成调用函数都行。

但是读取hook的配置文件,还是需要在系统的里面每次都需要读取,其实就失去了hook的意义,建议只做钩子本身的就好。

相关推荐:《PHP入门教程

参看一下ci的hook,仅截取hook函数核心部分。

<?php
 protected function _run_hook($data) {
        // Closures/lambda functions and array($object, &#39;method&#39;) callables
        if (is_callable($data)) {
            is_array($data) ? $data[0]->{$data[1]}() : $data();
            return TRUE;
        } elseif (!is_array($data)) {
            return FALSE;
        }
        if ($this->_in_progress === TRUE) {
            return;
        }
        if (!isset($data[&#39;filepath&#39;], $data[&#39;filename&#39;])) {
            return FALSE;
        }
        $filepath = APPPATH . $data[&#39;filepath&#39;] . &#39;/&#39; . $data[&#39;filename&#39;];
        if (!file_exists($filepath)) {
            return FALSE;
        }
        $class = empty($data[&#39;class&#39;]) ? FALSE : $data[&#39;class&#39;];
        $function = empty($data[&#39;function&#39;]) ? FALSE : $data[&#39;function&#39;];
        $params = isset($data[&#39;params&#39;]) ? $data[&#39;params&#39;] : &#39;&#39;;
        if (empty($function)) {
            return FALSE;
        }
        // Set the _in_progress flag
        $this->_in_progress = TRUE;
        // Call the requested class and/or function
        if ($class !== FALSE) {
            // The object is stored?
            if (isset($this->_objects[$class])) {
                if (method_exists($this->_objects[$class], $function)) {
                    $this->_objects[$class]->$function($params);
                } else {
                    return $this->_in_progress = FALSE;
                }
            } else {
                class_exists($class, FALSE) OR require_once($filepath);
                if (!class_exists($class, FALSE) OR ! method_exists($class, $function)) {
                    return $this->_in_progress = FALSE;
                }
                // Store the object and execute the method
                $this->_objects[$class] = new $class(); 
                $this->_objects[$class]->$function($params);
             // 核心部分 读取参数部分,去实例化类调用方法 传递参数  其实这也是MVC url路由实现的核心,现在很多
//都是使用 call_user_func_array  call_user_func 这两个方法
            }
        } else {
            function_exists($function) OR require_once($filepath);
            if (!function_exists($function)) {
                return $this->_in_progress = FALSE;
            }
            $function($params);
        }
        $this->_in_progress = FALSE;
        return TRUE;
    }

原理图解

php鉤子原理是什麼

个人实现版本

如果你觉得麻烦,甚至可以写个方法都行,建议写成一个类,因为有些东西需要更多的信息

php鉤子原理是什麼

php

include &#39;hook.class.php&#39;;
$rr = new hook();
//$ee = $rr->get_all_class();
$rr->run_hook(&#39;ff&#39;,&#39;ss&#39;,array());
//echo &#39;<pre class="brush:php;toolbar:false">&#39;;
//print_r($ee);
//echo &#39;
';

hook.class.php

class hook {
    public $HOOK_PATH;
    public $PATH; //完整钩子文件目录
    public $object;
    //调用的时候这个类使用的时候,必须在系统的执行流程当中
    public function __construct() {
        $this->HOOK_PATH = &#39;&#39;; //项目的路径,根据你的项目计算路径  
        $current_path = str_replace("\\", "/", getcwd()); //获取当前目录
        //这个地方在实际用的时候看你需要调整
        $this->PATH = $current_path . $this->HOOK_PATH;
    }
    /* 注册钩子 也可以叫做运行钩子
     * $class       类名称
     * $function    方法 
     * $param       方法参数
     */
    public function run_hook($class, $function, $param = array()) {
        include $this->PATH . &#39;/&#39; . $class . &#39;.class.php&#39;;
//        var_dump($this->PATH . &#39;/&#39; . $class . &#39;.class.php&#39;);
//        call_user_func_array(array($class, $function), $param);//只能调用类的静态方法
//        call_user_func(array($class, $function), $param);  //只能调用类的静态方法
//        其他写法
        $this->object = new $class();
        $this->object->$function($param); //这样就可以不用调用静态方法
    }
    //返回当前已经所有的钩子类和方法  不要当前方法调用这个核心类,需要稍微改造,在$hook_array[$key][&#39;function&#39;]的返回
    方法名的时候
    public function get_all_class() {
        //搜寻hook目录下的所有钩子文件,返回数组
//        $this->PATH
//        var_dump($this->PATH);
        $file_array = scandir($this->PATH);
        $hook_array = array();
        foreach ($file_array as $key => $value) {
            if (strpos($value, &#39;.class.php&#39;) == true) {     //扫描路径绝对不能和这个类本身在一个同一个目录下,不然
            会出现重复声明的同名类
                $name = explode(&#39;.&#39;, $value);
                $hook_array[$key][&#39;name&#39;] = $name[&#39;0&#39;] . &#39;钩子类&#39;;
                $hook_array[$key][&#39;url&#39;] = $this->PATH . &#39;/&#39; . $value;
//                include $hook_array[$key][&#39;url&#39;]; 
//                $cc = new $name[&#39;0&#39;]();
//                $hook_array[$key][&#39;function&#39;][] = get_class_methods($cc);
//                $hook_array[$key][&#39;function&#39;][&#39;param&#39;][] = get_class_vars($class_name); //获取方法变量
            }
        }
        return $hook_array;
    }
}

调用的某个类名

ff.class.php 的ss方法

    public function ss() {
//    static public function ss() {
        echo &#39;dddddddddddddddddddd&#39;;
    }

另一个版本

更方便调用

class hooks {
    const Directory_Structure = &#39;/hooks/&#39;; //相对目录的路径  具体项目使用的时候需要调整
    static public function get_path() {
        return str_replace("\\", "/", getcwd());
    }
    static public function run_hook($class, $function, $param = array()) {
       $s =  include self::get_path() . self::Directory_Structure .$class. &#39;.class.php&#39;;
        call_user_func(array($class, $function), $param);  //只能调用类的静态方法
//        其他写法
//        $object = new $class();
//        $object->$function($param); //这样就可以不用调用静态方法
    }
}

使用

include &#39;hooks.class.php&#39;;
hooks::run_hook(&#39;ee&#39;, &#39;vv&#39;,$param =array());
当然也可以这么访问
$foo = new hooks();
$foo->run_hook(&#39;ee&#39;, &#39;vv&#39;,array());
$foo::run_hook(&#39;ee&#39;, &#39;vv&#39;,array());

自 PHP 5.3.0 起,可以用一个变量来动态调用类。但该变量的值不能为关键字 self,parent 或 static。

 钩子是比较灵活的,可以额外增加一个功能代码,使代码更整洁,比如在做什么一些重要操作,创建订单,在创建订单之前需要做些什么,在创建之后做些什么,都可以使用钩子,这样代码更加灵活。

以上是php鉤子原理是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
php怎么把负数转为正整数php怎么把负数转为正整数Apr 19, 2022 pm 08:59 PM

php把负数转为正整数的方法:1、使用abs()函数将负数转为正数,使用intval()函数对正数取整,转为正整数,语法“intval(abs($number))”;2、利用“~”位运算符将负数取反加一,语法“~$number + 1”。

php怎么实现几秒后执行一个函数php怎么实现几秒后执行一个函数Apr 24, 2022 pm 01:12 PM

实现方法:1、使用“sleep(延迟秒数)”语句,可延迟执行函数若干秒;2、使用“time_nanosleep(延迟秒数,延迟纳秒数)”语句,可延迟执行函数若干秒和纳秒;3、使用“time_sleep_until(time()+7)”语句。

php字符串有没有下标php字符串有没有下标Apr 24, 2022 am 11:49 AM

php字符串有下标。在PHP中,下标不仅可以应用于数组和对象,还可应用于字符串,利用字符串的下标和中括号“[]”可以访问指定索引位置的字符,并对该字符进行读写,语法“字符串名[下标值]”;字符串的下标值(索引值)只能是整数类型,起始值为0。

php怎么除以100保留两位小数php怎么除以100保留两位小数Apr 22, 2022 pm 06:23 PM

php除以100保留两位小数的方法:1、利用“/”运算符进行除法运算,语法“数值 / 100”;2、使用“number_format(除法结果, 2)”或“sprintf("%.2f",除法结果)”语句进行四舍五入的处理值,并保留两位小数。

php怎么读取字符串后几个字符php怎么读取字符串后几个字符Apr 22, 2022 pm 08:31 PM

在php中,可以使用substr()函数来读取字符串后几个字符,只需要将该函数的第二个参数设置为负值,第三个参数省略即可;语法为“substr(字符串,-n)”,表示读取从字符串结尾处向前数第n个字符开始,直到字符串结尾的全部字符。

php怎么根据年月日判断是一年的第几天php怎么根据年月日判断是一年的第几天Apr 22, 2022 pm 05:02 PM

判断方法:1、使用“strtotime("年-月-日")”语句将给定的年月日转换为时间戳格式;2、用“date("z",时间戳)+1”语句计算指定时间戳是一年的第几天。date()返回的天数是从0开始计算的,因此真实天数需要在此基础上加1。

php怎么查找字符串是第几位php怎么查找字符串是第几位Apr 22, 2022 pm 06:48 PM

查找方法:1、用strpos(),语法“strpos("字符串值","查找子串")+1”;2、用stripos(),语法“strpos("字符串值","查找子串")+1”。因为字符串是从0开始计数的,因此两个函数获取的位置需要进行加1处理。

php怎么替换nbsp空格符php怎么替换nbsp空格符Apr 24, 2022 pm 02:55 PM

方法:1、用“str_replace("&nbsp;","其他字符",$str)”语句,可将nbsp符替换为其他字符;2、用“preg_replace("/(\s|\&nbsp\;||\xc2\xa0)/","其他字符",$str)”语句。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器