php把文件设置为插件
<img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"><p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">php中文网最新课程</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">每日17点准时技术干货分享</span></p><span style="color: black;"><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"></span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><strong style="color: blue;">PHP中插件机制的一种实现<span style="color: black;">方法</span></strong></span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">插件,<span style="color: black;">也</span>即Plug-in,<span style="color: black;">指的是</span>一类特定的功能模块(<span style="color: black;">一般</span>由第三方<span style="color: black;">研发</span>者实现),它的特点是:当你需要它的时候激活它,不需要它的时候禁用/删除它;</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">且无 论是激活还是禁用都不影响系统核心模块的运行,<span style="color: black;">亦</span><span style="color: black;">便是</span>说插件是一种非侵入式的模块化设计,实现了核心程序与插件程序的松散耦合。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">一个典型的例子<span style="color: black;">便是</span> Wordpress中众多的第三方插件,<span style="color: black;">例如</span>Akimet插件用于对用户的评论进行Spam过滤。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">一个健壮的插件机制,我认为必须具备以下特点:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">● 插件的动态监听和加载(Lookup)</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">● 插件的动态触发</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">以上两点的实现均不影响核心程序的运行</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">要在程序中实现插件,<span style="color: black;">咱们</span><span style="color: black;">首要</span>应该想到的<span style="color: black;">便是</span>定义<span style="color: black;">区别</span>的钩子(Hooks);“钩子”是一个很形象的<span style="color: black;">规律</span>概念,你<span style="color: black;">能够</span>认为它是系统预留的插件触发<span style="color: black;">要求</span>。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">它 的<span style="color: black;">规律</span>原理如下:当系统执行到某个钩子时,会判断这个钩子的<span style="color: black;">要求</span><span style="color: black;">是不是</span>满足;<span style="color: black;">倘若</span>满足,会转而先去调用钩子所制定的功能,<span style="color: black;">而后</span>返回继续执行余下的程序;</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">倘若</span> 不满足,跳过<span style="color: black;">就可</span>。这有点像汇编中的“中断<span style="color: black;">守护</span>”<span style="color: black;">规律</span>。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">某些钩子可能是系统事先就设计好的,<span style="color: black;">例如</span>之前我举的关于评论Spam过滤的钩子,<span style="color: black;">一般</span>它<span style="color: black;">已然</span>由核心系统<span style="color: black;">研发</span>人员设计进了评论的处理<span style="color: black;">规律</span>中;</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">另一</span>一类钩子则 可能<span style="color: black;">是由于</span>用户<span style="color: black;">自动</span>定制的(由第三方<span style="color: black;">研发</span>人员制定),<span style="color: black;">一般</span>存在于表现层,<span style="color: black;">例如</span>一个普通的PHP表单<span style="color: black;">表示</span>页面中。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">可能你感觉上面的话比较无聊,让人昏昏欲睡;<span style="color: black;">然则</span>要看懂下面我写的代码,理解以上的原理是必不可少的。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">下面进行PHP中插件机制的核心实现,<span style="color: black;">全部</span>机制核心分为三大块:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">一个插件经理类:这是核心之核心。它是一个应用程序全局Global对象。它<span style="color: black;">重点</span>有三个职责:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">● 负责监听<span style="color: black;">已然</span>注册了的所有插件,并实例化这些插件对象。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">● 负责注册所有插件。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">● 当钩子<span style="color: black;">要求</span>满足时,触发对应的对象<span style="color: black;">办法</span>。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">插件的功能实现:这大多由第三方<span style="color: black;">研发</span>人员完成,但需要遵循<span style="color: black;">必定</span>的规则,这个规则是插件机制所规定的,因插件机制的<span style="color: black;">区别</span>而<span style="color: black;">区别</span>,下面的<span style="color: black;">表示</span>代码你会看到这个规则。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">插件的触发:<span style="color: black;">亦</span><span style="color: black;">便是</span>钩子的触发<span style="color: black;">要求</span>。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">详细</span><span style="color: black;">来讲</span>这是一小段代码,<span style="color: black;">安置</span>在你需要插件实现的<span style="color: black;">地区</span>,用于触发这个钩子。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">原理讲了一大堆,下面<span style="color: black;">瞧瞧</span>我的实现<span style="color: black;">方法</span>:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">插件经理PluginManager类:</span></p><span style="color: black;"><?</span><span style="color: black;">/**</span><span style="color: black;">* STBLOG PluginManager Class</span><span style="color: black;">*</span><span style="color: black;">* 插件机制的实现核心类</span><span style="color: black;">*</span><span style="color: black;">* @package STBLOG</span><span style="color: black;">* @subpackage Libraries</span><span style="color: black;">* @category Libraries</span><span style="color: black;">* @author Saturn</span><span style="color: black;">*/</span><span style="color: black;">class PluginManager</span><span style="color: black;">{</span><span style="color: black;"> /**</span><span style="color: black;"> * 监听已注册的插件</span><span style="color: black;"> *</span><span style="color: black;"> * @access private</span><span style="color: black;"> * @var array</span><span style="color: black;"> */</span><span style="color: black;"> private $_listeners = array();</span><span style="color: black;"> /**</span><span style="color: black;"> * 构造函数</span><span style="color: black;"> * </span><span style="color: black;"> * @access public</span><span style="color: black;">* @return void</span><span style="color: black;"> */</span><span style="color: black;"> public function __construct()</span><span style="color: black;">{</span><span style="color: black;"> #<span style="color: black;">这儿</span>$plugin数组<span style="color: black;">包括</span><span style="color: black;">咱们</span>获取<span style="color: black;">已然</span>由用户激活的插件信息</span><span style="color: black;"> #为演示方便,<span style="color: black;">咱们</span>假定$plugin中<span style="color: black;">最少</span><span style="color: black;">包括</span></span><span style="color: black;"> #$plugin = array(</span><span style="color: black;"> # name => 插件名<span style="color: black;">叫作</span>,</span><span style="color: black;"> # directory=>插件安装目录</span><span style="color: black;"> #);</span><span style="color: black;">$plugins = get_active_plugins();#这个函数请<span style="color: black;">自动</span>实现</span><span style="color: black;"> if($plugins)</span><span style="color: black;"> {</span><span style="color: black;"> foreach($plugins as $plugin)</span><span style="color: black;"> {//假定<span style="color: black;">每一个</span>插件文件夹中<span style="color: black;">包括</span>一个actions.php文件,它是插件的<span style="color: black;">详细</span>实现</span><span style="color: black;">if (@file_exists(STPATH .plugins/.$plugin./actions.php))</span><span style="color: black;"> {</span><span style="color: black;"> include_once(STPATH .plugins/.$plugin./actions.php);</span><span style="color: black;"> $class = $plugin._actions;</span><span style="color: black;">if (class_exists($class))</span><span style="color: black;"> {</span><span style="color: black;"> //初始化所有插件</span><span style="color: black;"> new $class($this);</span><span style="color: black;"> }</span><span style="color: black;"> }</span><span style="color: black;"> }</span><span style="color: black;"> }</span><span style="color: black;"> #此处做些日志记录方面的东西</span><span style="color: black;"> }</span><span style="color: black;"> /**</span><span style="color: black;"> * 注册需要监听的插件<span style="color: black;">办法</span>(钩子)</span><span style="color: black;"> *</span><span style="color: black;"> * @param string $hook</span><span style="color: black;"> * @param object $reference</span><span style="color: black;"> * @param string $method</span><span style="color: black;"> */</span><span style="color: black;">function register($hook, &$reference, $method)</span><span style="color: black;">{</span><span style="color: black;"> //获取插件要实现的<span style="color: black;">办法</span></span><span style="color: black;"> $key = get_class($reference).->.$method;</span><span style="color: black;"> //将插件的引用连同<span style="color: black;">办法</span>push进监听数组中</span><span style="color: black;">$this->_listeners[$hook][$key] = array(&$reference, $method);</span><span style="color: black;"> #此处做些日志记录方面的东西</span><span style="color: black;"> }</span><span style="color: black;"> /**</span><span style="color: black;"> * 触发一个钩子</span><span style="color: black;"> *</span><span style="color: black;"> * @param string $hook 钩子的名<span style="color: black;">叫作</span></span><span style="color: black;"> * @param mixed $data 钩子的入参</span><span style="color: black;"> * @return mixed</span><span style="color: black;"> */</span><span style="color: black;">function trigger($hook, $data=)</span><span style="color: black;">{</span><span style="color: black;"> $result = ;</span><span style="color: black;"> //查看要实现的钩子,<span style="color: black;">是不是</span>在监听数组之中</span><span style="color: black;"> if (isset($this->_listeners[$hook]) && is_array($this->_listeners[$hook]) && count($this->_listeners[$hook]) > 0)</span><span style="color: black;"> {</span><span style="color: black;">// 循环调用<span style="color: black;">起始</span></span><span style="color: black;"> foreach ($this->_listeners[$hook] as $listener)</span><span style="color: black;"> {</span><span style="color: black;"> // 取出插件对象的引用和<span style="color: black;">办法</span></span><span style="color: black;"> $class =& $listener;</span><span style="color: black;"> $method = $listener;</span><span style="color: black;"> if(method_exists($class,$method))</span><span style="color: black;"> {</span><span style="color: black;">// 动态调用插件的<span style="color: black;">办法</span></span><span style="color: black;"> $result .= $class->$method($data);</span><span style="color: black;"> }</span><span style="color: black;"> }</span><span style="color: black;"> }</span><span style="color: black;"> #此处做些日志记录方面的东西</span><span style="color: black;"> return $result;</span><span style="color: black;"> }</span><span style="color: black;">}</span><span style="color: black;">?></span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">以上代码加上注释不超过100行,就完<span style="color: black;">成为了</span><span style="color: black;">全部</span>插件机制的核心。</span><span style="color: black;">需要再次说明的是,你必须将它设置成全局类,在所有 需要用到插件的<span style="color: black;">地区</span>,优先加载。</span></span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">用#注释的<span style="color: black;">地区</span>是你需要<span style="color: black;">自动</span>完成的部分,<span style="color: black;">包含</span>插件的获取和日志记录等等。</span></span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">下面是一个简单插件的实现。 </span></p><span style="color: black;"><?</span><span style="color: black;">/**</span><span style="color: black;">* 这是一个Hello World简单插件的实现</span><span style="color: black;">*</span><span style="color: black;">* @package DEMO</span><span style="color: black;">* @subpackage DEMO</span><span style="color: black;">* @category Plugins</span><span style="color: black;">* @author Saturn</span><span style="color: black;">*/</span><span style="color: black;">/**</span><span style="color: black;">*需要<span style="color: black;">重视</span>的几个默认规则:</span><span style="color: black;">* 1. 本插件类的文件名必须是action</span><span style="color: black;">* 2. 插件类的名<span style="color: black;">叫作</span>必须是{插件名_actions}</span><span style="color: black;">*/</span><span style="color: black;">class DEMO_actions</span><span style="color: black;">{</span><span style="color: black;"> //解析函数的参数是pluginManager的引用</span><span style="color: black;"> function __construct(&$pluginManager)</span><span style="color: black;">{</span><span style="color: black;">//注册这个插件</span><span style="color: black;"> //<span style="color: black;">第1</span>个参数是钩子的名<span style="color: black;">叫作</span></span><span style="color: black;"> //第二个参数是pluginManager的引用</span><span style="color: black;"> //第三个是插件所执行的<span style="color: black;">办法</span></span><span style="color: black;"> $pluginManager->register(demo, $this, say_hello);</span><span style="color: black;"> }</span><span style="color: black;"> function say_hello()</span><span style="color: black;">{</span><span style="color: black;"> echo Hello World;</span><span style="color: black;"> }</span><span style="color: black;">}</span><span style="color: black;">?></span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">这是一个简单的Hello World插件,用于输出一句话。</span></span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">在<span style="color: black;">实质</span><span style="color: black;">状况</span>中,say_hello可能<span style="color: black;">包含</span>对数据库的操作,<span style="color: black;">或</span>是其他<span style="color: black;">有些</span>特定的<span style="color: black;">规律</span>,<span style="color: black;">例如</span>调用Akimet API。</span></span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">插件实现的默认规则由核心系统<span style="color: black;">研发</span>者<span style="color: black;">自动</span>确定。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">例如</span>本例的<span style="color: black;">有些</span>默认规则我在注释中<span style="color: black;">已然</span>写的很清楚,<span style="color: black;">这里</span>不在赘述。需要<span style="color: black;">尤其</span><span style="color: black;">重视</span>的是钩子名<span style="color: black;">叫作</span>不要重复。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">最后一步,<span style="color: black;">便是</span>定义钩子的触发,你将钩子放在哪里,上面这个插件的<span style="color: black;">办法</span>就会在哪里出发。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">例如</span>我要将say_hello放到我博客首页Index.php, <span style="color: black;">那样</span>你在index.php中的某个位置写下:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">$pluginManager->trigger(demo,);</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;"><span style="color: black;">第1</span>个参数<span style="color: black;">暗示</span>钩子的名字,在本例中它是demo;</span></span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">第二个参数是插件对应<span style="color: black;">办法</span>的入口参数,<span style="color: black;">因为</span>这个例子中<span style="color: black;">无</span>输入参数,<span style="color: black;">因此</span>为空。</span></span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><strong style="color: blue;">总结</strong></span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">本篇<span style="color: black;">文案</span>介绍了插件机制在PHP中实现的一种<span style="color: black;">办法</span>和思路,以及我<span style="color: black;">自己</span>对插件机制的理解。初次接触这个东西,可能会比较生涩,难以理解。<span style="color: black;">然则</span>当你结合真实的</span><span style="color: black;">例子,再想想程序的运行流程,思路可能会更清晰<span style="color: black;">有些</span>。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/mmbiz_png/QicyPhNHD5vZ3Txm1k8cuNfHWPCVgS2F5kKTm9MalhVfvXiaTBy8ia1rH39Jicc03tCXCzzMz4Hico0xLRVLmibQiaEYA/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/mmbiz_png/QicyPhNHD5vZ3Txm1k8cuNfHWPCVgS2F5uadFxIVyJpwZg23B8DWnOKHibraia5DtWqoB1ic6r0KQUI5HDcmY30obQ/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><a style="color: black;"><span style="color: black;"><img src="https://mmbiz.qpic.cn/mmbiz_png/Lhm5kkN9JXO5BZicyutiaXYPlsEGtictxamrMiaPJ5ZZt8Vgbec2F2iaqzCAVKtuF0nO6k4qa3c9aAskc10fzb6VljA/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></span></a></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">▼</span><span style="color: black;">请点击下方:“阅读原文”,</span><span style="color: black;">在线</span><span style="color: black;">查看<span style="color: black;">所有</span><span style="color: black;">文案</span>内容!</span></span></p>
你的见解真是独到,让我受益良多。 你说得对,我们一起加油,未来可期。 外链发布社区 http://www.fok120.com/ i免费外链发布平台 http://www.fok120.com/
页:
[1]