keywod'finally'如何在PHP中使用

所以,我一直在阅读关于PHP在线手册中的例外情况,并意识到我还没有理解finally关键字的目的或真正的必要性。 我在这里看过一些帖子,所以我的问题稍有不同。

我明白我们可以最终以这种方式使用:

function hi(){
    return 'Hi';
}


try {
    throw new LogicException("Throw logic n");
} catch (InvalidArgumentException $e) {
    echo $e->getMessage(); 
}

echo hi();

输出:

Fatal error:  Uncaught LogicException: Throw Logic in C:Users...a.php:167
Stack trace:
#0 {main}
  thrown in C:Users...a.php on line 167

所以,在这种情况下,函数hi(); 没有被执行,并有很好的理由。 我明白,如果异常未处理PHP解释器停止脚本。 好。 到目前为止,我读到的,最终使我们能够执行函数hi(); 即使不处理异常(尽管我不知道为什么)

所以,我明白这一点。

try {
    throw new LogicException("Throw logic n");
} catch (InvalidArgumentException $e) {
    echo $e->getMessage(); 
}finally{
    echo hi();
}

输出:

Hi
Fatal error:  Uncaught LogicException: Throw Logic in C:Users...a.php:167
Stack trace:
#0 {main}
  thrown in C:Users...a.php on line 167

这应该是异常错误以及函数的'hi'消息,即使那些我不知道这个用法。 但我不undersand这一点,即使我们赶上LogicException与捕捉(LogicException $e)及无异常被抛出还是我们将看到的功能是执行,我们将看到“喜”的消息。 如在这个例子中

try {
    throw new LogicException("Throw logic n");
} catch (LogicException $e) {
    echo $e->getMessage(); 
}finally{
    echo hi();
}

输出

// Throw logic 
// Hi

所以,即使我们没有捕获异常,我们仍然可以看到函数hi()被执行。 为什么和这有什么用? 我认为finally块被用作万一未发现异常的最后手段,即使情况并非如此,那么为什么它可以用来运行它?


finally 每次都执行

无论是例外还是回报

例外

我看到的一个更常见的用途是关闭数据库连接 - 您希望每次都发生这种情况(有或没有例外),因此您最终不会遇到阻止数据库服务器接受新连接的悬挂连接。

考虑这个伪代码:

try {
   $database->execute($sql);
} catch (Exception $exception) {
   $logger->log($exception->getMessage());
   throw $exception;
} finally {
   $database->close();
}

所以在这里我们将总是关闭数据库连接。 如果这是一个正常的查询,我们会在成功后关闭连接。 如果这是一个错误的查询,那么在抛出异常之后我们仍然关闭。

请注意,这种行为在其他语言中是不同的。 例如,在.NET中,如果从catch块中抛出/重新抛出异常,那么finally块将不会执行。

返回

其中一个比较晦涩的行为是它在return语句后执行代码的能力。

这里你可以在函数返回后设置一个变量:

function foo(&$x)
{
    try {
        $x = 'trying';
        return $x;
    } finally {
        $x = 'finally';
    }
}

$bar = 'main';
echo foo($bar) . $bar;

tryingfinally

但是分配将是尝试返回的内容:

$bar = foo($bar);
echo $bar . $bar;

tryingtrying

并在终于返回覆盖尝试返回:

function baz()
{
    try {
        return 'trying';
    } finally {
        return 'finally';
    }
}

echo baz();

最后

注意这个行为在php 5中有所不同:

finallyfinally
finallyfinally
最后

https://3v4l.org/biO4e


try {
    throw new LogicException("Throw logic n"); -> LogicException thrown
} catch (InvalidArgumentException $e) { -> LogicException not catched
    echo $e->getMessage(); 
}finally{
    echo hi(); -> code executed. "Hi" printed out
}

LogicException is here -> Fatal error

所以在这种情况下:

try {
    throw new LogicException("Throw logic n"); -> LogicException thrown
} catch (InvalidArgumentException $e) { -> LogicException not catched
    echo $e->getMessage(); 
}finally{
    echo hi(); -> code executed
    die();
}

由于陈述和最后的变化,将不会引发致命错误:

try {
    throw new LogicException("Throw logic n"); -> LogicException thrown
} catch (InvalidArgumentException $e) { -> LogicException not catched
    echo $e->getMessage(); 
} catch (LogicException $e) { -> LogicException catched
    echo $e->getMessage(); 
}finally{
    echo hi(); -> code executed
}

最后应该包含任何需要执行的代码,而不管是否有例外。

没有最后:

try {
   $handle = fopen("file.txt");
   //Do stuff
   fclose($handle);
   return something;
} catch (Exception $e) {
   // Log
   if (isset($handle) && $handle !== false) {
      fclose($handle);
   }     
}

终于:

try {
   $handle = fopen("file.txt");
   return something;
} catch (Exception $e) {
   // Log
} finally {
   if (isset($handle) && $handle !== false) {
      fclose($handle);
   }     
}

在函数返回后需要释放资源的情况下,会出现一些问题。

这在以下情况下变得更有用:

 try {
     $handle = fopen("file.txt");
     if (case1) { return result1; }  
     if (case2) { return result2; }
     if (case3) { return result3; }
     if (case4) { return result4; }

 } finally {
     if (isset($handle) && $handle !== false) {
          fclose($handle);
       }    
 }

在这种情况下,可以减少所需的所有fclose每次回到单一之前调用fclose将在方法返回之前正确的,但之后的任何其他代码执行调用。

链接地址: http://www.djcxy.com/p/94767.html

上一篇: How keywod 'finally' is meant to be used in PHP

下一篇: Visual Studio 2015 (C++) : Stop compile on first build error (not first project)