Php 从尝试/捕获块中中断

Php 从尝试/捕获块中中断,php,exception,try-catch,Php,Exception,Try Catch,这在PHP中可能吗 try { $obj = new Clas(); if ($obj->foo) { // how to exit from this try block? } // do other stuff here } catch(Exception $e) { } 我知道我可以把其他东西放在{}之间,但这会增加更大代码块上的缩进,我不喜欢:p你就不能这样做吗 try{ $obj = new Clas(); if(!$obj->

这在PHP中可能吗

try {

  $obj = new Clas();

  if ($obj->foo) {
    // how to exit from this try block?
  }

  // do other stuff here

} catch(Exception $e) {

}

我知道我可以把其他东西放在
{}
之间,但这会增加更大代码块上的缩进,我不喜欢:p

你就不能这样做吗

try{

  $obj = new Clas();

  if(!$obj->foo){
  // do other stuff here
  }


}catch(Exception $e){

}

当然,这是没有原因的,但是您可以在
try
块中强制执行异常,停止函数的执行

try {
   if ($you_dont_like_something){
     throw new Exception();
     //No code will be executed after the exception has been thrown.
   }
} catch (Exception $e){
    echo "Something went wrong";
}
当然有一个好主意

try {

  $obj = new Clas();

  if ($obj->foo) {
    goto break_free_of_try;
  }

  // do other stuff here

} catch(Exception $e) {

}
break_free_of_try:

我也遇到了这种情况,和您一样,不希望出现无数的if/elseif/elseif/else语句,因为这会降低代码的可读性

我最终用自己的扩展了Exception类。下面的示例类用于验证问题,这些问题在触发时会产生不太严重的“日志通知”

class ValidationEx extends Exception
{
    public function __construct($message, $code = 0, Exception $previous = null)
    {
        parent::__construct($message, $code, $previous);
    }

    public function __toString()
    {
        return __CLASS__ . ": [{$this->code}]: {$this->message}\n";
    }
}
在我的主代码中,我称之为

throw new ValidationEx('You maniac!');
在Try语句的末尾,我有

        catch(ValidationEx $e) { echo $e->getMessage(); }
        catch(Exception $e){ echo $e->getMessage(); }

欢迎评论和批评,我们都在这里学习

在PHP5.3+中,将异常与try-catch块一起使用的好处是,您可以创建自己的异常,并在需要时以何种方式处理它们。见:

然后,您可以捕获特定异常,或者在
catch\Exception
块中使用
if($e instanceof AcceptedException)
,以确定如何处理异常

  • 示例:
  • 未处理的示例:

  • 与许多替代解决方案相比,这使您的代码更具可读性,更容易进行故障排除。

    我个人喜欢使用

    throw new MyException("optional message", MyException::ERROR_SUCCESS);
    
    很明显,我是通过使用:

    switch($e->getCode()) {
       /** other cases make sense here */
       case MyException::ERROR_SQL:
           logThis("A SQL error occurred. Details: " . $e->getMessage());
       break;
    
       case MyException::ERROR_SUCCESS:
           logThis("Completed with success. Details: " . $e->getMessage());
       break;
    
       case MyException::ERROR_UNDEFINED:
       default:
           logThis("Undefined error. Details: " . $e->getMessage());
       break;
    }
    

    throw('Get me out here!')
    将跳出。但这不太好。难道你不能在if之后使用其他选项吗?@MattyF-+1,听起来像是我的答案!我看不出这个有什么合理的用途?只有我吗?@bestprogrammerintheworld-这不是朝鲜,你想什么时候想什么就什么时候想吧!考虑抛出异常的特定子类,而不是顶级异常对象。然后,为各种可能性添加捕捉。与Dan的评论类似。如果你经常这样做,这会导致性能损失。这个答案让我感到恐惧和强大。它非常强大。“goto”没什么错——这是一个古老的神话。我们许多程序员都在等待业界认识到Dijkstra的争论已经结束,如果你知道自己在做什么,直接跳转没有什么错。汇编实现goto BTW,这意味着它是低级的、本地的,因此,如果你知道自己在做什么,就完全可以合法地使用。使用高级语言中的
    goto
    来控制流将导致意大利面代码和错误,并使将来试图维护代码的人(即使是编写
    goto
    的人)头疼不已,如果你在一个小函数中做一次,你会在大函数中重复多次。永远不要使用
    goto
    ,即使在
    C
    中,也没有必要使用
    goto
    。在汇编中没有
    goto
    ,主要是
    jmp
    指令,当然如果
    goto
    在引擎盖下做什么,这就是汇编和机器代码的工作方式,使用跳转和调用。克里斯托斯,你似乎是在错误的假设下操作的,我的代码还不是意大利面。
    try {
        $obj = (object) array('foo' => 'bar');
        if ($obj->foo) {
            throw new \AcceptedException;
        }
    } catch (\AcceptedException $e) {
        var_dump('I was accepted');
    } catch (\Exception $e) {
        if ($e instanceof \InvalidArgumentException) {
            throw $e; //don't handle the exception
        }
    }
    
    throw new MyException("optional message", MyException::ERROR_SUCCESS);
    
    switch($e->getCode()) {
       /** other cases make sense here */
       case MyException::ERROR_SQL:
           logThis("A SQL error occurred. Details: " . $e->getMessage());
       break;
    
       case MyException::ERROR_SUCCESS:
           logThis("Completed with success. Details: " . $e->getMessage());
       break;
    
       case MyException::ERROR_UNDEFINED:
       default:
           logThis("Undefined error. Details: " . $e->getMessage());
       break;
    }