Skip to content

Repository files navigation

PDO Debugging & Benchmarking Tools

Packagist versionPHP from PackagistGitHub licenseGitHub issuesPackagist

Donation

Compatibility

PHP 8.0.* ‾‾ 3.0.0

PHP ^7.4 ‾‾ 2.3.0

PHP >=7.3 < 7.4 ‾‾ 2.2.0

PHP >=7.2.5 < 7.3 ‾‾ 2.1.0

PHP ^7.0 ‾‾ 2.0.0

PHP ^5.6 ‾‾ 1.2.0

PHP ^5.5 ‾‾ 1.1.0

PHP ^5.4 ‾‾ 1.0.0

Installation

Run composer require deepeloper/pdo-debugging.

Benchmarking

Allows to collect following benchmarks per PDO connection:

  • Global:
    • queries count/time;
    • preparation count/time;
    • fetching count/time;
    • commits count/time;
    • roll back count/time;
    • sum of time calling:
      • PDO::__construct();
      • PDO::beginTransaction();
      • PDO::commit();
      • PDO::exec();
      • PDO::prepare();
      • PDO::query();
      • PDO::rollBack();
      • PDOStatement::execute();
      • PDOStatement::fetch*();
  • Statement:
    • queries count/time;
    • fetching count/time;
    • sum of time calling:
      • PDOStatement::execute();
      • PDOStatement::fetch*().

Benchmarking usage

usedeepeloper\PDO\PDOExcavated;
$pdo = newPDOExcavated(
$dsn,
$username,
$password,
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDOExcavated::ATTR_DEBUG => [],
]
);
$pdo->beginTransaction();
$stmt = $pdo->query("SELECT 1");
$stmt->fetch();
$pdo->commit();
$pdo->beginTransaction();
$stmt = $pdo->prepare("SELECT ?");
$stmt->bindValue(1, 100500, PDO::PARAM_INT);
$stmt->execute();
$stmt->fetch();
$pdo->rollBack();
echo"Global benchmarks: ";
print_r($pdo->getBenchmarks());
echo"\nStatement benchmarks: ";print_r($stmt->getBenchmarks());
echosprintf("\nLast query: %s\n", $stmt->getLastExecutedQuery());

will output:

Global benchmarks: Array
(
[query] => Array
(
[count] => 2
[time] => ...
)
[prepare] => Array
(
[count] => 1
[time] => ...
)
[fetch] => Array
(
[count] => 2
[time] => ...
)
[commit] => Array
(
[count] => 1
[time] => ...
)
[rollBack] => Array
(
[count] => 1
[time] => ...
)
[total] => Array
(
[time] => ...
)
)
Statement benchmarks: Array
(
[query] => Array
(
[count] => 1
[time] => ...
)
[fetch] => Array
(
[count] => 1
[time] => ...
)
[total] => Array
(
[time] => ...
)
)
Last query: SELECT 100500

Debugging

Allows to process next methods calls:

  • PDO::__construct();
  • PDO::beginTransaction();
  • PDO::commit();
  • PDO::exec();
  • PDO::prepare();
  • PDO::query();
  • PDO::rollBack();
  • PDOStatement::execute().

Allows to log queries with replaced placeholders from next methods:

  • PDO::exec();
  • PDO::query();
  • PDOStatement::execute().

Debugging usage

usedeepeloper\PDO\LoggerInterface;
usedeepeloper\PDO\PDOExcavated;
class Logger implements LoggerInterface
{
/** * Logs message. * * @param string $message * @return void */publicfunctionlog($message, array$scope)
{
echo"$message\n";
}
}
$dsn = "...";
$username = "...";
$password = "...";
$logger = newLogger();
$pdo = newPDOExcavated(
$dsn,
$username,
$password,
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDOExcavated::ATTR_DEBUG => [
'logger' => $logger,
/** * Defaults. *  * @see deepeloper\PDO\ExcavatingTrait::$debuggingOptions */'format' => [
'timeStamp' => "Y-m-d H:i:s",
'count' => "%03d",
'precision' => "%.05f",
'call' => "[ %TIME_STAMP% ] [ %DSN%;user=%USER_NAME% ] [ %EXECUTION_TIME% ] [ CALL ] [ %SOURCE%(%ARGS%) ]",
'query' => "[ %TIME_STAMP% ] [ %DSN%;user=%USER_NAME% ] [ %EXECUTION_TIME% ] [ QUERY ] [ #%COUNT% ] [ %SOURCE% ] [ %QUERY% ]",
],
'sources' => [
],
],
]
);
$pdo->exec("UPDATE `test` SET `foo` = 0");
$stmt = $pdo->query("SELECT 1");
$stmt->fetch();
$stmt = $pdo->prepare("SELECT ?");
$stmt->bindValue(1, 100500, PDO::PARAM_INT);
$stmt->execute();

will output:

[ ****-**-** **:**:** ] [ $dsn;user=$username ] [ *.***** ] [ CALL ] [ PDOExcavated::__construct(["$dsn","$username"]) ]
[ ****-**-** **:**:** ] [ $dsn;user=$username ] [ *.***** ] [ QUERY ] [ #001 ] [ PDOExcavated::exec ] [ UPDATE `test` SET `foo` = 0 ]
[ ****-**-** **:**:** ] [ $dsn;user=$username ] [ *.***** ] [ QUERY ] [ #002 ] [ PDOExcavated::query ] [ SELECT 1 ]
[ ****-**-** **:**:** ] [ $dsn;user=$username ] [ *.***** ] [ CALL ] [ PDOExcavated::prepare(["SELECT ?"]) ]
[ ****-**-** **:**:** ] [ $dsn;user=$username ] [ *.***** ] [ QUERY ] [ #003 ] [ PDOStatementExcavated::execute ] [ SELECT 100500 ]

If you wish to log only queries, pass following 'sources' section:

'sources' => [
"/^PDOExcavated::(?:exec|query)/",
"/^PDOStatementExcavated::execute/",
],

If source started with "/" it will be processed like regular expression, otherwise will be compared like string.

Customizing debugging

You can customize log message scope and process result message before logging:

usedeepeloper\PDO\LoggerInterface;
usedeepeloper\PDO\PDOExcavated;
usedeepeloper\PDO\PDOStatementExcavated;
class class PDOExcavatedExtended extends PDOExcavated
{
/** * Allows to customize log message scope. * * @param array &$scope * @return void * @see ExcavatingTrait::after() */protectedfunctionscope(array &$scope)
{
$scope['FOO'] = __METHOD__;
}
/** * Prepares query for logging. * * @param string &$query * @return void * @see ExcavatingTrait::after() */protectedfunctionprepareQueryForLogging(&$query)
{
// Modify query here.
}
/** * Method used to replace PDOStatementExcavated by possible child. * * @param string $template * @param PDOStatementExcavated $stmt * @return PDOStatementExcavatedExtended * @see self::getResultStatement() */protectedfunctiongetStatement($template, PDOStatement$stmt)
{
returnnewPDOStatementExcavatedExtended($template, $this, $stmt);
}
}
class PDOStatementExcavatedExtended extends PDOStatementExcavated
{
/** * Allows to customize log message scope. * * @param array &$scope * @return void * @see ExcavatingTrait::after() */protectedfunctionscope(array &$scope)
{
$scope['FOO'] = __METHOD__;
}
/** * Prepares query for logging. * * @param string &$query * @return void * @see ExcavatingTrait::after() */protectedfunctionprepareQueryForLogging(&$query)
{
// Modify query here.
}
}
class Logger implements LoggerInterface
{
/** * Logs message. * * @param string $message * @param array $scope * @return void */publicfunctionlog($message, array$scope)
{
echo"$message\n";
}
}
$dsn = "...";
$username = "...";
$password = "...";
$logger = newLogger();
$pdo = newPDOExcavatedExtended(
$dsn,
$username,
$password,
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDOExcavated::ATTR_DEBUG => [
'logger' => $logger,
'format' => [
'call' => "%FOO%",
'query' => "%FOO%",
],
],
]
);
$pdo->exec("UPDATE `test` SET `bar` = ''");
$pdo->query("SELECT 1");
$stmt = $pdo->prepare("SELECT ?, ?");
$stmt->bindValue(1, 100500, PDO::PARAM_INT);
$stmt->bindValue(2, "blah");
$stmt->execute();

will output:

deepeloper\PDO\PDOExcavatedExtended::scope
deepeloper\PDO\PDOExcavatedExtended::scope
deepeloper\PDO\PDOExcavatedExtended::scope
deepeloper\PDO\PDOExcavatedExtended::scope
deepeloper\PDO\PDOStatementExcavatedExtended::scope

About

PDO Debugging & Benchmarking Tools

Resources

Stars

4 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages