search
Homephp教程php手册PHP面向切面编程组件

PHP面向切面编程组件

Jun 13, 2016 am 10:46 AM
cakephpmvcphpyiigenerationusereasonusframecomponentsprogrammingFor

我们使用MVC框架,例如CI、YII、cakePHP,原因之一就是:能够使代码便于维护。

但当业务逻辑不断复杂时,在控制器中调用模型中的方法会越来越臃肿。

面向切面编程的思路,是解决不断变化的业务逻辑与写出便于维护代码的解决方法之一。

 


下面是向切面式组件源码,是根据AOP的思路设计的。

 

 

if (function_exists('__autoload')) { 
    trigger_error("Extension: It looks like your code is using an __autoload() function. Extension uses spl_autoload_register() which will bypass your __autoload() function and may break autoloading.", E_USER_WARNING); 

 
spl_autoload_register(array('ExtensionFactory', 'autoload')); 
 
class ExtensionFactory { 
     
    private static $extFamily = null; 
    private static $_classes = array( 
        'Extension' =>  '/Extension.php', 
        'ExtensionFamily' =>  '/ExtensionFamily.php' 
    ); 
     
    /**
     * Class autoloader. This method is provided to be invoked within an 
     * __autoload() magic method.
     * @param string $className The name of the class to load.
     */ 
    public static function autoload() { 
        foreach(self::$_classes as $v){ 
            require_once dirname(__FILE__) . $v; 
        } 
    } 
     
    /**
     * 必须先调用此方法来实例化扩展族,才能调用addExtension\removeExtension等
     * @return ExtensionFamily
     */ 
    public static function createExtension(){ 
        self::$extFamily = new ExtensionFamily(); 
        return self::$extFamily; 
    } 
     
    public static function removeExtension($extName){ 
        if(is_null(self::$extFamily)){ 
            throw new Exception("Please createExtension first"); 
            return false; 
        }else{ 
            unset(self::$extFamily->_extensionArray[$extName]); 
        } 
    } 
     
    public static function addExtension($extName, Extension $ext){ 
        if(is_null(self::$extFamily)){ 
            throw new Exception("Please createExtension first"); 
            return false; 
        }else{ 
            self::$extFamily->_extensionArray[$extName] = $ext; 
        } 
    } 
     
    public static function removeAllExtension(){ 
        if(is_null(self::$extFamily)){ 
            throw new Exception("Please createExtension first"); 
            return false; 
        }else{ 
            foreach(self::$extFamily->_extensionArray as $extName=>$ext){ 
                unset(self::$extFamily->_extensionArray[$extName]); 
            } 
        } 
    } 

if (function_exists('__autoload')) {
 trigger_error("Extension: It looks like your code is using an __autoload() function. Extension uses spl_autoload_register() which will bypass your __autoload() function and may break autoloading.", E_USER_WARNING);
}

spl_autoload_register(array('ExtensionFactory', 'autoload'));

class ExtensionFactory {
   
    private static $extFamily = null;
    private static $_classes = array(
        'Extension' =>  '/Extension.php',
        'ExtensionFamily' =>  '/ExtensionFamily.php'
    );
   
    /**
     * Class autoloader. This method is provided to be invoked within an
     * __autoload() magic method.
     * @param string $className The name of the class to load.
     */
    public static function autoload() {
        foreach(self::$_classes as $v){
            require_once dirname(__FILE__) . $v;
        }
    }
   
    /**
     * 必须先调用此方法来实例化扩展族,才能调用addExtension\removeExtension等
     * @return ExtensionFamily
     */
    public static function createExtension(){
        self::$extFamily = new ExtensionFamily();
        return self::$extFamily;
    }
   
    public static function removeExtension($extName){
        if(is_null(self::$extFamily)){
            throw new Exception("Please createExtension first");
            return false;
        }else{
            unset(self::$extFamily->_extensionArray[$extName]);
        }
    }
   
    public static function addExtension($extName, Extension $ext){
        if(is_null(self::$extFamily)){
            throw new Exception("Please createExtension first");
            return false;
        }else{
            self::$extFamily->_extensionArray[$extName] = $ext;
        }
    }
   
    public static function removeAllExtension(){
        if(is_null(self::$extFamily)){
            throw new Exception("Please createExtension first");
            return false;
        }else{
            foreach(self::$extFamily->_extensionArray as $extName=>$ext){
                unset(self::$extFamily->_extensionArray[$extName]);
            }
        }
    }
}

 


/**
 * 扩展家族
 *
 * @author Mr.Jin
 */ 
class ExtensionFamily implements Extension{ 
    public $_extensionArray = array(); 
     
    /**
     *
     * @param type $extName 扩展名
     * @param Extension $ext 实现Extension的对象
     */ 
    public function addExtension($extName, Extension $ext){ 
        $this->_extensionArray[$extName] = $ext; 
    } 
     
    public function beforeAppend(&$params){ 
        foreach($this->_extensionArray as $ext){ 
            $ext->beforeAppend($params); 
        } 
    } 
     
    public function afterAppend(&$params) { 
        foreach($this->_extensionArray as $ext){ 
            $ext->afterAppend($params); 
        } 
    } 

 
?> 
/**
 * 扩展家族
 *
 * @author Mr.Jin
 */
class ExtensionFamily implements Extension{
    public $_extensionArray = array();
   
    /**
     *
     * @param type $extName 扩展名
     * @param Extension $ext 实现Extension的对象
     */
    public function addExtension($extName, Extension $ext){
        $this->_extensionArray[$extName] = $ext;
    }
   
    public function beforeAppend(&$params){
        foreach($this->_extensionArray as $ext){
            $ext->beforeAppend($params);
        }
    }
   
    public function afterAppend(&$params) {
        foreach($this->_extensionArray as $ext){
            $ext->afterAppend($params);
        }
    }
}

?>

/**
 * 扩展接口
 *
 * @author Mr.Jin
 */ 
interface Extension { 
    public function beforeAppend(&$params); 
     
    public function afterAppend(&$params); 

 
?> 
/**
 * 扩展接口
 *
 * @author Mr.Jin
 */
interface Extension {
    public function beforeAppend(&$params);
   
    public function afterAppend(&$params);
}

?>

以上三个文件实现了简单的AOP组件。

 

下面是Demo:

/**
 * 自定义Extension
 * 用户积分Extension
 * 根据用户是否登录,决定此次消费是否记录用户积分
 *
 * @author Mr.Jin
 */ 
class ExampleExtension implements Extension { 
    public $check=false; 
     
    public function beforeAppend(&$isLogin) { 
        if($isLogin){ 
            $this->check = true; 
        } 
    } 
     
    public function afterAppend(&$pointer) { 
        if($this->check){ 
            //add pointer  
        }else{ 
            echo '未登录用户,积分不录入'; 
            return; 
        } 
    } 
 

 
?> 
/**
 * 自定义Extension
 * 用户积分Extension
 * 根据用户是否登录,决定此次消费是否记录用户积分
 *
 * @author Mr.Jin
 */
class ExampleExtension implements Extension {
 public $check=false;
   
    public function beforeAppend(&$isLogin) {
        if($isLogin){
         $this->check = true;
        }
    }
   
    public function afterAppend(&$pointer) {
        if($this->check){
         //add pointer
        }else{
         echo '未登录用户,积分不录入';
         return;
        }
    }

}

?>

 


demo.php
require_once('ExtensionFactory.php');//导入组件本身  
 
require_once('ExampleExtension.php');//导入扩展  
 
$ext = ExtensionFactory::createExtension(); 
 
ExtensionFactory::addExtension('example', new ExampleExtension());//积分录入功能  
 
/*
 * 按照需求的变化,可以增加相应的Extension.
 * eg.
 * 新需求:新增会员类型,根据不同类型,进行价格优惠。
 * 实现思路:
 * 一、建立卡号类型工厂
 * 二、建立SeniorMemberExtension、PuTongMeberExtension.
 * 三、工厂方法根据会员类型addExtension
 */ 
 
$isLogin = false; //假设用户未登录  
 
$ext->beforeAppend($isLogin); 
 
 
/**
 * 面向切面编程,最重要一点是:必须先分析出整个业务处理中,哪个才是重点。
 * 这里的重点是订单的入库。
 * 在订单入库之前可能业务逻辑不断增加,例如:登录验证、卡上余额验证等
 * 在订单入库之后:积分处理、订单监控等
 */ 
echo "此处是主要业务逻辑:订单入库\r\n"; 
 
$pointer = 100; 
 
$ext->afterAppend($pointer); 
require_once('ExtensionFactory.php');//导入组件本身

require_once('ExampleExtension.php');//导入扩展

$ext = ExtensionFactory::createExtension();

ExtensionFactory::addExtension('example', new ExampleExtension());//积分录入功能

/*
 * 按照需求的变化,可以增加相应的Extension.
 * eg.
 * 新需求:新增会员类型,根据不同类型,进行价格优惠。
 * 实现思路:
 * 一、建立卡号类型工厂
 * 二、建立SeniorMemberExtension、PuTongMeberExtension.
 * 三、工厂方法根据会员类型addExtension
 */

$isLogin = false; //假设用户未登录

$ext->beforeAppend($isLogin);


/**
 * 面向切面编程,最重要一点是:必须先分析出整个业务处理中,哪个才是重点。
 * 这里的重点是订单的入库。
 * 在订单入库之前可能业务逻辑不断增加,例如:登录验证、卡上余额验证等
 * 在订单入库之后:积分处理、订单监控等
 */
echo "此处是主要业务逻辑:订单入库\r\n";

$pointer = 100;

$ext->afterAppend($pointer);
运行结果:
此处是主要业务逻辑:订单入库
未登录用户,积分不录入

 摘自 God's blog

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

MantisBT

MantisBT

Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.

Dreamweaver Mac version

Dreamweaver Mac version

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool

WebStorm Mac version

WebStorm Mac version

Useful JavaScript development tools