forrest79/phpgsql-nette

将 PhPgSql 集成到 Nette 框架中。

v1.5.3 2024-04-29 19:54 UTC

README

Latest Stable Version Monthly Downloads License Build

使用 PhPgSql 集成 Nette 框架。

简介

扩展,简化在 Nette 应用中使用 PhPgSql。

安装

推荐通过 Composer 安装 PhPgSql - Nette。

composer require forrest79/phpgsql-nette

PhPgSql 需要 PHP 8.1.0 和 pgsql 二进制扩展。

使用

首先,在 neon 配置中注册扩展

extensions:
    database: Forrest79\PhPgSql\Nette\DI\Extension(%debugMode%)

然后,注册连接(默认为一个连接)

database:
    config: # default is empty array, keys and values are not checked, just imploded to `pg_connect` `$connection_string` as `"key1=value1 key2=value2 ..."`
        host: localhost
        port: 5432
        user: postgres
        password: postgres
        dbname: postgres
        connect_timeout: 5 # good habit is to use connect_timeout parameter
    errorVerbosity: ::constant(PGSQL_ERRORS_VERBOSE) # default is NULL and it will use default error verbose PGSQL_ERRORS_DEFAULT, other value can be PGSQL_ERRORS_TERSE
    asyncWaitSeconds: 5 # default is NULL and it will use default seconds value
    defaultRowFactory: @App\PhPgSql\Db\RowFactories\MyOwnRowFactory # this service is needed to be registered, default is NULL, and default row factory is used
    dataTypeParser: @App\PhPgSql\Db\DataTypeParsers\MyOwnDataTypeParser # this service is needed to be registered, default is NULL, and default data type parser is used
    dataTypeCache: @Forrest79\PhPgSql\Db\DataTypeCaches\PhpFile # this service is needed to be registered like this `- Forrest79\PhPgSql\Db\DataTypeCaches\PhpFile('%tempDir%/phpgsql/data-types-cache.php')`, this is recommended settings, default is NULL and cache is disabled
    forceNew: true # default is false
    async: true # default is false, when true, connection is made in async way, and it's not blocking the next PHP code execution (before the first query is run, a library is waiting for active connection)
    lazy: false # default is true, when false, connection is made right after the Connection object is created, when true, connection is made with the first query
    autowired: false # default is true (for second and next connection is always false)
    debugger: false # default is true (when true, the exception panel on Bluescreen is added, and Tracy bar is shown in debug mode)
    tracyBluescreenPanelClass: App\PhPgSql\MyOwnTracy\BarPanel # default is Forrest79\PhPgSql\Tracy\BluescreenPanel (you can use your own Tracy bluescreen panel class)
    tracyBarPanelClass: App\PhPgSql\MyOwnTracy\BarPanel # default is Forrest79\PhPgSql\Tracy\BarPanel (you can use your own Tracy bar panel class)
    queryDumper: false # default is null (when false, no query dumper is used, and all SQL queries are displayed as it is, when null - auto-detection is used - when Doctrine\Sql-Formatter is installed, it is used, when not, internal basic formatter is used or use own service via @serviceName)
    explain: true # default is false (when true, if the Tracy panel is enabled, explain is shown for every query)
    notices: true # default is false (when true, if the Tracy panel is enabled, after every SQL command and before connection is closed, notices are got and put into the query log)
    longQueryTimeMs: 100 # default is NULL = disabled, is set (float, time in milliseconds) and Tracy panel is enabled, all queries that takes longer than this value is marked in the panel with bold red time)
    repeatingQueries: true # default is FALSE (when true, if the Tracy panel is enabled, repeating queries are detected and listed - except BEGIN, COMMIT, ROLLBACK and SET statements)
    nonParsedColumns: true # default is FALSE (when true, if the Tracy panel is enabled, queries with some non-parsed (used) columns are detected and listed)

或多个连接

database:
    first:
        config:
            host: localhost
            port: 5432
            user: postgres
            password: postgres
            dbname: postgres
    second:
        config:
            host: localhost
            port: 5433
            user: postgres
            password: postgres
            dbname: postgres

重要!连接名称不能为 config

第一个 connection 自动绑定为 Forrest79\PhPgSql\Fluent\Connection。如果您想自动绑定其他连接或无连接,您必须显式设置 autowired: false

您还可以通过以下方式获取连接

$container->getService('database.default.connection'); // for one connection, default

$container->getService('database.first.connection');

第二个可以通过以下方式获取

$container->getService('database.second.connection');

使用您自己的连接类

默认情况下,Forrest79\PhPgSql\Fluent\Connection 已注册到 DI 作为连接类。如果您想使用其他(您自己的)连接类,您需要使用您自己的连接工厂。这是一个实现了 Forrest79\PhPgSql\Nette\Connection\ConnectionCreator 接口类的类,并且您必须指定您的连接类的具体返回类型。

示例

class ConnectionFactory implements Forrest79\PhPgSql\Nette\Connection\ConnectionCreator
{
    /** @var int */
    private $statementTimeout = NULL;

    public function __construct(int $sessionTimeout)
    {
        $this->statementTimeout = $sessionTimeout;
    }

    /**
     * In `$config` array are all values from connection config definition, you can use some special/meta values for your own logic and unset it from `$config` before sending it to `prepareConfig()` function.
     */
    public function create(array $config, bool $forceNew, bool $async): MyOwnConnection
    {
        return (new Connection(
            $this->prepareConfig($config), // this will implode array config to string, you can extend this method and add some default settings or your own logic
            $forceNew,
            $async,
        ))->addOnConnect(function(Forrest79\PhPgSql\Db\Connection $connection) {
            $connection->query(sprintf('SET statement_timeout = %d', $this->statementTimeout));
        });
    }

    protected function prepareConfig(array $config): string
    {
        return parent::prepareConfig($config + ['connect_timeout' => 5]);
    }
}

函数 prepareConfig(array $config) 从配置数组创建连接字符串(key='value' key='value' ...)。具有 NULL 值的项将被跳过。

现在,您只需要在 DI 配置中的 services 部分覆盖旧连接工厂,如下所示

services:
    database.default.connection.factory: ConnectionFactory(15)

其中 default 是连接名称。

查询转储

SQL 查询在 Tracy\BarTracy\Bluescreen 中转储,并且您可以使用不同的转储器/格式化器。包含三个

  • PhPgSql\Tracy\QueryDumpers\NullDumper - 显示原始 SQL 查询,当 queryDumper: false 设置时使用
  • PhPgSql\Tracy\QueryDumpers\Basic - 使用基本内部格式化器突出显示并格式化 SQL 查询,当 queryDumper: nullDoctrine\Sql-Formatter 未安装时使用
  • PhPgSql\Tracy\QueryDumpers\SqlFormatter - 使用 Doctrine\Sql-Formatter 突出显示并格式化 SQL 查询,当 queryDumper: nullDoctrine\Sql-Formatter 已安装时使用

您可以通过 composer require doctrine/sql-formatter --dev 仅在您的开发环境中安装更好的格式化,以便通过 Doctrine\Sql-Formatter

或者,您可以使用您自己的查询转储器,只需创建一个扩展抽象类 PhPgSql\Tracy\QueryDumper,将其注册到 DI 容器中,并将服务设置为 queryDumper: @class/serviceName

Tracy BarPanel

带有数据库查询的 BarPanel 用于 Tracy 显示指向 PHP 源文件的链接,其中查询被发送到数据库。这是使用 PHP 函数 debug_backtrace() 实现的。此函数返回整个调用堆栈。要获取 PHP 源文件中的正确位置,我们必须忽略一些内部库类,其中查询被发送到数据库。基本上,BarPanel 忽略来自 PhPgSql 库的所有类/函数,以显示 PHP 源文件中最准确的位置。

当您使用一些自己的自定义包装对象时,您想忽略在调用堆栈中,您可以扩展 backtraceContinueIterate() 方法并在此处添加您自己的逻辑。例如

protected static function backtraceContinueIterate(string $class, string $function): bool
{
    return parent::backtraceContinueIterate() // just for sure, you can use multiple extends...
        || (is_a($class, MyOwnFluentQuery::class, TRUE) && ($function === 'count'))
        || (is_a($class, Mapper\Record::class, TRUE) && ($function === 'fetch'));
}