老規矩,先上代碼再說話。
<?phpfunction showArray($cols){ foreach ($cols as $obj) { echo $obj . " "; } echo "<br>";}function showObj($obj){ echo $obj . " ";}//mswap傳入的是參考型別。function mswap(&$a,&$b){ $tmp=$a; $a=$b; $b=$tmp;}function bubbleSort(&$cols){ $len=count($cols); for ($i=0; $i <$len ; $i++) { for ($j=1; $j < $len-$i; $j++) { if ($cols[$j-1]>$cols[$j]) { mswap($cols[$j-1],$cols[$j]); } } }}$data = array(8,2,3,9,0,45,35,235);//排序bubbleSort($data);//列印數組showArray($data);//使用回呼函數依次遍曆列印數組array_map('showObj',$data);echo "<br>";//使用匿名函數遍曆列印數組array_map(create_function('$obj','echo $obj." " ;'),$data);echo "<br>";//使用新的方法(php5.3+)建立匿名函數array_map(function($obj){echo $obj. " ";},$data);//匿名函數捕獲外部變數$msg="val:";array_map(function($obj)use ($msg){echo $msg.$obj." ";},$data); ?>
程式的輸出:
代碼的功能十分簡單,先初始化一個數組,然後對其排序,最後使用三種不同的方式將其列印輸出。
排序的演算法使用最簡單的冒泡排序,不做贅述。
需要注意的有:
(1)排序函數和交換函數都使用了傳遞引用的方法。若使用傳值方式的話,排序和交換函數不會生效,因為此時函數實際上操作的是參數對象的拷貝。
(2)array_map是php內建的,其作用是為數組中的每個對象依次調用傳入的函數。此種方式稱為回調。
(3)create_function可以建立一個匿名函數。在最後一個列印樣本中,正是將其建立的匿名函數作為array_map的參數使用。
實際上有經驗的程式員都知道,不管是C++11還是php中,匿名函數的效率偏低的。那麼為什麼還要使用匿名函數呢。為什麼C#和java的新標準也紛紛支援它呢。
因為有名函數雖然看起來直觀,但是存在著管理的代價。多一個函數,就多一個需要管理的地方。而且對於一個“微型”的程式碼片段而言,單獨為其編寫一個有名函數亦顯得代碼不夠緊湊。然而這也絕不意味著匿名函數可以被濫用,在程式碼片段過大時,使用匿名函數會嚴重破壞可讀性。對匿名函數的使用要視情況而定。
create_function有一個問題,就是它建立的匿名函數要執行的代碼被放在一個字串中,易讀性不是很好。
所幸在php5.3+中有一個新函數用來建立匿名函數。來看看如何使用(依然通過匿名函數來遍曆數組)。
//使用新的方法(php5.3+)建立匿名函數array_map(function($obj){echo $obj. " ";},$data);
是不是優雅多了。 →_→...
還有一個問題:現在匿名函數只能使用它自己的參數,如果它需要使用自己範圍外部的變數怎麼辦呢。php中的use關鍵字對此提供了支援:
//匿名函數捕獲外部變數$msg="val:";array_map(function($obj)use ($msg){echo $msg.$obj." ";},$data);
此時輸出為:
val:0 val:2 val:3 val:8 val:9 val:35 val:45 val:235
另外本例中的array_map對數組只是實行了遍曆,回呼函數未改變數組中的元素。若回呼函數要改變數組的內容,則需要通過傳回值來接收。
php中另有一個array_walk函數,功能與array_map一樣,但是在回呼函數需要改變數組中的資料的時候,它是通過傳遞數組的引用來完成。
來看看樣本:
<?phpfunction f1($n){ $n *= 100; return $n;}//f2的參數是參考型別function f2(&$n){ $n /= 100;}$data = array( 1, 2, 3, 4, 5);//array_map通過傳回值來接收改動過的數組$data = array_map("f1", $data);var_dump($data);//array_walk通過傳遞引用改變數組的值array_walk($data, "f2");echo "<br>";var_dump($data);?>
代碼也很簡單,使用array_map依次調用回調f1將數組中的每個值乘以100,然後再使用array_walk依次調用回調f2將數組中的每個值除以100。
如果不希望回呼函數會改變數組的值的話,f1改為不傳回值,f2改為不傳遞引用即可做到。