程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> PHP面向切面編程組件

PHP面向切面編程組件

編輯:關於PHP編程

我們使用MVC框架,例如CI、YII、cakePHP,原因之一就是:能夠使代碼便於維護。

但當業務邏輯不斷復雜時,在控制器中調用模型中的方法會越來越臃腫。

面向切面編程的思路,是解決不斷變化的業務邏輯與寫出便於維護代碼的解決方法之一。

 


下面是向切面式組件源碼,是根據AOP的思路設計的。

 

 

<?php 
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]); 
            } 
        } 
    } 

<?php
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]);
            }
        }
    }
}

 


<?php 
/**
 * 擴展家族
 *
 * @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); 
        } 
    } 

 
?> 
<?php
/**
 * 擴展家族
 *
 * @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);
        }
    }
}

?>

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

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

?>

以上三個文件實現了簡單的AOP組件。

 

下面是Demo:

<?php 
/**
 * 自定義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; 
        } 
    } 
 

 
?> 
<?php
/**
 * 自定義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
<?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); 
<?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);
運行結果:
此處是主要業務邏輯:訂單入庫
未登錄用戶,積分不錄入

 摘自 God's blog

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved