Skip to content

gonzalo123/using

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

implementation of C# "using" statement in PHP

Build Status Latest Stable Version

Usage

using(new File(__DIR__ . "/file.txt", 'w'), function (File $file) {
        $file->write("Hello\n");
        $file->write("Hello\n");
        $file->write("Hello\n");
    });

The problem

Imagine this class:

class File
{
    private $resource;

    public function __construct($filename, $mode)
    {
        $this->resource = fopen($filename, $mode);
    }

    public function write($string)
    {
        fwrite($this->resource, $string);
    }

    public function close()
    {
        fclose($this->resource);
    }
}

We can use this class:

$file = new File(__DIR__ . "/file.txt", 'w');
$file->write("Hello\n");
// ...
// some other things
// ...
$file->write("Hello\n");
$file->close();

What happens if there is an exceptions in "some other things"? Simple: close() function isn't called.

The solution

We can solve the problem with try - catch:

try {
    $file->write("Hello\n");
    // ...
    // some other things
    // ...
    $file->write("Hello\n");
    $file->close();
} catch (\Exception $e) {
    $file->close();
}

or using "finally" keyword is we use PHP5.5

try {
    $file->write("Hello\n");
    // ...
    // some other things
    // ...
    $file->write("Hello\n");
} catch (\Exception $e) {
} finally {
    $file->close();
}

Better solution

c# has "using" statement to solve this problem in a smart way.

http://msdn.microsoft.com/en-us//library/yh598w02(v=vs.90).aspx

We're going to implement something similar in PHP.

First we will add G\IDisposable interface to our File class

namespace G;

interface IDisposable
{
    public function dispose();
}

Now our File class looks like this:

class File implements IDisposable
{
    private $resource;

    public function __construct($filename, $mode)
    {
        $this->resource = fopen($filename, $mode);
    }

    public function write($string)
    {
        fwrite($this->resource, $string);
    }

    public function close()
    {
        fclose($this->resource);
    }

    public function dispose()
    {
        $this->close();
    }
}

And we can use our "using" funcion in PHP:

using(new File(__DIR__ . "/file.txt", 'w'), function (File $file) {
        $file->write("Hello\n");
        $file->write("Hello\n");
        $file->write("Hello\n");
    });

As we can see we can forget to close() our file instance. "using" will do it for us, even if one exception is triggered inside.

We also can use an array of instances (implementing the IDisposable interface of course)

using([new Bar, new Foo], function (Bar $bar, Foo $foo) {
        echo $bar->hello("Gonzalo");
        echo $foo->hello("Gonzalo");
    });

About

c# using statement implementation in PHP

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages