【问题标题】:How to stop execution of code after return the value in a recursive function?在递归函数中返回值后如何停止执行代码?
【发布时间】:2015-06-23 12:11:36
【问题描述】:

我在 yii 中有如下代码。

<?php
class MediaController extends Controller {
     public $mail_try = 1;

    public function actionUpdate() 
    {
        // ........... Other Code
        $return_err = array();
        /* Now Send Email */
        if(sizeof($mail_queue)>0)
        {
            foreach($mail_queue as $resmail)
            {
                $this->mail_try = 1;
                $to_arr = $resmail['to_arr'];
                $cc_arr = $resmail['cc_arr'];
                $from = $resmail['from'];
                $subject = $resmail['subject'];
                $message = $resmail['message'];
                $log_msg = $resmail['log_msg'];
                $attachment = $resmail['attachment'];
                $log =  $resmail['log'];
                $output = $this->mailsend($to_arr, $cc_arr, $from, $subject, $message, 'Image/Media update (action : insert) ', $attachment,$log);
                if($output==0)
                {
                    $return_err[] = $resmail['vendor_name'];
                }
            }
        }
    }


    public function mailsend($to, $cc, $from, $subject, $message, $crontask, $attachment = array(),$log='') {
        //.......  Other Code
        //.......  Other Code
        try{
             if (!$mail->Send()) {
                if($this->mail_try < 3)
                {
                    $this->mail_try++;
                    $this->mailsend($to, $cc, $from, $subject, $message, $crontask,$attachment,$log);
                    return 0;
                }
            } else {
                return 1;
            }
        } catch (Exception $ex) {
            return 0;
        }
    }   
}
?>

我想要做的是如果邮件发送失败,然后调用相同的函数来重试发送电子邮件。如果电子邮件发送仍然失败,则返回 0,否则返回 1。然后使用此返回值,我试图通知用户有关邮件发送错误的信息。

之前,我认为低于返回值的代码不会执行。但我错了。在上述情况下,它在返回值之后执行,因为它在递归函数中。

那么,如何解决这个问题?

【问题讨论】:

  • 说实话,我无法弄清楚你在说什么是你的问题。快速查看代码虽然让我觉得$this-&gt;mailsend(...) 行应该是return $this-&gt;mailsend(...),删除以下return 0;。最后,从外观上看,有一个路径,当邮件失败两次时将返回 null。
  • 这里的问题是,代码在返回值之后还在执行,所以我无法得到预期的返回值。我正在尝试做的是在几次尝试发送电子邮件后返回 1 或 0 值。
  • 所以如果我按照你的建议编辑我的代码,它仍然会在返回值之后执行代码。
  • 返回后不再继续运行。 return 完成当前块的过程,在您的情况下,返回的调用块恰好是将完成运行的相同方法,这就是递归所做的。但是,如果该行在递归调用 mailsend 时简单地返回,那么它应该级联返回到原始调用,并返回到您的 actionUpdate 方法,并返回 1 或 0(如果您修复了返回 null 的路径)。跨度>
  • 您能否用示例代码将其写为答案,对不起,但我无法理解您的意思,“(如果您修复返回 null 的路径)”是什么意思?

标签: php recursion yii


【解决方案1】:

所以我看到提供的代码存在 2 个问题。

1)无论重发通过还是失败,方法都返回0

2) 如果函数失败两次,则该方法将返回 null 而不是 0 或 1,因为没有后备可以拾取它(即当 $this-&gt;mail_try 为 3 时)。

以下更新的代码被修改,无论递归调用的返回值是什么,都直接返回而不是只返回0。另一个变化是如果两次都失败,它将返回0为空

public function mailsend($to, $cc, $from, $subject, $message, $crontask, $attachment = array(),$log='') {
    //.......  Other Code
    //.......  Other Code
    try{
         if (!$mail->Send()) {
            if($this->mail_try < 3)
            {
                $this->mail_try++;
                return $this->mailsend($to, $cc, $from, $subject, $message, $crontask,$attachment,$log);
            }
            return 0;
        } else {
            return 1;
        }
    } catch (Exception $ex) {
        return 0;
    }
} 

【讨论】:

  • 如果mailsend一开始失败,然后第二次通过,那么输出是什么,那么返回值是多少?而返回值之后的代码是执行还是停止?
  • 当前方法在遇到return 语句时立即结束并返回到原始调用者(可能是之前运行的mailsend)。如果第一个mailsend() 失败,第二个成功,它应该返回1
  • 另外需要注意的是,如果发生异常,它不会在已经发生的事情之外再试一次,所以如果在mailsend的原始调用中抛出异常,它就不会尝试再次。不确定这是不是故意的,这是你自己的决定。
  • 好的.. 感谢您的详细解释。但是在这个例子中“如果第一个 mailsend() 失败,第二个成功”,第二个的原始调用者是第一个 mailsend()。那么第一个 mailsend() 的执行停止了吗?很抱歉让我感到痛苦,但我正在努力理清思路。
  • 是的,没错。 actionUpdate 有第一个电话。如果失败,mailsend 方法会增加计数器并再次运行。没有第三次因为你的mail_try默认和条件。
【解决方案2】:

mail-&gt;Send() 方法是什么? 如果它用于发送电子邮件,这可能是一个答案。

public function mailsend($to, $cc, $from, $subject, $message, $crontask, $attachment = array(),$log='') {
//.......  Other Code
//.......  Other Code
try{
     $this->mail_try = 1;
     while(!mail->Send() && $this->mail_try<=3){
        $this->mail_try++;
     }
     if($this->mail_try == 4){return 0;}//failed
     else {return 1;} //it means mail has been send before $this->mail_try = 3
} catch (Exception $ex) {
    return 0;
}
}

尚未测试,请尝试

【讨论】:

    猜你喜欢
    • 2012-03-31
    • 2022-06-15
    • 1970-01-01
    • 2015-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-16
    • 2018-11-30
    相关资源
    最近更新 更多