随机数,满足范围和,才返回,递归造成了栈溢出,请大神给出解决方案

jz15136122392 2014-03-31 04:15:05
function   get_rand_array(){
for($h=0;$h<=$_POST['peoplenum'];$h++){
$total[$h]=$this->moneyrand($_POST['endnum']);
if($total[$h]['total']>$_POST['startnum'] && $total[$h]['total']<$_POST['endnum']){
$user->query("SET NAMES utf8");
$data=$user->query("SELECT * FROM `m_user` WHERE id >= (SELECT floor(RAND() * (SELECT MAX(id) FROM `m_user`)))
ORDER BY id LIMIT ".$_POST['peoplenum']."; ",'select');//随机抽取
}else{

$total[$h]=call_user_func_array(array('Index','rechangeadd'),array($_POST['startnum'],$_POST['endnum']));
if(!is_callable($total[$h])){
$total[$h]=$this->rechangeadd($_POST['startnum'],$_POST['endnum']);
}

}
return $total;
}
function moneyrand($endnum){

$money=array('10','50','100');
$money_rand=mt_rand(0,2);
$total['max_10']=$max_10=$endnum/10;
$total['max_10']=$max_10=$endnum/10;
$total['max_50']=$max_50=$endnum/50;
$total['max_100']=$max_100=$endnum/100;
$rand_10=mt_rand(0,50);
$rand_50=mt_rand(0,$max_50);
$rand_100=mt_rand(0,$max_100);
//随机10元充值
$total['rand_10']=$rand_10;
$total['rand_50']=$rand_50;
$total['rand_100']=$rand_100;
$total['total']=$money[0]*$rand_10+$money[1]*$rand_50+$money[2]*$rand_100;
return $total;
}
这个随机数,范围做了限制以后,还是会报出
Fatal error: Maximum function nesting level of '100' reached, aborting!的错误
这个错误是递归造成了栈溢出,请大神给出解决方案
...全文
444 35 打赏 收藏 转发到动态 举报
写回复
用AI写文章
35 条回复
切换为时间正序
请发表友善的回复…
发表回复
傲雪星枫 2014-04-01
  • 打赏
  • 举报
回复
先不考虑生成很大数据,你先做一个生成10个数据的程序,没问题了,再改成生成很大数据就简单了。 我看了你的程序,思路不明确。请给出如何才算符合条件的数。
just_for_download1 2014-04-01
  • 打赏
  • 举报
回复
如果从一开始思路都错了,还需要去优化吗?
xuzuning 2014-03-31
  • 打赏
  • 举报
回复
我要你给出你的算法的文字描述! 因为你的程序是有问题的,我不可能从错误的程序中抽象出你的算法 call_user_func_array 不能消除递归,只是用于动态调用函数
jz15136122392 2014-03-31
  • 打赏
  • 举报
回复
引用 31 楼 xuzuning 的回复:
不错,你现在的目的是优化程序 但这个程序期望达到什么目的? 这你并没有说清楚
功能就是一个模拟用户充值的东西,数据量很大,一次需要生成很大数据量,而这个随机数的变化是不能控制的,所以要考虑到大数据量的时候会报出 Fatal error: Maximum function nesting level of '100' reached, aborting!的错误,我查阅资料,看到,可以用 call_user_func_array()来消除递归,所以就想要把这个优化一下,但是call_user_func_array()在类中,还是返回null
xuzuning 2014-03-31
  • 打赏
  • 举报
回复
不错,你现在的目的是优化程序 但这个程序期望达到什么目的? 这你并没有说清楚
jz15136122392 2014-03-31
  • 打赏
  • 举报
回复
引用 29 楼 xuzuning 的回复:
现在的问题在于你似乎并不知道你想做什么,完全是在用代码做文字游戏 没有目标如何能写好程序
因为随机数的不确定因素,还有取值范围问题,就会有这个问题 我现在的目标就是把moneyrand()返回值在callbacktotal()调取返回 用call_user_func_array()函数吧递归优化了,就这么简单
xuzuning 2014-03-31
  • 打赏
  • 举报
回复
现在的问题在于你似乎并不知道你想做什么,完全是在用代码做文字游戏 没有目标如何能写好程序
jz15136122392 2014-03-31
  • 打赏
  • 举报
回复
引用 26 楼 xuzuning 的回复:
moneyrand 方法对了,是这个意思 rechangeadd 方法至少需要有 return $total; 不然你算了半天不是白算了吗?
我在rechangeadd()中这样调用了 for($h=0;$h<=$_POST['peoplenum'];$h++){ $total[$h]=$this->callbacktotal(array('Index','moneyrand'),array($_POST['endnum'],$_POST['startnum'])); } 我写了一个callbacktotal()专门来调用call_user_func_array(); function callbacktotal($callback,$params){ //P($callback); //p($params); $result=call_user_func_array($callback,$params); while(is_callable($reuslt)){ return $result; } } function moneyrand($endnum,$startnum){ // P($endnum); // p($startnum); $money=array('10','50','100'); $money_rand=mt_rand(0,2); $total['max_10']=$max_10=$endnum/10; $total['max_10']=$max_10=$endnum/10; $total['max_50']=$max_50=$endnum/50; $total['max_100']=$max_100=$endnum/100; $rand_10=mt_rand(0,50); $rand_50=mt_rand(0,$max_50); $rand_100=mt_rand(0,$max_100); //随机10元充值 $total['rand_10']=$rand_10; $total['rand_50']=$rand_50; $total['rand_100']=$rand_100; $total['total']=$money[0]*$rand_10+$money[1]*$rand_50+$money[2]*$rand_100; if($total['total']>$startnum && $total['total']<$endnum){ return $total; }else{ return $this->moneyrand($startnum,$endnum); } } 我这样写有错么?为什么返回的还null呢?
jz15136122392 2014-03-31
  • 打赏
  • 举报
回复
引用 26 楼 xuzuning 的回复:
moneyrand 方法对了,是这个意思 rechangeadd 方法至少需要有 return $total; 不然你算了半天不是白算了吗?
您能加我QQ么,329297103,我改到这儿,改不下去了!盲区了
xuzuning 2014-03-31
  • 打赏
  • 举报
回复
moneyrand 方法对了,是这个意思 rechangeadd 方法至少需要有 return $total; 不然你算了半天不是白算了吗?
jz15136122392 2014-03-31
  • 打赏
  • 举报
回复
如果这个和,符合,就会执行一次插入数据,如果不符合
引用 23 楼 xuzuning 的回复:
返回的和如果在 传递的金额范围内,就调用这三个随机数,进行数据插入,如果不在金额范围内容,重新再调用 重新调用是从头来过吗?原来符合的也从新算? 在不在范围里 的判断要在 moneyadd 中进行,使得 moneyadd 总是返回合适的数据
如果这个和,符合要求范围,就会执行一次插入数据,如果不符合,就会重新调随机三个随机数,直到符合位置,我把符合条件的随机数放到了$total数组里面 for($h=0;$h<=$_POST['peoplenum'];$h++){ $total[$h]=$this->callbacktotal(array('Index','moneyrand'),array($_POST['endnum'],$_POST['startnum'])); }
jz15136122392 2014-03-31
  • 打赏
  • 举报
回复
引用 23 楼 xuzuning 的回复:
返回的和如果在 传递的金额范围内,就调用这三个随机数,进行数据插入,如果不在金额范围内容,重新再调用 重新调用是从头来过吗?原来符合的也从新算? 在不在范围里 的判断要在 moneyadd 中进行,使得 moneyadd 总是返回合适的数据
您帮我看下,我大概按照您的意思来改了一下,我粘贴一部分重要的部分,我把求和范围是否符合加到了moneyrand()里了; function callbacktotal($callback,$params){ // P($callback); // p($params); $result=call_user_func_array($callback,$params); while(is_callable($reuslt)){ return $result; } } function rechangeadd($start,$end){ $starttime=strtotime($_POST['starttime']); $endtime =strtotime($_POST['endtime']); $user=D('user'); if(!empty($_POST['startnum']) && !empty($_POST['endnum'])){ $user->query("SET NAMES utf8"); $data=$user->query("SELECT * FROM `m_user` WHERE id >= (SELECT floor(RAND() * (SELECT MAX(id) FROM `m_user`))) ORDER BY id LIMIT ".$_POST['peoplenum']."; ",'select');//随机抽取 for($h=0;$h<=$_POST['peoplenum'];$h++){ $total[$h]=$this->callbacktotal(array('Index','moneyrand'),array($_POST['endnum'],$_POST['startnum'])); } } function moneyrand($endnum,$startnum){ P($endnum); p($startnum); $money=array('10','50','100'); $money_rand=mt_rand(0,2); $total['max_10']=$max_10=$endnum/10; $total['max_10']=$max_10=$endnum/10; $total['max_50']=$max_50=$endnum/50; $total['max_100']=$max_100=$endnum/100; $rand_10=mt_rand(0,50); $rand_50=mt_rand(0,$max_50); $rand_100=mt_rand(0,$max_100); //随机10元充值 $total['rand_10']=$rand_10; $total['rand_50']=$rand_50; $total['rand_100']=$rand_100; $total['total']=$money[0]*$rand_10+$money[1]*$rand_50+$money[2]*$rand_100; if($total['total']>$startnum && $total['total']<$endnum){ return $total; }else{ return $this->moneyrand($startnum,$endnum); } } 这是我重新修改以后的,您给看下,返回的还是null,哪个地方不正确啊
xuzuning 2014-03-31
  • 打赏
  • 举报
回复
返回的和如果在 传递的金额范围内,就调用这三个随机数,进行数据插入,如果不在金额范围内容,重新再调用 重新调用是从头来过吗?原来符合的也从新算? 在不在范围里 的判断要在 moneyadd 中进行,使得 moneyadd 总是返回合适的数据
jz15136122392 2014-03-31
  • 打赏
  • 举报
回复
在这个段程序最上面是 function rechangeadd(){ 这个没粘贴上去
jz15136122392 2014-03-31
  • 打赏
  • 举报
回复
引用 20 楼 xuzuning 的回复:
你不是调用用 call_user_func_array 调用 rechangeadd 的吗? call_user_func_array 将返回 rechangeadd 的返回值 而你的 rechangeadd 并没有返回值,很自然 $total[$h] 就是 null 了 让你描述一下整体思路,你又不愿意
我详细给你说一遍 $starttime=strtotime($_POST['starttime']); $endtime =strtotime($_POST['endtime']); $user=D('user'); if(!empty($_POST['startnum']) && !empty($_POST['endnum'])){ $user->query("SET NAMES utf8"); $data=$user->query("SELECT * FROM `m_user` WHERE id >= (SELECT floor(RAND() * (SELECT MAX(id) FROM `m_user`))) ORDER BY id LIMIT ".$_POST['peoplenum']."; ",'select');//随机抽取 for($h=0;$h<=$_POST['peoplenum'];$h++){ $total[$h]=$this->moneyrand($_POST['endnum']); if($total[$h]['total']>$_POST['startnum'] && $total[$h]['total']<$_POST['endnum']){ $total[$h]['total']=$total[$h]['total']; }else{ //$total[$h]=call_user_func_array(array('Index','rechangeadd'),array($_POST['startnum'],$_POST['endnum'])); $total[$h]=$this->rechangeadd($_POST['startnum'],$_POST['endnum']); } } $rech=D('rechange'); for($i=0;$i<=$_POST['peoplenum']-1;$i++){ // $rechange[$i]['ip']=$ip; 可用记录 //插入充值10元的记录 for($j=0;$j<$total[$i]['rand_10'];$j++){ $ip_rand=mt_rand(0,2);//ip随机数 $ip_arr=explode(',',$data[$i]['ip']); $rechange[$i]['ip']=$ip_arr[$ip_rand]; $rechange[$i]['username']=$data[$i]['username']; $rechange[$i]['paystyle']='1'; $rechange[$i]['paytime']=rand($starttime,$endtime);; $rechange[$i]['paynum']='10'; $chars = 'abcdefghijklmnopqrstuvwxyz0123456789'; $rand_order = ""; for ( $m = 0; $m < 5; $m++ ) { // 这里提供两种字符获取方式 // 第一种是使用 substr 截取$chars中的任意一位字符; // 第二种是取字符数组 $chars 的任意元素 // $password .= substr($chars, mt_rand(0, strlen($chars) – 1), 1); $rand_order .= $chars[ mt_rand(0, strlen($chars) - 1) ]; } $rechange[$i]['ordernum']='xnc'.date("YmdHms",$rechange[$i]['paytime']).$rand_order; $result=$rech->insert($rechange[$i],1,1); } //插入充值50元记录 for($k=0;$k<$total[$k]['rand_50'];$k++){ $ip_rand=mt_rand(0,2);//ip随机数 $ip_arr=explode(',',$data[$i]['ip']); $rechange[$i]['ip']=$ip_arr[$ip_rand]; $rechange[$i]['username']=$data[$i]['username']; $rechange[$i]['paystyle']='1'; $rechange[$i]['paytime']=rand($starttime,$endtime);; $rechange[$i]['paynum']='50'; $chars = 'abcdefghijklmnopqrstuvwxyz0123456789'; $rand_order =""; for ( $n = 0; $n < 5; $n++ ) { // 这里提供两种字符获取方式 // 第一种是使用 substr 截取$chars中的任意一位字符; // 第二种是取字符数组 $chars 的任意元素 // $password .= substr($chars, mt_rand(0, strlen($chars) – 1), 1); $rand_order .= $chars[ mt_rand(0, strlen($chars) - 1) ]; } $rechange[$i]['ordernum']='xnc'.date("YmdHms",$rechange[$i]['paytime']).$rand_order; $result=$rech->insert($rechange[$i],1,1); } //插入充值100元记录 for($x=0;$x<$total[$x]['rand_100'];$x++){ $ip_rand=mt_rand(0,2);//ip随机数 $ip_arr=explode(',',$data[$i]['ip']); $rechange[$i]['ip']=$ip_arr[$ip_rand]; $rechange[$i]['username']=$data[$i]['username']; $rechange[$i]['paystyle']='1'; $rechange[$i]['paytime']=rand($starttime,$endtime);; $rechange[$i]['paynum']='100'; $chars = 'abcdefghijklmnopqrstuvwxyz0123456789'; $rand_order = ""; for ( $q = 0; $q < 5; $q++ ) { // 这里提供两种字符获取方式 // 第一种是使用 substr 截取$chars中的任意一位字符; // 第二种是取字符数组 $chars 的任意元素 // $password .= substr($chars, mt_rand(0, strlen($chars) – 1), 1); $rand_order .= $chars[ mt_rand(0, strlen($chars) - 1) ]; } $rechange[$i]['ordernum']='xnc'.date("YmdHms",$rechange[$i]['paytime']).$rand_order; $result=$rech->insert($rechange[$i],1,1); } } } echo "<center><h1 style='color:green;'>ok</h1></center>"; } function moneyrand($endnum){ $money=array('10','50','100'); $money_rand=mt_rand(0,2); $total['max_10']=$max_10=$endnum/10; $total['max_10']=$max_10=$endnum/10; $total['max_50']=$max_50=$endnum/50; $total['max_100']=$max_100=$endnum/100; $rand_10=mt_rand(0,50); $rand_50=mt_rand(0,$max_50); $rand_100=mt_rand(0,$max_100); //随机10元充值 $total['rand_10']=$rand_10; $total['rand_50']=$rand_50; $total['rand_100']=$rand_100; $total['total']=$money[0]*$rand_10+$money[1]*$rand_50+$money[2]*$rand_100; return $total; } 这个是功能的全部 我想要的是: 1)form会传递3个值:开始金额,结束金额,生成数量,也就是moneyadd()方法 这三个随机的数据的范围(0.结束金额/10),(0.结束金额/50),(0.结束金额/100) 2)随机三个数,分别与10,50,100相乘后,得到一个和 ,返回总和 跟 随机出来的三个随机数 3)返回的和如果在 传递的金额范围内,就调用这三个随机数,进行数据插入,如果不在金额范围内容,重新再调用(也就是递归)rechangeadd()这个方法 4) 因为call_user_func_array()方法,我没有用过,具体怎么弄,不知道,所以现在屏蔽掉了 这个流程,您能看明白么?
xuzuning 2014-03-31
  • 打赏
  • 举报
回复
你不是调用用 call_user_func_array 调用 rechangeadd 的吗? call_user_func_array 将返回 rechangeadd 的返回值 而你的 rechangeadd 并没有返回值,很自然 $total[$h] 就是 null 了 让你描述一下整体思路,你又不愿意
jz15136122392 2014-03-31
  • 打赏
  • 举报
回复
引用 18 楼 xuzuning 的回复:
你的方法没有返回值,自然是 null
引用 18 楼 xuzuning 的回复:
你的方法没有返回值,自然是 null
如果我用call_user_func_array(),需要再重新写一个方法?来return 值么? 或者,我给闭掉,直接调用自己?
xuzuning 2014-03-31
  • 打赏
  • 举报
回复
你的方法没有返回值,自然是 null
jz15136122392 2014-03-31
  • 打赏
  • 举报
回复
引用 16 楼 xuzuning 的回复:
function rechangeadd(){
    for($h=0;$h<=$_POST['peoplenum'];$h++){
      $total[$h]=$this->moneyrand($_POST['endnum']);
      ......             
      if($total[$h]['total']>$_POST['startnum'] && $total[$h]['total']<$_POST['endnum']){
        ......
      }else{
         //这里不加判断的重入,目的何在?
         $total[$h]=call_user_func_array(array('Index','rechangeadd'),array($_POST['startnum'],$_POST['endnum']));
         ......                     
}
这个地方一直给我返回null,我没闭掉
xuzuning 2014-03-31
  • 打赏
  • 举报
回复
function rechangeadd(){
    for($h=0;$h<=$_POST['peoplenum'];$h++){
      $total[$h]=$this->moneyrand($_POST['endnum']);
      ......             
      if($total[$h]['total']>$_POST['startnum'] && $total[$h]['total']<$_POST['endnum']){
        ......
      }else{
         //这里不加判断的重入,目的何在?
         $total[$h]=call_user_func_array(array('Index','rechangeadd'),array($_POST['startnum'],$_POST['endnum']));
         ......                     
}
加载更多回复(15)

21,882

社区成员

发帖
与我相关
我的任务
社区描述
从PHP安装配置,PHP入门,PHP基础到PHP应用
社区管理员
  • 基础编程社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧