插件结构的好处就是实现了项目的可插拔性,我给我的项目添加一个插件,我就可以使用该插件的功能,我把这个插件删除,界面也不再显示该插件的相关信息。
介绍一下项目结构:
项目使用CI框架,
application
|--plugin(添加plugin文件夹,放置实现pluginInterface接口的文件)
| |--pluginInterface.php (接口)
|--controllers
| |--plugin(添加plugin文件夹,放置插件中的controller)
|--views
| |--plugin(放置插件中的view)
首先为了方便管理插件,我们提供一个接口,所有的插件提供者按接口实现自己的插件。
例如我们提供如下的接口:
<?php interface pluginInterface { function getLevel(); function getName(); function getMenus(); function getDescription(); function getVersion(); function getReleaseDate(); function getProviderName(); } ?>
插件提供者实现该接口
<?php require_once dirname(dirname(dirname(__FILE__)))."/plugin/pluginInterface.php"; class xxxx implements pluginInterface{ function __construct() { } function getLevel(){ return 1; } function getName(){ return 'xxx'; } function getMenus(){ $sideBars ="<h3>xxx</h3> <ul class='toggle'> <li class='icn_my_application'> <a href='".site_url()."/plugin/xx/xxx' class='colorMediumBlue bold spanHover'>xx首页</a> </li> <li class='icn_add_apps'> <a href='".site_url()."/plugin/xxxxx/xxxx' class='colorMediumBlue bold spanHover'> xxxx</a></li> </ul>"; return $sideBars; } function getDescription(){} function getVersion(){} function getReleaseDate(){} function getProviderName(){} } ?>
插件管理类:pluginM.php
<?php class pluginM extends CI_Model { function __construct() { parent::__construct(); $this->load->helper('file'); $this->load->helper('path'); } function traverse($path ,$returnarr) { $entity = array(); $classname=array(); $current_dir = opendir($path); //opendir()返回一个目录句柄,失败返回false while(($file = readdir($current_dir)) !== false) { //readdir()返回打开目录句柄中的一个条目 $sub_dir = $path. $file; //构建子目录路径 if($file == '.' || $file == '..') { continue; } else {if(is_dir($sub_dir)) { //如果是目录,进行递归 $returnarr=$this->traverse($sub_dir."/",$returnarr); } else { //如果是文件 $index=strrpos ($file,"."); $filename=substr($file,0,$index); $entity=array( 'classpath'=>$path . $file, 'classname'=>$filename); array_push($returnarr, $entity); }} } return $returnarr; } function run($functionname,$par){ $dir=dirname(dirname(__FILE__))."/plugin/"; $returnarr=array(); $arr=$this->traverse($dir,$returnarr); for($i=0;$i<count($arr);$i++){ $classpat = $arr[$i]['classpath']; require_once ($classpat); $classname=$arr[$i]['classname']; if($classname=="pluginInterface"){ continue; } $reflectionClass = new ReflectionClass($classname); if ($reflectionClass->implementsInterface('pluginInterface')) { try { $cla= $reflectionClass->newInstance(); } catch (Exception $e) { continue; } if(method_exists($cla, $functionname)){ $function= $reflectionClass->getmethod($functionname); // $this->runfunction($classname,$classpat, "getName", $par); $str=$function->invoke($cla,$par); echo $str; } } } } } ?>
<?php $this->pluginM->run("getMenus","");?>