Symfony / Doctrine:如何使Doctrine使用Unix套接字?

我正在尝试使用Unix套接字连接到PostgreSQL。我认为只有一种方法可以连接到主机上的数据库,但是应用程序在Docker中(我遵循不对未复制的数据库进行容器化的原则)。我正在将Symfony 4与最新的学说一起使用。

我使用PDO在原始PHP上进行了测试,并且可以正常工作。我不知道如何强制Doctrine使用Unix套接字。

<?php
$dbh = new PDO('pgsql:host=/var/run/postgresql;user=xxxx;dbname=zzzz;password=yyyy');
$dbh->setattribute(PDO::ERRMODE_EXCEPTION,true);
var_dump($dbh->errorInfo());

$stmt = $dbh->query('SELECT 1 as dupa;');
$stmt->execute();

var_dump($stmt->fetchAll());

结果如预期:

www-data@ef0f2269b69a:~/html$ php o.php 
array(3) {
  [0]=>
  string(5) "00000"
  [1]=>
  NULL
  [2]=>
  NULL
}
array(1) {
  [0]=>
  array(2) {
    ["dupa"]=>
    int(1)
    [0]=>
    int(1)
  }
}

问题是我在教义中配置的所有内容:

In PDOConnection.php line 27:

  [PDOException (7)]                                                    
  SQLSTATE[08006] [7] could not connect to server: Connection refused   
        Is the server running on host "localhost" (127.0.0.1) and accepting  
        TCP/IP connections on port 5432?                                     
  could not connect to server: Cannot assign requested address          
        Is the server running on host "localhost" (::1) and accepting        
        TCP/IP connections on port 5432?    

我尝试了Doctrine的语法,原始的PDO语法,没有任何想法。 我的pdo_pgsql是否没有编译为unix套接字支持的可能性?

这是我在Doctrine中作为数据库URL尝试的方法:

pdo-pgsql://yyyy:xxxxx@/var/run/postgresql:5432/zzzzz
pgsql:host=/var/run/postgresql;user=xxxx;dbname=zzzz;password=yyyy

感谢您的时间!

urboat20 回答:Symfony / Doctrine:如何使Doctrine使用Unix套接字?

以上都不适合我。我打开了关于这个主题的多个新问题,只是为了让它们作为这个问题的副本被迅速关闭(这真的不是同一个问题,因为我的问题更多是关于对等身份验证):How to make Symfony authenticate to PostgreSQL using peer authentication without a username and password 和 {{3 }} 主要是反复试验,找到了一个无证但并不可怕的解决方案。

我们知道 PHP 和 Doctrine 都能够使用 Unix 套接字和对等身份验证进行连接,因为以下两者都有效。

$pdo = new PDO("pgsql:dbname=testing");

$pdo = EntityManager::create(['driver' => 'pdo_pgsql','dbname' => 'testing'],Setup::createAnnotationMetadataConfiguration([__DIR__."/../src"],true,null,false))->getConnection();

因此,人们可能认为以下 config/packages/doctrine.yaml 会起作用:

doctrine:
    dbal:
        driver: pdo_pgsql
        dbname: testing
        server_version: 13

但没那么幸运:

[2021-07-25T22:15:57.675268+00:00] console.CRITICAL: Error thrown while running command "doctrine:schema:validate". Message: "An exception occurred in driver: SQLSTATE[08006] [7] fe_sendauth: no password supplied" {"exception":"[object] (Doctrine\\DBAL\\Exception\\ConnectionException(code: 0): An exception occurred in driver: SQLSTATE[08006] [7] fe_sendauth: no password supplied at /var/www/software-requirements/api/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractPostgreSQLDriver.php:88)\n[previous exception] [object] (Doctrine\\DBAL\\Driver\\PDO\\Exception(code: 7): SQLSTATE[08006] [7] fe_sendauth: no password supplied at /var/www/software-requirements/api/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDO/Exception.php:18)\n[previous exception] [object] (PDOException(code: 7): SQLSTATE[08006] [7] fe_sendauth: no password supplied at /var/www/software-requirements/api/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:39)","command":"doctrine:schema:validate","message":"An exception occurred in driver: SQLSTATE[08006] [7] fe_sendauth: no password supplied"} []

然后我查看了赋予 \Doctrine\DBAL\Driver\__construct 的内容,发现原生 Doctrine 方法将 userhost 都保留为 null,但 Symfony 不恰当地将它们设置为rootlocalhost 分别。解决方案是稍微修改 config/packages/doctrine.yaml 并将 userhost 设置为 null。虽然未显示,但显然您可以并且应该在 .env 中定义变量。

doctrine:
    dbal:
        driver: pdo_pgsql
        dbname: testing
        server_version: 13
        user: null
        host: null
,

调试Doctrine的驱动程序后的解决方案我创建的解决方案不是那么优雅,但是目前它可以正常工作并且可以改进。我不喜欢驱动程序本身中的环境变量,但这可能可以改进。

doctrine.yaml

doctrine:
    dbal:
        #driver:   %database_driver%
        driver_class: App\Infrastructure\Common\Service\PostgreSQLDoctrineDriver
        host:     %database_host%
        port:     %database_port%
        dbname:   %database_name%
        user:     %database_user%
        password: %database_password%
        #charset:  UTF8

    orm:
        auto_generate_proxy_classes: %kernel.debug%
        auto_mapping: true

PostgreSQLDoctrineDriver.php

<?php declare(strict_types=1);

namespace App\Infrastructure\Common\Service;

use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Driver\PDOConnection;
use Doctrine\DBAL\Driver\PDOPgSql\Driver;
use \PDO;
use \PDOException;
use function defined;

/**
 * Driver that connects through pdo_pgsql
 *
 * Forked original PostgreSQL driver,extended to have a possibility to pass raw PDO DSN to be
 * able to connect via Unix socket
 */
class PostgreSQLDoctrineDriver extends Driver
{
    /**
     * {@inheritdoc}
     */
    public function connect(array $params,$username = null,$password = null,array $driverOptions = [])
    {
        try {
            $pdo = new PDOConnection(
                $_SERVER['POSTGRES_DB_PDO_DSN'] ?? '',$username,$password,$driverOptions
            );

            if (defined('PDO::PGSQL_ATTR_DISABLE_PREPARES')
                && (! isset($driverOptions[PDO::PGSQL_ATTR_DISABLE_PREPARES])
                    || $driverOptions[PDO::PGSQL_ATTR_DISABLE_PREPARES] === true
                )
            ) {
                $pdo->setAttribute(PDO::PGSQL_ATTR_DISABLE_PREPARES,true);
            }

            /* defining client_encoding via SET NAMES to avoid inconsistent DSN support
             * - the 'client_encoding' connection param only works with postgres >= 9.1
             * - passing client_encoding via the 'options' param breaks pgbouncer support
             */
            if (isset($params['charset'])) {
                $pdo->exec('SET NAMES \'' . $params['charset'] . '\'');
            }

            return $pdo;
        } catch (PDOException $e) {
            throw DBALException::driverException($this,$e);
        }
    }

    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return 'pdo_pgsql';
    }
}
,

您可以通过unix_socket配置选项来配置套接字,该选项自一段时间以来似乎已经可用:https://symfony.com/doc/current/reference/configuration/doctrine.html

,

您可以将套接字路径作为主机,例如:

doctrine:
    dbal:
        host: /var/pgsql_socket
本文链接:https://www.f2er.com/3146896.html

大家都在问