21

这里的每个人都应该知道“或”语句,通常粘在 die() 命令上:

$foo = bar() or die('Error: bar function return false.');

大多数时候我们会看到类似的东西:

mysql_query('SELECT ...') or die('Error in during the query');

但是,我无法理解那个“或”语句的工作原理。

我想抛出一个新异常而不是 die(),但是:

try{
    $foo = bar() or throw new Exception('We have a problem here');

不起作用,也没有

$foo = bar() or function(){ throw new Exception('We have a problem here'); }

我发现这样做的唯一方法是这个可怕的想法:

function ThrowMe($mess, $code){
    throw new Exception($mess, $code);
}
try{
    $foo = bar() or ThrowMe('We have a problem in here', 666);
}catch(Exception $e){
    echo $e->getMessage();
}

但是有一种方法可以在 'or' 语句之后直接抛出一个新异常?

或者这种结构是强制性的(我根本不喜欢 ThrowMe 函数):

try{
    $foo = bar();
    if(!$foo){
        throw new Exception('We have a problem in here');
    }
}catch(Exception $e){
    echo $e->getMessage();
}

编辑:我真正想要的是避免使用 if() 检查我所做的每一个潜在的危险操作,例如:

#The echo $e->getMessage(); is just an example, in real life this have no sense!
try{
    $foo = bar();
    if(!$foo){
        throw new Exception('Problems with bar()');
    }
    $aa = bb($foo);
    if(!$aa){
        throw new Exception('Problems with bb()');
    }
    //...and so on!
}catch(Exception $e){
    echo $e->getMessage();
}

#But i relly prefer to use something like:

try{
    $foo = bar() or throw new Exception('Problems with bar()');
    $aa = bb($foo) or throw new Exception('Problems with bb()');
    //...and so on!
}catch(Exception $e){
    echo $e->getMessage();
}

#Actually, the only way i figured out is:

try{
    $foo = bar() or throw new ThrowMe('Problems with bar()', 1);
    $aa = bb($foo) or throw new ThrowMe('Problems with bb()', 2);
    //...and so on!
}catch(Exception $e){
    echo $e->getMessage();
}

#But i'll love to thro the exception directly instead of trick it with ThrowMe function.
4

7 回答 7

35

or只是一个逻辑运算符,它类似于||.

的常见技巧

mysql_query() or die();

也可以写成

mysql_query() || die();

这里发生的是“逻辑或”运算符(无论您选择哪个)试图确定任一操作数的计算结果是否为 TRUE。这意味着操作数必须是可以转换为布尔值的表达式。

那么,原因

bar() or throw new Exception();

是非法的,是因为

(boolean)throw new Exception();

也是非法的。本质上,抛出异常的过程不会生成返回值供操作员检查。

但是调用函数确实会生成一个返回值供操作员检查(没有显式的返回值会导致函数返回NULL转换为的函数FALSE),这就是为什么当您将异常抛出到函数中时它对您有用。

于 2009-07-31T09:16:20.970 回答
3

我只是toss为此定义了函数。

function toss(Exception $exception): void
{
    throw $exception;
}

因为在构造异常时会捕获文件/行/堆栈信息(new)而不是抛出(throw),这不会干扰调用堆栈。

所以你可以这样做。

something() or toss(new Exception('something failed'));
于 2018-07-27T18:56:54.467 回答
2

为什么不抛出异常bar()bb()在 PHP Exceptions 中冒泡,因此无需在调用bar()/的函数/方法中抛出异常bb()。这些异常可能由bar()/抛出bb()。如果您想抛出另一个异常,您可以简单地执行以下操作:

function foo() {
    try {
        $bar = bar();
    } catch (BarException) {
        throw new FooException;
    }
}
于 2009-07-31T08:22:43.650 回答
2

我发现可以在任何地方替换“or die()”的解决方案是用一个匿名函数包装 throw,该函数会立即由 call_user_func 调用:

call_user_func(function(){
    throw new Exception("ERROR");
});

您可以通过在虚拟脚本上执行它来查看它的工作原理:

false or call_user_func(function(){throw new Exception("ERROR");});
于 2018-03-09T13:04:02.727 回答
1

我认为您想使用类似最后一个结构的东西,尽管为此使用异常确实没有意义:

$foo = bar();
if(!$foo){
    echo 'We have a problem in here';
}

每条评论 - 我认为你不能在一行中做到这一点(即没有if(!$foo)检查),我同意异常抛出方法非常可怕。就个人而言,我更喜欢以下内容的明确性:

$foo = bar();
if(!$foo){
    throw new Exception('We have a problem in here');
}

但这是个人喜好。如果你想要单行的东西,我认为你必须使用你的异常抛出功能选项。

我猜这个限制可能归结于 PHP 的动态类型,它可以将函数调用的结果转换为条件,但不能将throw.

于 2009-07-31T08:07:57.987 回答
1

这是一个没有额外功能的单行解决方案:

if (!($foo = bar())) throw new Exception('We have a problem here');
于 2015-11-27T13:15:35.577 回答
1

您还可以创建自定义异常类并使用它的静态构造方法而不是构造方法throw new Exception()

异常类:

class CustomException extends Exception {
  static public function doThrow($message = "", $code = 0, Exception $previous = null) {
    throw new Exception($message, $code, $previous);
  }
}

用法:

try {

  $foo = bar() or CustomException::doThrow('Problems with bar()');
  $aa = bb($foo) or CustomException::doThrow('Problems with bb()');

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

笔记

如果您使用的是 PHP 7 及更高版本 - 您可以将静态方法重命名doThrow()为 simple throw(),因为在 PHP 7 及更高版本中允许使用保留关键字作为方法名称。

于 2017-04-12T08:33:22.997 回答