Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/243.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 标准化返回值-这是个好主意还是个坏主意_Php - Fatal编程技术网

Php 标准化返回值-这是个好主意还是个坏主意

Php 标准化返回值-这是个好主意还是个坏主意,php,Php,我使用PHP(但在本例中,我认为编程语言并不重要),在我的类方法中,我通常会遇到以下情况: 方法必须返回true或false 方法必须返回true或错误消息 方法必须返回true+成功消息或false+错误消息 方法必须返回true+成功结果(对象、数组等)或false 方法必须返回true+成功结果(对象、数组等)或false+错误消息 等等 我的问题是,当我在代码中的某个地方使用这个类方法时,我总是要回到这个类,检查这个方法实际返回的是什么:简单地说是真还是假,是真还是错误消息,等等 将返回

我使用PHP(但在本例中,我认为编程语言并不重要),在我的类方法中,我通常会遇到以下情况:

  • 方法必须返回true或false
  • 方法必须返回true或错误消息
  • 方法必须返回true+成功消息或false+错误消息
  • 方法必须返回true+成功结果(对象、数组等)或false
  • 方法必须返回true+成功结果(对象、数组等)或false+错误消息
  • 等等
  • 我的问题是,当我在代码中的某个地方使用这个类方法时,我总是要回到这个类,检查这个方法实际返回的是什么:简单地说是真还是假,是真还是错误消息,等等

    将返回值标准化是一个好主意吗?如果是,如何进行

    我的想法是:

  • 若函数必须返回true或false,那个么只需返回true或false即可
  • 如果函数必须返回true或error消息,则:

  • 如果函数必须返回true+成功消息或错误消息,则:

  • 等等

  • 我希望你们能理解我的问题,即使我的解释不是很好:) 您的建议或最佳实践是什么?我该怎么处理

    更新: 让我们举一个简单的例子:

    function login($username, $password) 
    {
        // Login logic here ..
        if ($logged_in) 
        {
            return TRUE;
        }
        {
            return $error_message;
        }
    }
    

    所以正确的方法是:返回true,或者抛出异常,当调用login方法时,使用try-catch执行。因此,当某些方法出错(验证失败等)时,我应该使用异常。

    在特定情况下,返回包含多个元素的数组(这些元素不是同类实体的集合)的解决方案可能是可接受的解决方案。但总的来说,这是一种代码气味

    这种设计可能会暗示一些问题:

    • 您没有正确使用异常处理
    • 你的设计违背了单一责任原则
    • 您总是等待返回,直到方法结束
    如果一个方法真的不能完成它应该做的事情,它不应该返回任何东西,它应该抛出一个异常

    如果您的方法执行的任务不止一项,那么您必须重构

    尽早返回。编写更像这样的方法:

    if (!$something)
    {
        return FALSE;
    }
    
    //do some other stuff
    return 'great, it worked';
    
    您的特定登录功能不应返回消息。此类特定于操作的用户消息应该被解耦,并由消息队列处理

    因此,您可以将Messenger类注入到控制器中,以便您可以在任何地方使用它并将消息添加到队列中

    function login($username, $password) 
    {
        // Login logic here ..
        if ($logged_in) 
        {
            $this->messenger->addMessage('success', 'You are loggend in.');
            return TRUE;
        }
        {
            $this->messenger->addMessage('error', $message);
            return FALSE;
        }
    }
    

    我认为返回布尔值和其他东西的前提是错误的

    函数应具有明确的目的和明确的结果。如果可以实现此结果,则返回结果。如果无法获得结果,则函数要么返回
    false
    ,要么抛出异常。哪一个更好取决于情况和您的一般错误处理理念。无论哪种方式,让函数返回错误消息通常都没有用处。该消息对调用函数的代码没有用处

    除了返回
    false
    结果:
    trigger\u error
    之外,PHP还有自己的机制来输出错误消息。不过,它纯粹是一个帮助调试的工具,它不会取代标准返回值。不过,它非常适合于只为了帮助开发人员而显示错误消息的情况

    如果一个函数足够复杂,可能会导致需要以不同方式处理的几种不同类型的错误,那么应该使用异常来执行此操作

    例如,一个用途明确的非常简单的函数,只需要返回
    true
    false

    function isUserLoggedIn() {
        return $this->user == 'logged in';
    }
    
    具有可能无法实现该目的的功能:

    function convertToFoo($bar) {
        if (!is_int($bar)) {
            return false;
        }
        // here be dragons
        return $foo;
    }
    
    该函数还触发消息,对调试非常有用:

    function convertToFoo($bar) {
        if (!is_int($bar)) {
            trigger_error('$bar must be an int', E_USER_WARNING);
            return false;
        }
        // here be dragons
        return $foo;
    }
    
    一个函数可能会合法地遇到调用代码需要知道的几种不同类型的错误:

    function httpRequest($url) {
        ...
    
        if (/* could not connect */) {
            throw new CouldNotConnectException('Response code: ' . $code);
        }
    
        ...
    
        if (/* 404 */) {
            throw new PageNotFoundException('Page not found for ' . $url);
        }
    
        return true;
    }
    

    我也会将此评论粘贴到这里:

    不应由职能部门负责准备、返回 或显示最终用户错误消息。如果函数的目的是 就是说,从数据库中获取一些东西,然后显示错误 信息与它无关。调用 从数据库获取函数只需要通知 结果;从这里开始,需要一个代码,它的唯一任务是 如果数据库函数无法获取 所需信息。不要把这两种责任混为一谈


    错误消息与返回值无关可能有助于避免已知的编码错误。函数应返回与其目的一致的值,即:

    canWriteFile() { return true or false }
    writeFile() { should return void }
    
    writeFile()
    根据名字,程序员不期望任何价值,他必须学习文档,这需要时间,不直观,可能会导致错误。发明这样的名称,不需要任何文档

    您绝对不应该将数组与第一项bool、第二项错误消息一起使用-这将返回复杂的数据类型,而不是简单的直观值,最终将编写通用函数的适配器,并且代码很快就会出错

    如何处理错误有3种可能:

    1)错误标志/状态对通知有用

    $error = "";
    function foo() {
      if($somethingBad) $error = "error occured";
      return !$somethingBad;
    }
    
    2)错误处理程序适用于大多数错误

    function handleError($message) {
      ...
    }
    
    function foo() {
      if($somethingBad) handleError("error occured");
      return !$somethingBad;
    }
    
    3)错误捕获对于无法处理的错误非常有用(即服务器在请求期间脱机)


    尝试例外情况

    我建议稍微研究一下例外情况,因为它们会派上用场。首先,消除返回的错误消息:改为抛出异常

    第二,您不再需要任何正确或错误的返回代码:如果所有事情都按预期工作,那么您知道这一点,因为不会引发异常

    如果你
    $error = "";
    function foo() {
      if($somethingBad) $error = "error occured";
      return !$somethingBad;
    }
    
    function handleError($message) {
      ...
    }
    
    function foo() {
      if($somethingBad) handleError("error occured");
      return !$somethingBad;
    }
    
    function foo() {
      try {
        // dangerous code here
      }
      catch($e) {
        // handle error here
      }
      return !$somethingBad
    }
    
    class Error {
    
        const OK = 1;
        //general error
        const FAIL = 0;
        //invalid url
        const RequestParseError = -1;
        //resource not found
        const ResourceNotFound = -2;
    
        ....
    
        static public function _($errCode) {
    
            switch ($errCode) {
    
                case Error::OK:
                    return "OK";
    
                case Error::FAIL:
                    return "General Failure";
    
                case Error::RequestParseError:
                    return "Request Parse Error";
    
            .....
        }
    
    }
    
    /**
     * @param  MyInput $input
     * @return MyOutput
     * @throws MyException
     */
    function myOperation(MyInput $input) 
    {
    
    }
    
    /**
     * @param  MyInput  $input
     * @param  MyOutput $output
     * @return bool
     */
    function tryMyOperation(MyInput $input, &$output = null) 
    {
    
    }
    
    /**
     * @param  string $input
     * @return string
     * @throws TypeException
     */
    function stringToUpper($input) 
    {
        if (!is_string($input)) 
        {
            throw new TypeException('String expected');
        }
        return strtoupper($input);
    }
    
    /**
     * @param  string $input
     * @param  string $output
     * @return boolean
     */
    function tryStringToUpper($input, &$output) 
    {
        try 
        {
            $output = stringToUpper($input);
            return true;
        } 
        catch (TypeException $exception) 
        {
            $output = null;
            return false;
        }
    }
    
    try 
    {
        $output = stringToUpper($input);
        // use $output
    } 
    catch (TypeException $exception) 
    {
        // recover
    }
    
    if (tryStringToUpper($input, &$output)) 
    {
        // use $output
    } 
    else 
    {
        // recover
    }