php递归函数原理,实例助你理解php递归函数原理及调用方法
小白們在學習遞歸函數的時候可能無法搞清楚遞歸函數的原理和運行機制,遞歸函數是常用到的一類函數,最基本的特點是函數自身調用自身,但必須在調用自身前有條件判斷,若滿足條件,則調用函數本身,若不滿足則終止本函數的自調用,然后把目前流程的主控權交回給上一層函數來執行,否則就會無限調用下去。下面先介紹php實現遞歸函數的3種基本方式。
一、利用引用做參數
先不管引用做不做參數,必須先明白引用到底是什么?引用不過是指兩個不同名的變量指向同一塊存儲地址。本來每個變量有各自的存儲地址,賦值刪除各行其道。現在可好,兩個變量共享一塊存儲地址。 $a=&$b; 。實際上指的是 $a 不管不顧自己原來的存儲地址,非要和 $b 共享一室了。因而任何對存儲地址數值的改變都會影響兩個值。
函數之間本來也是各行其是,即便是同名函數。遞歸函數是考慮將引用作為參數,成為一個橋梁,形成兩個函數間的數據共享。雖然兩個函數見貌似操作的是不同地址,但是實際上操作的是一塊兒內存地址。
function test($a=0,&$result=array()){
$a++;
if ($a<10) {
$result[]=$a;
test($a,$result);
}
echo $a;
return $result;
}上面的例子非常簡答,以a<10作為判斷條件,條件成立,則把a賦給result[];將result的引用傳入函數,會將每一次遞歸產生的a添加到結果數組result。因而本例生成的$result數組是 Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 [5] => 6 [6] => 7 [7] => 8 [8] => 9 ) 。
本例比較有意思的是echo a的值。相信很多人認為是12345678910吧,其實不然,是1098765432。為什么呢?因為函數還沒執行echoa前就進行了下一次的函數遞歸。真正執行echo a是當a<10條件不滿足的時候,echo a,返回result,對于上一層而言,執行完遞歸函數,開始執行本層的echo $a,依次類推。
二、利用全局變量
利用全局變量完成遞歸函數,請確保你確實理解什么是全局變量。global在函數內申明變量不過是外部變量的同名引用。變量的作用范圍仍然在本函數范圍內。改變這些變量的值,外部同名變量的值自然也改變了。但一旦用了&,同名變量不再是同名引用。利用全局變量實現遞歸函數沒必要理解到這么深的一層,還保持原有對全局變量的看法就可以順理成章理解遞歸函數。
function test($a=0,$result=array()){
global $result;
$a++;
if ($a<10) {
$result[]=$a;
test($a,$result);
}
return $result;
}
三、利用靜態變量
我們常常在類中見到static,今天我們把它利用到遞歸函數中。請記住static的作用:僅在第一次調用函數的時候對變量進行初始化,并且保留變量值。
舉個例子:
function test(){
static $count=0;
echo $count;
$count++;
}
test();
test();
test();
test();
test();這一段代碼的執行結果是多少?是00000么?必然不是。是01234。首先第一次調用test(),static對 $count 進行初始化,其后每一次執行完都會保留 $count 的值,不再進行初始化,相當于直接忽略了 static $count=0; 這一句。
因而將static應用到遞歸函數作用可想而知。在將需要作為遞歸函數間作為“橋梁"的變量利用static進行初始化,每一次遞歸都會保留"橋梁變量"的值。
function test($a=0){
static $result=array();
$a++;
if ($a<10) {
$result[]=$a;
test($a);
}
return $result;
}
小結
所謂遞歸函數,重點是如何處理函數調用自身是如何保證所需要的結果得以在函數間合理"傳遞",當然也有不需要函數之間傳值得遞歸函數,例如:
function test($a=0){
$a++;
if ($a<10) {
echo $a;
test($a);
}
}
php函數遞歸調用實例
function arrContentReplact($array)
{
if(is_array($array))
{
foreach($array as $k => $v)
{
$array[$k] = arrContentReplact($array[$k]);
}
}else
{
$array = str_replace(
array(''),
array('{', '}'),
$array
);
}
return $array;
}
$arr = array(array("< 小剛>","< 小曉>",array("",array(""))),"< 小飛>","< 小李>","< 小紅>");
$arr3 = arrContentReplact($arr);
echo "
";
print_r($arr3);
echo "
";
?>
PHP遞歸實現無限級分類
在一些復雜的系統中,要求對信息欄目進行無限級的分類,以增強系統的靈活性。那么PHP是如何實現無限級分類的呢?下面介紹一下使用遞歸算法并結合mysql數據表實現無限級分類的方法。
1、Mysql
首先我們準備一張數據表class,記錄商品分類信息。表中有三個字段,id:分類編號,主鍵自增長;title:分類名稱;pid:所屬上級分類id。
class表結構:
CREATE TABLE IF NOT EXISTS `class` (
`id` mediumint(6) NOT NULL AUTO_INCREMENT,
`title` varchar(30) NOT NULL,
`pid` mediumint(6) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
插入數據后,如圖:
2、PHP
根據不同的需求,我們提供兩種不同格式的自定義函數,一種是返回字符串,一種是返回數組,兩種函數都使用了遞歸方法。先看返回字符串格式的函數:
function get_str($id = 0) {
global $str;
$sql = "select id,title from class where pid= $id";
$result = mysql_query($sql);//查詢pid的子類的分類
if($result && mysql_affected_rows()){//如果有子類
$str .= '
- ';
while ($row = mysql_fetch_array($result)) { //循環記錄集
$str .= "
" . $row['id'] . "--" . $row['title'] . ""; //構建字符串get_str($row['id']); //調用get_str(),將記錄集中的id參數傳入函數中,繼續查詢下級
}
$str .= '
';}
return $str;
}以上函數get_str()通過遞歸,不斷查詢下級分類,并最終返回字符串,大家可以根據項目需求修改其中的str,最終生成一個無限分級列表:
include_once('connect.php'); //連接數據庫,connect.php文件自己寫一個啊
echo get_str(0); //輸出無限級分類
效果如圖:
接著我們來看返回數組格式的函數,一樣要使用遞歸:
function get_array($id=0){
$sql = "select id,title from class where pid= $id";
$result = mysql_query($sql);//查詢子類
$arr = array();
if($result && mysql_affected_rows()){//如果有子類
while($rows=mysql_fetch_assoc($result)){ //循環記錄集
$rows['list'] = get_array($rows['id']); //調用函數,傳入參數,繼續查詢下級
$arr[] = $rows; //組合數組
}
return $arr;
}
}函數get_array()返回了數組,這是我們期待的,所以推薦使用get_array()得到數組,這樣一來,我們可以對數組進行任意操作,比如我們可以將數組轉換成json格式的數據傳給前端頁面,前端頁面可以通過解析json數據靈活展示分類信息。比如樹形結構的分類列表,下拉分類列表等。
include_once('connect.php'); //連接數據庫
$list = get_array(0); //調用函數
print_r($list); //輸出數組
輸出效果:
如果要輸出json格式的數據,則可使用:
echo json_encode($list);
總結
以上是生活随笔為你收集整理的php递归函数原理,实例助你理解php递归函数原理及调用方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IBM刀片服务器管理模块恢复出厂默认值实
- 下一篇: bios sgx需要开启吗_惠普HP笔记