在較復雜的web程序開發中,由于采用面向對象的數據操作方式,或者業務邏輯太過復雜,開發人員在開發過程中,經常會無意識的重復讀取數據。
比如:
$result1 = tableobjectPeer::getResult($var1,$var2,$var3);
開發人員在需要的該table數據的時候,經常直接調用 tableobjectPeer::getResult方法。
又或者程序在進行forward的時候,也會導致重復調用 tableobjectPeer::getResult 方法,導致“重復讀”。
要避免類似的“重復讀”,最主要的辦法是,開發人員在代碼開發的時候,就要有“避免重復讀”的意識。
其實只要在:
$result1 = tableobjectPeer::getResult($var1,$var2,$var3);
之后,需要的地方進行
$result2 = $result1;
$result3 = $result1;
即可。這樣子就可以避免掉大量的“重復讀”了。
但是如果開放人員一開始沒有這樣做,那要進行這方面的重構可能是很大的工作量。
另外,由于框架中的forward()也容易造成“重復讀”。如果“重復讀”是forward()造成的,那該方法就不可行了(這點也許和不同的開發語言,不同的開發框架有關,在php的symfony框架中是如此)。
因此,在采用上面的方法進行優化的同時,對于一些較復雜的情況,決定采用另一種方式:使用static,設置變量為靜態變量,來避免重復讀取數據。
以下為引用的內容: <?php //要改寫的函數也請加上$is_static=1變量,用來控制是否開啟 static。 function staticFunc ($var1,$var2,$var3,$is_static=1) { if ( $is_static == 1 )//默認需要緩存函數結果 { static $result_array;//該數組用來保存函數的結果,支持不同參數的結果緩存 $vars_string = serialize( func_get_args() ); if ( empty( $result_array ) )//第一次運行需要初始化 { $result_array = array(); } if ( array_key_exists( $vars_string, $result_array ) )//參數已經存在 { return $result_array[$vars_string];//返回靜態變量中已經保存的結果 }else//參數不存在 { $result_array[$vars_string] = '';//后面會把結果補充進來 } }else//不利用static 緩沖結果 { if ( empty( $result_array ) ) { $result_array = array(); } } $result_array[$vars_string] = rand();//獲取結果,請把獲取的代碼放在此處即可 return $result_array[$vars_string]; } echo staticFunc(1,2,3); echo "<br>"; echo staticFunc(2,2,2); echo "<br>"; echo staticFunc(1,2,3); echo "<br>"; echo staticFunc(2,2,2); echo "<br>"; echo staticFunc(3,3,3); echo "<br>"; echo staticFunc(3,3,3,0); echo "<br>"; ?> |
運行上述代碼,產生的結果類似:
16667
8888
16667
8888
2193
1014
可以看出,第1行和第3行的結果一致,第2行和第4行的結果一致,說明只要函數的參數相同,函數結果就進行了有效的“cache”。
從第4行和第5行,可以看出,通過設置$is_static變量能有效控制是否開啟“cache”。
補充:上述使用static方法,可以有效的避免在一個線程內,重復讀取數據,但是該cache只存在一個線程內,不同線程是相互獨立的。雖然只是線程內的函數結果“cache”,但是其原理和其他方式的cache是類似的,就是要針對不同的參數(不同的情況)構造出cache的key。
轉自:http://www.cnblogs.com/rethink/