Does PHP support the RAII pattern? How?

PHP uses reference counting, so when you're done with a variable it gets cleaned up immediately. (Unless you create cycles.) That frees up resources promptly so you generally don't need to worry about explicit resource management beyond being careful to not create memory cycles.

If you did want to implement any particular strategy, you can do it by making sure that the resource is only used by one variable. Whenever that variable is pointed away from the resource, the resource should be immediately freed up.


This is nearly the same question as Is destructor in PHP predictable? and the answer is the same. PHP uses refcounting, and it promises that the destructor will be called immediately as soon as the refcount goes to zero (generally when the object goes out of scope). So if you create an object and take care not to leak it out of scope, RAII is viable.


The following class ReturnHandler provides automatic invocation of a handler when ReturnHandler's instance goes out of scope. You can have several returns in your function (myfunc) without the need to think of releasing the resource before each of them.

/**
 * 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();
  }
}

Here's a test for it:

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);
  }
}

Tags:

Php

Raii