PHP:检查函数是否应抛出异常

时间:2015-11-11 11:39:42

标签: php exception error-checking

这不一定只适用于PHP,但这是我关注的领域。

我最近一直在编写一些检查函数,得到一些参数,然后以各种方式检查它的有效性。比如,checkXmlString($ xml)将检查给定的字符串是否包含格式正确的xml文档等。

问题是,如果这些函数返回一个布尔值,或抛出异常而不返回任何成功的东西。

所以

function checkAbc($arg) { if ($arg is invalid) return false; else return true; }

或者更确切地说

function checkAbc($arg) { if ($arg is invalid) throw new Exception(...); }

6 个答案:

答案 0 :(得分:0)

我真的不太确定哪种形式更适合。

一方面,如果出现错误,您需要一条有用的消息,因此最终会出现混合返回(true / string),这很难看,或者返回一个数组(甚至更难)。一个例外可以免费提供。

另一方面,一个名为check ...()的函数不应该抛出异常,因为找出"这不是一个有效的东西"没什么特别的,也不是错误。

第三种方式是将它称为" throwIfFalse",但那也很难看......

...嗯

一种可能的解决方案:

interface Checker {
  public function check();
  public function getMessage();
}
class WhateverChecker implements Checker { ... }

class ClientOfChecker {
  public function doStuff() {
     $checker = new Checker();
     if (! $checker->check() )
        throw new Exception($checker->getMessage());
  }
}

然而,这似乎令人难以置信的冗长,而且,我可以说,Javaesque给我。

答案 1 :(得分:0)

根据几乎所有关于主题的书籍而言,根据逻辑,这个名称应该是该功能的最大暗示。在这种情况下,只适用第一个选项。正如Bet Lamed之前所说,一个名为“check”的函数不应该抛出异常,只是为了让你知道支票是否正常。

如果您想要例外,您可能希望将其重命名为DeserialisationToAbc()或TryParseAbc()或类似的东西。

答案 2 :(得分:0)

  

问题是,如果这些函数返回一个布尔值或抛出   例外而不是任何成功的回报。

首先确定如果这是一种例外情况而不是使用例外情况。你的情况似乎不是例外情况,这只是一个条件,所以把它当成一个条件。如果它是正确但在某些情况下失败,你可能认不出比你考虑使用例外更好。

访问这两个链接,了解有关例外的更多信息

Exception Best Practices in PHP 5.3

A primer on PHP exceptions

答案 3 :(得分:0)

这当然是基于意见,但问问自己,checkEmail()这样的函数有什么期望?该方法的目的是验证某些内容,因此您可以期望得到这个问题的答案。

$isValid = checkEmail($arg);

我认为大多数开发人员都希望bool作为返回值,它使代码可读。错误的值是预期的,因此如果传递了无效的参数,则不能说它是一个例外。要返回错误消息,我将使用out参数:

function checkAbc($arg, &$errorMessage)
{
  if ($arg is invalid)
  {
    $errorMessage = 'The argument is invalid because of...';
    return false;
  }
  else
  {
    $errorMessage = '';
    return true;
  }
}

答案 4 :(得分:0)

你可以抛出一个InvalidArgumentException来检查参数是否不正确,但我认为如果你正在编写" checkers"他们应该返回一个布尔值,以便你知道不要继续操作,例如,如果foobar.xml实际上是一个CSV文件你不想继续你的操作,但你不想要捕获一个例外

<?php 
class Checker {
    function validXml($string)
    {
        if(!(bool)$string) throw new \InvalidArgumentException("Cannot pass empty string as argument", 1);
        // Check
        // Is valid XML ? Return True : return false
    }
}
try {
    if(new Checker->validXml($xmlString))
    {
        // Continue Operation
        // return 
    }
    // Notify User of invalidity
    // return
} catch (\InvalidArgumentException $e) {
    // Log args 
    // 
}

答案 5 :(得分:0)

关于您的问题通常有两种类型的功能:

  • 测试条件是否成立的纯函数。

  • 确保条件成立的功能,如果没有,则改变控制流程。

不同的编程语言可能对两种类型的命名有不同的约定。以C++为例,类型2的常用命名为CHECK_XXX,类型1为IsXXX。 以下是从{-3}} google-log库中获取的示例:

CHECK(fp->Write(x) == 4) << "Write failed!";
CHECK_NE(1, 2) << ": The world must be ending!";

另一个示例是Vimscript的{​​{3}}实用程序库,其中maktaba#value#IsXXX()用于测试参数是否属于某种类型,而maktaba#ensure#IsXXX()用于确保 IsXXX成立,否则抛出异常。

function! TakeAString(name)
  " Ensure argument type is String.
  let name = maktaba#ensure#IsString(a:name)
endfunction

if maktaba#value#IsString(name)
  " Branch if name is a String.
  echo name
endif

所以重点是:选择最适合您需要的那个,并根据语言的惯例命名该功能。就两者的用例而言,粗略地,使用类型2来检查前置条件,如参数类型,并在条件语句中使用类型1。