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

初探AOP FOR PHP

編輯:關於PHP編程



問題
初探AOP FOR PHP
解決方法


AOP是OOP的延續,是Aspect Oriented Programming的縮寫,意思是面向方面編程。AOP實際是GoF設計模式的延續,設計模式孜孜不倦追求的是調用者和被調用者之間的解耦,AOP可以說也是這種目標的一種實現。其實這個技術在很久前就出現了。我google的時候已經是06年就出現的技術。
用我的理解是,在不破壞原有方法或者類的時候將函數的進行橫向切面。然後加進自己的方法處理。比如說,我們經常有一些方法執行之前要進行權限判斷。處理之後要進行日志寫入等等操作。一般的操作方式是在方法的頭部和底部寫處理過程。這就破壞了OOP的單一功能的原則。因為當有100甚至1000個方法要許進行同樣處理的時候,難免會出現一些不必要的錯誤。這就是AOP的實際運用。。。
我們寫一個函數輸出一些信息的時候,在處理前,不希望沒有權限看到這些信息的人來看。處理之後可能會寫入一些常用緩存信息。通常的寫法是這樣 class OneTest{

public function getInfo(){

//檢查一下權限

ACL::checkRole();

//做獲取信息的動作過程;

.....

//寫入緩存

Cache::writeCache();

}

}


復制代碼如果有1000個這樣需要做同樣操作的方法怎麼辦呢。。一處修改處處修改。難維護的情況就出現了。而用AOP的辦法去處理這個問題,就只需要這樣 class OneTest{

public function getInfo(){

//做獲取信息的動作過程;

.....

}

}


復制代碼這樣兩個破壞封裝的就拿出來在其他地方統一定義了。。。。。大體就是這麼一個意思。當然理解錯誤,誤人子弟純屬巧合。
詳細介紹大家可以google。。一些資料還沒整理。。。。。這還是忙裡偷閒的時候整出來的。
下面是幾個關於php的鏈接。有興趣的可以看一下
AOP FOR PHP探討
[url=http://blog.csdn.net/xiaoxiaohai123/archive/2008/06/30/2598377.aspx]鏈接標記http://blog.csdn.net/xiaoxiaohai123/archive/2008/06/30/2598377.aspx[/url]
PHP准AOP實現
[url=http://hi.baidu.com/thinkinginlamp/blog/item/864a0ef46d93b86eddc474f3.html]鏈接標記http://hi.baidu.com/thinkinginlamp/blog/item/864a0ef46d93b86eddc474f3.html[/url]
然後自己簡單實現了一下

/**

* TSAspect{

* AOP for php

* @package

* @version $id$

* @copyright 2009-2011 SamPeng

* @author SamPeng <[[email protected]][email protected][/email]>

* @license PHP Version 5.2 {@link [url=http://www.sampeng.cn]www.sampeng.cn[/url]}

*/

class TSAspect{

/**

* instance

* 方法所屬對象引用

* @var mixed

* @access private

*/

private $instance;

/**

* method

* 方法名

* @var mixed

* @access private

*/

private $method;



/**

* aspect

* 切面保存數組

* @var array

* @access private

*/

private $aspect = array();



/**

* __construct

* 構造函數查找出所有Aspect的實現方法

* @param mixed $instance

* @param mixed $method

* @param mixed $arg

* @access public

* @return void

*/

public function __construct( $instance,$method,$arg = null ){

$this->aspect = self::findFunction();

$this->instance = $instance;

$this->method = $method;

}



public function callAspect(){

$before_arg = $this->beforeFunction();

$callBack = array( $this->instance,$this->method);

$return = call_user_func_array( $callBack,$arg );

$this->afterFunction();

}





/**

* beforeFunction

* 方法之前執行的方法集合

* @static

* @access public

* @return void

*/

protected function beforeFunction(){

$result = $this->getFunction("before");

return $result;

}



/**

* afterFunction

* 方法之後執行的方法集合

* @static

* @access public

* @return void

*/

protected function afterFunction(){

$result = $this->getFunction( "after" );

}



/**

* findFunction

* 查找所有的Aspect的方法集合.

* @static

* @access private

* @return void

*/

private static function findFunction(){

$aspect = array();

foreach ( get_declared_classes() as $class ){

$reflectionClass = new ReflectionClass( $class );

if ( $reflectionClass->implementsInterface( 'InterfaceAspect' ) )

$aspect[] = $reflectionClass;

}

return $aspect;



}



/**

* getFunction

* 調用插入的方法

* @param mixed $aspect

* @static

* @access private

* @return void

*/

private function getFunction($aspect){

$result = array();

$array = $this->aspect;

foreach ( $array as $plugin ){

if ( $plugin->hasMethod($aspect ) ){

$reflectionMethod = $plugin->getMethod( $aspect );

if ( $reflectionMethod->isStatic() ){

$items = $reflectionMethod->invoke( null );

}else{

$pluginInstance = $plugin->newInstance();

$items = $reflectionMethod->invoke( $pluginInstance );

}

//處理經過處理的集合

if ( is_array( $items ) ){

$result = array_merge( $result,$items );

}

}

}

return $result;

}

}





interface InterfaceAspect{

public static function getName();

}



class testAspect implements InterfaceAspect{

public static function getName(){

return "這是一個測試AOP";

}



public static function before(){

echo "方法執行之前";

}

public static function after(){

echo "方法執行後
";

}

}



class test{

public function samTest($arg){

echo "這是一個測試方法";

}

}



$test = new test();

$aspect = new TSAspect($test,'samTest');

$aspect->callAspect();


復制代碼輸出:
方法執行之前
這是一個測試方法
方法執行之後


網友建意:
不懂,,,對開發思想有用不?
網友建意:
思想?這其實也是一種設計模式。。。。將破壞函數單一功能的部分耦合出來。。具體實現有很多辦法。。當然PHP的是准AOP。。因為他不能像java那樣的編譯語言在編譯時的時候插入橫切面處理過程。
網友建意:
新的事物總是被人華麗的無視。。。
網友建意:
去年就知道面向切面編程了,,,用不上,,,,呵呵,,,
網友建意:
剛剛接觸面向函數式編程,Haskell 、Erlang
網友建意:
PHP實現AOP要比Java簡單的多..因為有runkit
網友建意:
自己連OOP還沒大懂呢。技術啊。追不上。

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