Intercepting Execution of System Functions in PHP

Posted on

Intercepting an execution of methods is one of the most common tasks for AOP. In the Java world there are a lot of articles that has a detailed examples for transactional control, logging, authorization, etc. But all AOP stuff in Java is related only to the classes and objects, because functions are not first-class citizens in Java whereas PHP has a good support for functions. By using some tricks we can create a proxies for system functions and add our own interceptors with custom logic. This article will show you how to use AOP techniques with functions in PHP.

Ok, let’s have some experiments with PHP. Suppose, that we have a nice code that uses the file_get_contents() function to load the content of a file and then prints it to the screen:

1
2
3
4
5
6
7
8
9
namespace Test;

class FilePrinter
{
    public function show($filename)
    {
        echo '<pre>', htmlspecialchars(file_get_contents($filename)), '</pre>';
    }
}

Is it possible to test this class and method? Of course, yes! We can create a unit test that will generate a temporary file and then just check that content is correct:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
namespace Test;

use PHPUnit_Framework_TestCase as TestCase;

class FilePrinterTest extends TestCase
{
    protected $printer;

    public function setUp()
    {
        $this->printer = new FilePrinter();
    }

    public function testShow()
    {
        $file = tempnam("/tmp", "PHP");
        file_put_contents($file, 'test');
        ob_start();
        $this->printer->show($file);
        $content = ob_end_clean();
        $this->assertEqual('test', $content);
        unlink($file);
    }
}

Not so cool to use a real filesystem. Real programmers should use virtual file system! But is it possible to intercept system functions like file_get_contents() in PHP?

I can suppose that most of programmers will argue that it’s impossible to intercept system function without extensions such as runkit. Yes, it’s absolutely true that we can not change the function that already loaded into the memory of PHP. However there is a small loophole in the PHP that can be exploited for free.

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s