Skip to content

PDO Proxy usable for intercepting and altering PDO commands

License

Notifications You must be signed in to change notification settings

artur-graniszewski/pdo-proxy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Latest Stable Version Build Status Coverage Status Code Climate Percentage of issues still open

Introduction

PDO Proxy is a simple, event-driven PDO wrapper that allows to intercept and alter execution of all PDO methods.

Such feature can be used to:

  • selectively (or entirely) mock the PDO functionality for integration tests
  • intercept PDO method execution for logging or debugging purposes

The PDOProxy\PDO and PDOProxy\PDOStatement classes extend the native PDO and PDOStatement classes, therefore they are compatible with any method expecting regular PDO objects.

Usage

After installing this library, you must provide the Proxy configuration, like so:

<?php

use PDOProxy\EventManager;
use PDOProxy\ProxyConfiguration;
use PDOProxy\PDOCommand;

$ev = new EventManager();

// you can alter the output of any method, like "__construct", "query", "prepare"...
// in order to do so, you must pass method name as an event name
// please note: multiple event listeners may be attached to a single event type
$ev->addEventListener("query", function(PDOCommand $command, string $eventName) {
    // you can alter the result of any PDO method
    $event->setResult(new PDOMockStatement("query", "SELECT 1");
    $command->stopPropagation();
});

// you can intercept any method, like "__construct", "query", "prepare"...
// to do so, you must add "#pre" suffix to the event name
$ev->addEventListener("query#pre", function(PDOCommand $command, string $eventName) {
    // if you stop event propagation, the real PDO method won't be executed and the result will be taken from this callback
    if ($command->getArgs()[0] == "SELECT 1") {
        $command->stopPropagation();
    }
});

ProxyConfiguration::init($ev);

Now, you can initialize PDOProxy just like regular PDO object:

<?php

use PDOProxy\PDO;

$pdo = new PDO("dsn", "user", "password", ["option1" => 1, "option2" => 2]);
$result = $pdo->query("SELECT 2");

// [...]

Installation

Proxy can be installed in two different ways:

via Composer:

user@host:/directory$ composer require pdo-proxy/pdo-proxy

by downloading source code

Source codes can be found in ZIP file under the following URL: https://github.com/artur-graniszewski/pdo-proxy/archive/master.zip

Event types

As demonstrated in code above, each event handler gains access to two parameters, specific Event object and event name (as string).

Here is an overview of two event types raised by PDO Proxy:

PDO Command Event:

It is raised on every execution of PDOProxy\PDO class method

<?php

namespace PDOProxy;

interface PDOCommandInterface
{
    public function getArgs() : array;
    
    public function setArgs(array $args);
    
    public function getMethodName() : string;
    
    public function getResult();
    
    public function setResult($result);
}

The getArgs() and setArgs() methods allow to fetch and alter input parameters passed to PDOProxy\PDO method, while getMethodName() allows to check which PDO method was executed.

The getResult() and setResult() event methods allow to access and alter result that will be returned by specific PDO method.

PDO Statement Command Event

It is raised on every execution of PDOProxy\PDOStatement class method

<?php

namespace PDOProxy;

interface PDOStatementCommandInterface extends PDOCommandInterface
{   
    public function getParentArgs() : array;
    
    public function setParentArgs(array $args);
    
    public function getParentMethodName() : string;
}

The getParentArgs() and setParentArgs() methods allow to fetch and alter input parameters passed to PDOProxy\PDO method that created the given PDOProxy\PDOStatement object, while getParentMethodName() allows to check which PDO method was executed in the first place.

Generic Event interface

All PDO events extend the following, generic event interface:

<?php

namespace PDOProxy;

interface EventInterface
{
    public function stopPropagation();
    
    public function isPropagationStopped() : bool;
}

The stopPropagation() method stops further event propagation (resulting in other event listeners not being executed for a given event type). In case of event names suffixed with "#pre" sentence (like "query#pre"), the original PDO/PDOStatement method won't be executed on database, in such case result must be mocked by executing the setResult() method.

Proxy configuration

Proxy must be configured by providing an instance of PDOProxy\EventManager to static init() method of a PDOProxy\ProxyConfiguration class (see example above).

Please keep in mind that instantiating PDOProxy\PDO class prior to Proxy configuration results in LogicException