精华内容
下载资源
问答
  • 摘要:PHP钩子简单的说它一种事件驱动的信息处理机制。一件事情,比如说你为了完成某个目的的程序,一次数据库查询,为了一次注册,为了一次登录,为了访问某个特定的网站等等。 1、什么PHP钩子简单的说它一种...

    favicon.ico摘要:PHP钩子简单的说它是一种事件驱动的信息处理机制。一件事情,比如说你为了完成某个目的的程序,一次数据库查询,为了一次注册,为了一次登录,为了访问某个特定的网站等等。

    1、什么是PHP钩子

    简单的说它是一种事件驱动的信息处理机制。一件事情,比如说你为了完成某个目的的程序,一次数据库查询,为了一次注册,为了一次登录,为了访问某个特定的网站等等。

    而事件驱动分为两个阶段:

    注册事件,目的是给未来可能发生的'事情'起一个名字,名字,可以用单例模式或者注册 为一个全局的变量,用的时候直接在对应的方法或者类再或者函数中插入这个变量即可。

    触发事件,本质上就是在事件的全局变量中查询要触发的时间名称,然后找到注册号的类与方法,实例化运行。

    下面通过一个demo代码示例来说明PHP钩子原理:

    假设项目开发过程如下:1.产品经理根据用户需求(甲方乙方都行)搞了一大堆的需求.

    2.当用户注册成功后需要发短信,邮箱等等验证.

    3.工程师蜂拥而上开始写代码

    4.写什么?把产品经理提出的需求实现,转换成代码在"用户注册成功"和"跳转页面"之间class Demo{

    public function index(){

    //用户注册成功

    /*

    发送短信的代码

    */

    /*

    发送邮箱的代码

    */

    /*

    其他功能balabla

    */

    //页面跳转到网站首先等等

    }}

    $demo = new Demo(); //new一个对象出来

    $demo->index();     //调用执行就可以了

    如果这段代码的几块功能块由不同的PHPer完成:

    1、代码混乱

    2、配合麻烦

    封装成函数?

    1、代码会整洁一些

    2、方便重复调用class Test{

    public function index(){

    // 用户注册成功

    // 发送短信

    sendSms($phone);

    // 发送邮件

    sendSms($email);

    // 其他操作...

    // 前往网站首页

    }}

    /**

    * 发送短信通知

    * @param  integer $phone 手机号

    */function sendSMS($phone){

    // 此处是发送短信的代码}

    /**

    * 发送邮件通知

    * @param  string $email 邮箱地址

    */function sendEmail($email){

    // 此处是发送邮件的代码}

    这时甲方或不懂代码的产品狗就会说,好难用,也理解不了你们这帮程序员竟然说这样好用?我会的就只有点击,双击,鼠标中间都不会用。搞毛呢?<?php

    class Test{

    public function index(){

    // 用户注册成功

    if ('如果设置了发送短信') {

    // 发送短信

    sendSms($phone);

    }

    if ('如果设置了发送邮件') {

    // 发送邮件

    sendSms($email);

    }

    // 其他操作...

    // 前往网站首页

    }}

    /**

    * 发送短信通知

    * @param  integer $phone 手机号

    */function sendSMS($phone){

    // 此处是发送短信的代码}

    /**

    * 发送邮件通知

    * @param  string $email 邮箱地址

    */function sendEmail($email){

    // 此处是发送邮件的代码}

    自己发开写个简单的文档给产品狗或者甲方问题不大,同为工程狗的我们也能看和开发个差不多。

    如果我们想开源出去,想让更多的人参与进来完善功能.这样显然就不合适了。

    那可不可以把自己写的代码放在某个目录下?

    然后系统自动的 根据配置项把这些代码加载到"用户注册成功"和"跳转到首页"之间?

    好先定义如下目录:├─plugin // 插件目录│  ├─plugin1 // 插件1│  │  ├─config.php // 插件1的配置项│  │  ├─index.php // 插件1的程序处理内容│  ├─plugin2

    │  │  ├─config.php

    │  │  ├─index.php

    │  ├─plugin3

    │  │  ├─config.php

    │  │  ├─index.php

    │  ├─...├─index.php // 业务逻辑

    业务逻辑:class Test{

    public function index(){

    // 用户注册成功

    // 获取全部插件

    $pluginList=scandir('./plugin/');

    // 循环插件 // 排除. ..

    foreach ($pluginList as $k => $v) {

    if ($v=='.' || $v=='..') {

    unset($pluginList[$k]);

    }

    }

    echo "简易后台管理


    ";

    // 插件管理

    foreach ($pluginList as $k => $v) {

    // 获取配置项

    $config=include './plugin/'.$v.'/config.php';

    $word=$config['status']==1 ? '点击关闭' : '点击开启';

    echo $config['title'].''.$word.'
    ';

    }

    echo '


    ';

    // 输出插件内容

    foreach ($pluginList as $k => $v) {

    // 获取配置项

    $config=include './plugin/'.$v.'/config.php';

    if ($config['status']==1) {

    include './plugin/'.$v.'/index.php';

    // 运行插件

    Hook::run($v);

    }

    }

    // 前往网站首页

    }

    }

    // 插件类

    class Hook{

    // 注册添加插件

    public static function add($name,$func){

    $GLOBALS['hookList'][$name][]=$func;

    }

    // 执行插件

    public static function run($name,$params=null){

    foreach ($GLOBALS['hookList'][$name] as $k => $v) {

    call_user_func($v,$params);

    }

    }

    }

    // 更改插件状态

    if (isset($_GET['change'])) {

    // 获取到配置项

    $config=include './plugin/plugin'.substr($_GET['change'],-1).'/config.php';

    // 如果是开启 那就关闭 如果是关闭 则开启

    $config['status']=$config['status']==1 ? 0: 1;

    // 将更改后的配置项写入到文件中

    $str="<?php  \r\n return ".var_export($config,true).';';

    file_put_contents('./plugin/'.$_GET['change'].'/config.php', $str);

    header('Location:./');

    }

    $test=new Test();

    $test->index();

    插件配置项:return array (

    'status' => 1, // 定义状态 1表示开启  0表示关闭

    'title' => '发送短信', // 插件的名称

    );

    插件内容:Hook::add('plugin1',function(){

    echo '发送短信的内容
    ';

    });

    当然,这个只是简单的理解钩子。像国内的discuz,wordpress等等这些源码,都是很厉害。

    展开全文
  • 1 引用数据类型对象一种特殊的数据, 看如下代码示例 // 一. 定义一个学生类 function Student(n, a) { this.uname = n; this.age = a; } // 二. 实例化对象 var stu = new Student('xiaoming', 20); 这里并...

    1 引用数据类型

    对象是一种特殊的数据, 看如下代码

    示例
     // 一. 定义一个学生类
     function Student(n, a) {
         this.uname = n;
         this.age = a;
     }
     // 二. 实例化对象
     var stu = new Student('xiaoming', 20);
    
    • 这里并不是把所有的数据直接保存在变量中
    • 而是先在堆区开辟一个空间, 把这个空间的引用保存在变量中.
    • 在js中, 函数和对象都是引用数据类型

    d3d4111c112a1da1ff0abe415d7a3795.png

    这里有个词--"引用"

    什么是引用呢, 引用有什么用呢?

    一句话解释: 引用就是来找数据的

    类似于路径的概念, 就像我们可以通过路径E:docmentimageimg.jpg找到电脑中的一个文件,

    又或者酒店的房间号, 通过房间号就可以找到房间

    通过引用就可以找到内存中的数据.

    引用本质上是内存首地址. 通过这个地址就可以找到对应的内存空间, 进而获取数据

    574e79ef2dafd5787e1e9d09246a1e2c.png
    https://www.zhihu.com/video/1153304026035630080

    2 new实例化的过程

    示例
     // 一. 定义一个学生类
     function Student(n, a) {
         this.uname = n;
         this.age = a;
     }
     // 二. 实例化对象
     var stu = new Student('xiaoming', 20);
    

    852b90f978d3fb8a18f005ed367964f6.gif

    当代码执行到行7行时.

    1. 在堆内存中开辟一段内存空间, 假设这段内存空间是从0x1111~0x20003
      因此通过0x1111就可以找到对应的这段内存空间, 进而获取其中的数据
    2. 0x1111保存在this中, 我们也可以说让this指向这个空间
    3. 执行函数. 通过this=0x1111找到内存空间, 在这个空间中保存数据name:xiaoming,age:20
    4. 最后, 将0x1111返回, 保存在stu中
    b3576bb8f59f3eb6002636150b97c4bb.png
    https://www.zhihu.com/video/1153304158340743168
    练习

    如果再实例化一个对象stu1, (假设内存地址是0x2222), 画出实例化的过程

     // 一. 定义一个学生类
     function Student(n, a) {
         this.uname = n;
         this.age = a;
     }
     // 二. 实例化对象
     var stu = new Student('xiaoming', 20);
     var stu1 = new Student('xiaomei', 18);
    
    参考答案

    25322f60ef790c4bf301e45c62d923b5.png

    这样, 我们就可以通过一个模板(Student构造函数)得到多个不同的对象(stu对象和stu1对象). 对象中保存的数据也不一样.

    edcf8c26b9d656bdea736ffa24475458.png
    https://www.zhihu.com/video/1153304226963873792
    展开全文
  • 据华为中国官方消息,今日,华为中国发文《小白看过来,让Python爬虫成为你的好帮手》,文中详细介绍了Python爬虫的工作原理,我们来看一下吧。以下为《小白看过来,让Python爬虫成为你的好帮手》全文:随着信息化...

    据华为中国官方消息,今日,华为中国发文《小白看过来,让Python爬虫成为你的好帮手》,文中详细介绍了Python爬虫的工作原理,我们来看一下吧。

    以下为《小白看过来,让Python爬虫成为你的好帮手》全文:

    随着信息化社会的到来,人们对网络爬虫这个词已经不再陌生。但什么是爬虫,如何利用爬虫为自己服务,这些在ICT技术小白听起来又有些高入云端。不用愁,下面一文带你走近爬虫世界,让即使身为ICT技术小白的你,也能秒懂使用Python爬虫高效抓取图片。

    什么是专用爬虫?

    网络爬虫是一种从互联网抓取数据信息的自动化程序。如果我们把互联网比作一张大的蜘蛛网,数据便是存放于蜘蛛网的各个节点,而爬虫就是一只小蜘蛛(程序),沿着网络抓取自己的猎物(数据)。

    爬虫可以在抓取过程中进行各种异常处理、错误重试等操作,确保爬取持续高效地运行。它分为通用爬虫和专用爬虫。通用爬虫是捜索引擎抓取系统的重要组成部分,主要目的是将互联网上的网页下载到本地,形成一个互联网内容的镜像备份;专用爬虫主要为某一类特定的人群提供服务,爬取的目标网页定位在与主题相关的页面中,节省大量的服务器资源和带宽资源。比如要获取某一垂直领域的数据或有明确的检索需求,此时就需要过滤掉一些无用的信息。

    爬虫工作原理

    爬虫可以根据我们提供的信息从网页上获取大量的图片,它的工作原理是什么呢?

    爬虫首先要做的工作是获取网页的源代码,源代码里包含了网页的部分有用信息;之后爬虫构造一个请求并发送给服务器,服务器接收到响应并将其解析出来。实际上,获取网页——分析网页源代码——提取信息,便是爬虫工作的三部曲。如何提取信息?最通用的方法是采用正则表达式。网页结构有一定的规则,还有一些根据网页节点属性、CSS选择器或XPath来提取网页信息的库,如Requests、pyquery、lxml等,使用这些库,便可以高效快速地从中提取网页信息,如节点的属性、文本值等,并能简单保存为TXT文本或JSON文本,这些信息可保存到数据库,如MySQL和MongoDB等,也可保存至远程服务器,如借助SFTP进行操作等。提取信息是爬虫非常重要的作用,它可以使杂乱的数据变得条理清晰,以便我们后续处理和分析数据。

    原标题:华为官方解析何为Python爬虫

    责任编辑:曾少林

    展开全文
  • 那么,thinkphp钩子(Hook)机制的原理是什么呢?1、框架在\Think\Think->start()方法中调用Hook类中的import方法批量加载模式行为:默认为\Model\common.php中的配置文件,该文件定义行为扩展2、通过...

    81ce7843dc250ef4768fc463a2b3c889.png

    首先,钩子是一种触发机制,如同一个陷阱,当程序运行到某个地方时就会触发这个陷阱,然后执行这个Hook,执行完成后,系统根据执行的不同结果继续进行。

    那么,thinkphp钩子(Hook)机制的原理是什么呢?

    1、框架在\Think\Think->start()方法中调用Hook类中的import方法批量加载模式行为:默认为\Model\common.php中的配置文件,该文件定义行为扩展

    dec84a1df873169d75384c275100543a.png

    2、通过Hook:listen()方法监听tag标记的行为.Hook类中定义一个数组tags:tag为key;Behavior行为是value.通过Hook:exec()执行该标记的行为插件/**

    * 监听标签的插件

    * @param string $tag 标签名称

    * @param mixed $params 传入参数

    * @return void

    */

    static public function listen($tag, &$params=NULL) {

    if(isset(self::$tags[$tag])) {

    if(APP_DEBUG) {

    G($tag.'Start');

    trace('[ '.$tag.' ] --START--','','INFO');

    }

    foreach (self::$tags[$tag] as $name) {

    APP_DEBUG && G($name.'_start');

    $result = self::exec($name, $tag,$params);

    if(APP_DEBUG){

    G($name.'_end');

    trace('Run '.$name.' [ RunTime:'.G($name.'_start',$name.'_end',6).'s ]','','INFO');

    }

    if(false === $result) {

    // 如果返回false 则中断插件执行

    return ;

    }

    }

    if(APP_DEBUG) { // 记录行为的执行日志

    trace('[ '.$tag.' ] --END-- [ RunTime:'.G($tag.'Start',$tag.'End',6).'s ]','','INFO');

    }

    }

    return;

    }

    /**

    * 执行某个插件

    * @param string $name 插件名称

    * @param string $tag 方法名(标签名)

    * @param Mixed $params 传入的参数

    * @return void

    */

    static public function exec($name, $tag,&$params=NULL) {

    if('Behavior' == substr($name,-8) ){

    // 行为扩展必须用run入口方法

    $tag = 'run';

    }

    $addon = new $name();

    return $addon->$tag($params);

    }

    以上内容仅供参考!

    展开全文
  • 提示无驱动电压源,这因为你的芯片管脚设置了电气属性造成的。有以下几种方式解决,看你喜欢 方式1.如果不仿真的话,就可以忽略。 方式2.在库里面将相对应的管脚修改其电气属性为passive就可以了。 见图: ...
  • MySQL 主从复制原理是啥?如何解决 MySQL 主从同步的延时问题? 考点分析 高并发这个阶段,肯定是需要做读写分离的,啥意思?因为实际上大部分的互联网公司,一些网站,或者是 app,其实都是读多写少。所以针对...
  • Drawcall的原理: 著作权归作者所有。 商业转载请联系作者获得授权,非商业转载请注明出处。 作者:Yubo Zhang 链接:http://www.zhihu.com/question/29730328/answer/45414167 来源:知乎 Draw call一般包含了要画...
  • CD4060芯片简介CD4060逻辑芯片一种内置振荡器的14分频串行计数器。其振荡频率可以使用外接阻容元件来确定,对于精度要求比较高的,也可以使用晶振来作为频率基准。CD4060内置了14级的分频器,方便根据实际的频率...
  • MySql的架构原理mysql架构原理图执行查询流程图执行修改语句执行流程MySQL Server架构自顶向下大致可以分网络连接层、服务层、存储引擎层和系统文件层网络连接层客户端连接器(Client Connectors ,和谁通信):提供与...
  • MySQL 主从复制原理是啥?如何解决 MySQL 主从同步的延时问题? 面试官心理分析 高并发这个阶段,肯定是需要做读写分离的,啥意思?因为实际上大部分的互联网公司,一些网站,或者是 app,其实都是读多写少。所以...
  • 平滑异同平均线(Moving Average Convergence Divergence)原理:MACD(Moving Average Convergence Divergence)中文名称:平滑异同移动平均线,由Gerald Appel首先在Systems And Forecasts一书中发表,主要利用...
  • MySQL 主从复制原理是啥?如何解决 MySQL 主从同步的延时问题? 考点分析 高并发这个阶段,肯定是需要做读写分离的,啥意思?因为实际上大部分的互联网公司,一些网站,或者是 app,其实都是读多写少。所以针对这...
  • MySQL 主从复制原理是啥?如何解决 MySQL 主从同步的延时问题?考点分析高并发这个阶段,肯定是需要做读写分离的,啥意思?因为实际上大部分的互联网公司,一些网站,或者是 app,其实都是读多写少。所以针对这个...
  • MySQL 主从复制原理是啥?如何解决 MySQL 主从同步的延时问题? 考点分析 高并发这个阶段,肯定是需要做读写分离的,啥意思?因为实际上大部分的互联网公司,一些网站,或者是 app,其实都是读多写少。所以针对...
  • ![图片说明](https://img-ask.csdn.net/upload/201912/11/1576033326_834412.png) 网上看hashmap原理,说entry对象保存在数组的bucket里,那这个图片上的linkedlist在bucket里的吗?
  • (一)分频器相关原理1.DDS原理任意分频原理起源于DDS(Direct Digital Synthesizer,直接频率合成法)的原理,DDS重要的频率合成方法,在波形发生器中占有举足轻重的地位。DDS一种从相位概念出发,直接合成所需要的...
  • 今天我们通过几个例子,来彻底搞清楚python3中的编码格式原理,这样你之后写python脚本时碰到编码问题,才能有章可循。我们先搞清楚几个概念:系统默认编码:指python解释器默认的编码格式,在python文件头部没有...
  • javascript中,new操作符的工作原理是什么?它是怎样改变构造函数的返回值和this指向的?下面这篇文章就来给大家介绍了关于Javascript中new()到底做了些什么的相关资料,需要的朋友可以参考下。前言和其他高级语言...
  • MySQL 主从复制原理是啥?如何解决 MySQL 主从同步的延时问题?考点分析高并发这个阶段,肯定是需要做读写分离的,啥意思?因为实际上大部分的互联网公司,一些网站,或者是 app,其实都是读多写少。所以针对这个...
  • /usr/sbin/lsof -p 26449看打开了哪些文件句柄不就知道是啥了如下:[root@SZOA04165 ~]# /usr/sbin/lsof -p 11843|moreCOMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAMEjava 11843 weblogic cwd D...
  • Pandas教程写的差不多了,来...这个系列会涉及Matplotlib的一些简单的概念、绘图原理、常见图形的绘制以及一些高阶的绘图技巧。学完之后,期待达到的效果可以用Matplotlib画出这样的图形。这篇文章先介绍一下Matpl...
  • 原理利用Android多用户的特性,对于不同的用户展示不同的桌面。所以需要在Launcher初始化的时候判断当前user。这个需要在framework中添加接口判断,不详说。这样,就有了两套桌面主题,一套的要求六边形的图标展示...
  • 高并发这个阶段,肯定需要做读写分离的,啥意思? 因为实际上大部分的互联网公司,一些网站,或者 app,其实都读多写少。 所以针对这个情况,就是写一个主库,但是主库挂多个从库,然后从多个从库来读,那不...
  • MySQL 主从复制原理是啥?如何解决 MySQL 主从同步的延时问题? 面试官心理分析 高并发这个阶段,肯定是需要做读写分离的,啥意思?因为实际上大部分的互联网公司,一些网站,或者是 app,其实都是读多写少。...
  • MySQL 主从复制原理是啥?如何解决 MySQL 主从同步的延时问题? 面试官心理分析 高并发这个阶段,肯定是需要做读写分离的,啥意思?因为实际上大部分的互联网公司,一些网站,或者是 app,其实都是读多写少。所以...
  • 高并发这个阶段,肯定需要做读写分离的,啥意思?因为实际上大部分的互联网公司,一些网站,或者 app,其实都读多写少。所以针对这个情况,就是写一个主库,但是主库挂多个从库,然后从多个从库来读,那不就...
  • 小皮2017-04-11 13:13:591楼以下代码用了ES6,取名比较随意s就是space,空格的意思,n要总次数,第二个参数输出的图形第一个很简单,累加就好了//ES6function first(n,print = "*"){for(let i = 0; i < n ;i++)...

空空如也

空空如也

1 2 3 4 5 ... 13
收藏数 242
精华内容 96
关键字:

原理是啥意思