php递归函数 如何理解php中的递归函数 (详细讲解)
亲爱的读者们,你是否对php递归函数和如何理解php中的递归函数 (详细讲解)的相关问题感到困惑?别担心,今天我将为你解答这些问题,让你对此有更清晰的认识。
PHP怎么递归
下面我举一个其他的例子,虽然不是族谱,但是原理都是一样的。
在一些复杂的系统中,要求对信息栏目进行无限级的分类,以增强系统的灵活性。那么PHP是如何实现无限级分类的呢?我们在本文中使用递归算法并结合mysql数据表实现无限级分类。
递归,简单的说就是一段程序代码的重复调用,当把代码写到一个自定义函数中,将参数等变量保存,函数中重复调用函数,直到达到某个条件才跳出,返回相应的数据。
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;
插入数据后,如图:
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.='<ul>';
while($row= mysql_fetch_array($result)){//循环记录集
$str.="<li>".$row['id']."--".$row['title']."</li>";//构建字符串
get_str($row['id']);//调用get_str(),将记录集中的id参数传入函数中,继续查询下级
}
$str.='</ul>';
}
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实现递归的方法是:1、利用引用做参数,代码为【$result[]=$a;test($a,$result)】;2、利用全局变量;3、利用静态变量,代码为【static$count=0;】。
【相关学习推荐:php图文教程】
php实现递归的方法是:
一、利用引用做参数
先不管引用做不做参数,必须先明白引用到底是什么?引用不过是指两个不同名的变量指向同一块存储地址。本来每个变量有各自的存储地址,赋值删除各行其道。现在可好,两个变量共享一块存储地址。$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,依次类推。
例子二、
PHP的引用允许用两个变量来指向同一个内容,例如$a=&$b;这意味着$a和$b指向了同一个变量。
如下例子,因为$data使用了引用传递,所以数据会一直累加。
function recursion(&$data= [],$i= 0)
{
if($i< 10){
$data[]=$i;
$i++;
$this->recursion($data,$i);
}
return$data;
}
//调用
$this->recursion();// [0,1,2,3,4,5,6,7,8,9]二、利用全局变量
利用全局变量完成递归函数,请确保你确实理解什么是全局变量。global在函数内申明变量不过是外部变量的同名引用。变量的作用范围仍然在本函数范围内。改变这些变量的值,外部同名变量的值自然也改变了。但一旦用了&,同名变量不再是同名引用。利用全局变量实现递归函数没必要理解到这么深的一层,还保持原有对全局变量的看法就可以顺理成章理解递归函数。
function test($a=0,$result=array()){
global$result;
$a++;
if($a<10){
$result[]=$a;
test($a,$result);
}
return$result;
}global在函数内申明变量不过是外部变量的同名引用。变量的作用范围仍然在本函数范围内。改变这些变量的值,外部同名变量的值自然也改变了。
function recursion($data= [],$i= 0)
{
global$data;
if($i< 10){
$data[]=$i;
$i++;
$this->recursion($data,$i);
}
return$data;
}
//调用
$this->recursion();// [0,1,2,3,4,5,6,7,8,9]三、利用静态变量
我们常常在类中见到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 recursion($i= 0)
{
static$data= [];
if($i< 10){
$data[]=$i;
$i++;
$this->recursion($i);
}
return$data;
}
//调用
$this->recursion();// [0,1,2,3,4,5,6,7,8,9]相关学习推荐:php编程(视频)
如何理解php中的递归函数 (详细讲解)
递归其实就是“一个函数的自调用”
在这个“自调用”的过程中,必须要有一个变化的“参数”,当这个“参数”达到你的期望值的时候,终止该“自调用”过程
拿楼主的程序来说
demo($n)内部又有调用demo($n-1),构成了“自调用”
且,$n又有一个“期望值”,即是$n>1,不满足此条件时,该自调用终止
即是说,最后一个执行的demo是demo($n9-1),其中$n9=2,然后返回为1(因为执行了return 1)
则$n9*demo($n9-1)即等于 2*demo(2-1),又等于2*1=2;
则$n8*demo($n8-1)即等于 3*demo(3-1),又等于3*2=6;
则$n7*demo($n7-1)即等于 4*demo(4-1),又等于4*6=24;
……
依次类推
这样想:
demo(1)是等于1,这个没有疑问吧?
然后demo(2)等于2*demo(1)=2*1=2
然后demo(3)等于3*demo(2)=3*2=6
……
一直到demo(10)
非常感谢您的阅读!我们希望本文对于解决您关于php递归函数和如何理解php中的递归函数 (详细讲解)的问题提供了一些有价值的信息。如果您还有其他疑问,我们将很乐意为您提供进一步的帮助。