14

PHP 上的大多数资源从不涉及内存管理,因为语言本身非常擅长为您做这件事。然而,在 PHP 中,您经常会处理非内存的外部资源——数据库句柄、会话、数据库事务等。这些外部资源可以使用某种形式的 RAII 对象进行最干净的管理。

我最初认为 PHP 使用了类似于 JVM 或 CLR 的垃圾收集方案,其中不存在析构函数的概念。(记住:每个人都以错误的方式看待垃圾收集——终结器不是析构函数!)有一种特殊的__destruct方法,但我认为这是一个类似于 Java 或 C# 终结器的“终结器”。出于这个原因,您不能在 JVM 或 CLR 上使用 RAII(C# 的using块可以让您完成大约 95% 的工作,但这有点不同......)。

然而,谷歌似乎表明 PHP 支持 RAII 模式,尽管我在 PHP 文档中找不到对此的验证。语言是否支持这一点并且是否将清理逻辑__destruct用于完成 RAII 任务?

4

4 回答 4

14

这几乎与PHP 中的析构函数可预测吗?答案是一样的。PHP 使用引用计数,它承诺一旦引用计数变为零(通常是当对象超出范围时),就会立即调用析构函数。因此,如果您创建一个对象并注意不要将其泄漏到范围之外,那么 RAII 是可行的。

于 2011-02-08T21:37:51.890 回答
5

PHP 使用引用计数,因此当您使用完一个变量后,它会立即被清除。(除非您创建循环。)这会迅速释放资源,因此您通常无需担心显式资源管理,只需小心不要创建内存循环。

如果您确实想要实施任何特定策略,您可以通过确保资源仅由一个变量使用来实现。每当该变量指向远离资源时,应立即释放该资源。

于 2011-02-08T21:36:18.930 回答
4

当' 的实例超出范围时,以下类ReturnHandler提供处理程序的自动调用。您的函数 ( ) 中ReturnHandler可以有多个s,而无需考虑在每个函数之前释放资源。returnmyfunc

/**
 * Automatically calls a handler before returning from a function. Usage:
 *
 * function myfunc()
 * {
 *  $resource = new Resource();
 *  $rh = new ReturnHandler( function() use ($resource) { $resource->release(); } );
 *  // ...
 *  if(...) {
 *    return; // look, ma, automatic clean up!
 *  }
 * }
 */
class ReturnHandler
{
  private $return_handler;

  public function __construct( $return_handler )
  {
    $this->return_handler = $return_handler;
  }

  public function __destruct()
  {
    $handler = $this->return_handler;
    $handler();
  }
}

这是一个测试:

class ReturnHandlerTest extends PHPUnit_Framework_TestCase
{

  private static function trigger_return_handler(&$var)
  {
    $rh = new ReturnHandler(function() use (&$var) { $var++; } );
  }

  public function test()
  {
    $a = 0;
    $this->assertEquals(0, $a);
    self::trigger_return_handler($a);
    $this->assertEquals(1, $a);
  }
}
于 2013-03-13T13:55:08.443 回答
0

有点题外话:你可以using用 lambdas 做一个类似的模式。像这样:

function WithFile($Name, $Func)
{
    $File = fopen($Name, 'r');
    $r = $Func($File);
    fclose($File);
    return $r;
}

然后像这样使用它

$FileHeader = WithFile('myfile', function($File) {return fread($File, 16);});

完全确定性。也就是说,是否有更简洁的 lambda 语法...

于 2020-11-11T18:06:59.973 回答