PHP Debug Bar with Slim 4

Is there any guide/tutorial for adding phpdebugbar into Slim 4 application?

Have you considered using Xdebug as well?

Actually I was thinking to measure the performance and memory usage of my application.

Then the Xdebug Profiler might be the right tool for you.

PhpDebugbar can be finicky to try and weave into your app

we load ours into the twig view

// Set view in Container
$container->set('view', function(DI\Container $container) {
    $debug = SITE_TYPE === DEV_SITE;
    $twig = Twig::create(__DIR__ . '/../templates',  ['debug' => $debug]);

    $twig->addExtension(new \Twig\Extra\Intl\IntlExtension());
    $debugbar = $container->get('DebugBar\StandardDebugBar');
    $profile = new \Twig\Profiler\Profile();
    $twig->addExtension(new \Twig\Extension\DebugExtension());
    $twig->addExtension(new DebugBar\Bridge\Twig\TimeableTwigExtensionProfiler($profile, $debugbar['time']));
    $debugbar->addCollector(new DebugBar\Bridge\TwigProfileCollector($profile));
    return $twig;
});

and then we add into our database class for both our read and write connections

if (SITE_TYPE == DEV_SITE) {
	if (!$this->debugBar->hasCollector('pdo')) {
		$pdo = new DebugBar\DataCollector\PDO\TraceablePDO($this->getDBConnection($this->readDBUserName, $this->readDBPassword, $this->readDBHost, $this->readDBName, $options));
		$pdoCollector = new DebugBar\DataCollector\PDO\PDOCollector();
		$pdoCollector->addConnection($pdo, "pdo-readonly");
		$this->debugBar->addCollector($pdoCollector);

		$this->sqlRead = $pdo;
	} else {
		$pdo = new DebugBar\DataCollector\PDO\TraceablePDO($this->getDBConnection($this->readDBUserName, $this->readDBPassword, $this->readDBHost, $this->readDBName, $options));
		$this->debugBar->getCollector('pdo')->addConnection($pdo, "pdo-readonly");
		$this->sqlRead = $pdo;
	}
  }

There’s so much more we’d like to do with it for twig stuff but it’s just too much to bother with at this time.

我找到一个解决方法,这适用于slim4。

composer require tracy/tracy

然后在index.php这样配置

use Tracy\Debugger;

然后在以下代码

$app->run();

前添加

Debugger::enable(Debugger::Development);
// 关于可见性问题可以参考 https://tracy.nette.org/en/guide

这之后再访问应用程序,你应该可以在页面右下角看见一个bar

如果你和我一样使用 illuminate/database,你可以再做一些改动以便用来查看 sql 查询和耗时

<?php

namespace App\Services;

use App\Utils\Tools;
use Illuminate\Database\Capsule\Manager as Capsule;

class Db
{
    private static $capsule;

    public static function bootEloquent(array $dbSettings)
    {
        self::$capsule = new Capsule;
        self::$capsule->addConnection($dbSettings);
        self::$capsule->setAsGlobal();
        self::$capsule->bootEloquent();
        self::$capsule::connection()->enableQueryLog();
    }

    public static function getQueryLog(): array
    {
        $raw_logs = self::$capsule::connection()->getQueryLog();
        return Tools::parseQueryLog($raw_logs);
    }
}

Tools类的代码

<?php

namespace App\Utils;

class Tools
{
    /**
     * 解析illuminate查询日志
     */
    public static function parseQueryLog(array $queryLog)
    {
        return array_map(static function ($entry) {
            $query = array_reduce($entry['bindings'], static function ($query, $binding) {
                $value = is_numeric($binding) ? $binding : "'" . addslashes($binding) . "'";
                return preg_replace('/\?/', $value, $query, 1);
            }, $entry['query']);

            return [
                'query' => $query,
                'time' => $entry['time'] / 1000,
            ];
        }, $queryLog);
    }
}

在 index.php 中加载数据库服务

<?php

use App\Services\Db;
use Slim\Factory\AppFactory;
use Tracy\Debugger;

require __DIR__ . '/../vendor/autoload.php';

/**
 * Load database service
 */

$database_config = require __DIR__ . '/../config/database.php';
Db::bootEloquent($database_config);
...

然后我们实现 IBarPanel 接口

<?php

namespace App\Services\Tracy;

use Tracy\IBarPanel;

class QueryPanel implements IBarPanel
{
    private $queryLog;

    public function __construct(array $queryLog)
    {
        $this->queryLog = $queryLog;
    }

    public function getTab()
    {
        return '
        <span title="SQL Queries">' .
            '<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
            viewBox="0 0 56 56" xml:space="preserve">
                <g>
                    <g>
                        <path style="fill:#545E73;" d="M49.455,8L49.455,8C48.724,3.538,38.281,0,25.5,0S2.276,3.538,1.545,8l0,0H1.5v0.5V20v0.5V21v11
                            v0.5V33v12h0.045c0.731,4.461,11.175,8,23.955,8s23.224-3.539,23.955-8H49.5V33v-0.5V32V21v-0.5V20V8.5V8H49.455z"/>
                        <g>
                            <path style="fill:#38454F;" d="M25.5,41c-13.255,0-24-3.806-24-8.5V45h0.045c0.731,4.461,11.175,8,23.955,8
                                s23.224-3.539,23.955-8H49.5V32.5C49.5,37.194,38.755,41,25.5,41z"/>
                            <path style="fill:#38454F;" d="M1.5,32v0.5c0-0.168,0.018-0.334,0.045-0.5H1.5z"/>
                            <path style="fill:#38454F;" d="M49.455,32c0.027,0.166,0.045,0.332,0.045,0.5V32H49.455z"/>
                        </g>
                        <g>
                            <path style="fill:#556080;" d="M25.5,29c-13.255,0-24-3.806-24-8.5V33h0.045c0.731,4.461,11.175,8,23.955,8
                                s23.224-3.539,23.955-8H49.5V20.5C49.5,25.194,38.755,29,25.5,29z"/>
                            <path style="fill:#556080;" d="M1.5,20v0.5c0-0.168,0.018-0.334,0.045-0.5H1.5z"/>
                            <path style="fill:#556080;" d="M49.455,20c0.027,0.166,0.045,0.332,0.045,0.5V20H49.455z"/>
                        </g>
                        <ellipse style="fill:#91BAE1;" cx="25.5" cy="8.5" rx="24" ry="8.5"/>
                        <g>
                            <path style="fill:#8697CB;" d="M25.5,17c-13.255,0-24-3.806-24-8.5V21h0.045c0.731,4.461,11.175,8,23.955,8
                                s23.224-3.539,23.955-8H49.5V8.5C49.5,13.194,38.755,17,25.5,17z"/>
                            <path style="fill:#8697CB;" d="M1.5,8v0.5c0-0.168,0.018-0.334,0.045-0.5H1.5z"/>
                            <path style="fill:#8697CB;" d="M49.455,8C49.482,8.166,49.5,8.332,49.5,8.5V8H49.455z"/>
                        </g>
                    </g>
                    <g>
                        <circle style="fill:#26B999;" cx="42.5" cy="44" r="12"/>
                        <path style="fill:#FFFFFF;" d="M49.071,38.179c-0.455-0.316-1.077-0.204-1.392,0.25l-5.596,8.04l-3.949-3.242
                            c-0.426-0.351-1.057-0.288-1.407,0.139c-0.351,0.427-0.289,1.057,0.139,1.407l4.786,3.929c0.18,0.147,0.404,0.227,0.634,0.227
                            c0.045,0,0.091-0.003,0.137-0.009c0.276-0.039,0.524-0.19,0.684-0.419l6.214-8.929C49.636,39.118,49.524,38.495,49.071,38.179z"/>
                    </g>
                </g>
            </svg>' .
        ' SQL Queries</span>';
    }

    public function getPanel(): string
    {
        $html = '<h1>SQL Queries</h1>';
        $html .= '<div class="tracy-inner">';
        $html .= '<table class="tracy-sortable">';
        $html .= '<thead><tr><th>Query</th><th>Time</th></tr></thead>';
        $html .= '<tbody>';

        foreach ($this->queryLog as $entry) {
            $html .= '<tr>';
            $html .= '<td>' . htmlspecialchars($entry['query'], ENT_QUOTES) . '</td>';
            $html .= '<td>' . htmlspecialchars($entry['time'], ENT_QUOTES) . ' seconds</td>';
            $html .= '</tr>';
        }

        $html .= '</tbody></table>';
        $html .= '</div>';
        return $html;
    }
}

最后在 index.php 中修改
(你可以将默认的 $errorMiddleware 注释,这样会使用 Tracy 的错误和异常的可视化)


//$errorMiddleware = $app->addErrorMiddleware(true, true, true);

Debugger::enable(Debugger::Development);

// Run app
$app->run();

$queryPanel = new \App\Services\Tracy\QueryPanel(Db::getQueryLog());
Debugger::getBar()->addPanel($queryPanel);

然后是这样的效果