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.

1 Like

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.

1 Like

我找到一个解决方法,这适用于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);

然后是这样的效果