【问题标题】:Using Laravel service provider to override connector classes使用 Laravel 服务提供者覆盖连接器类
【发布时间】:2017-07-23 19:52:54
【问题描述】:

我在 Laravel 5.2 中工作,我正在尝试让它与 Vertica 一起工作。几个月前,我和我的同事提出了this 解决方案,但我们现在正试图让事情变得不那么老套,并使用服务提供商来让事情正常进行,这样我们就可以更轻松地升级 Laravel。所以到目前为止我们所做的是:

1) 创建两个新的类来扩展它们的对应类:

新的 BaseConnector:

namespace App\Vertica;
include 'clsPDOVertica.php';

use Illuminate\Support\Arr;
use \Illuminate\Database\Connectors\Connector as BaseConnector;

class Connector extends BaseConnector
{
    /**
     * Create a new PDO connection.
     *
     * @param  string  $dsn
     * @param  array   $config
     * @param  array   $options
     * @return \PDO
     */
    public function createConnection($dsn, array $config, array $options)
    {
        $username = Arr::get($config, 'username');

        $password = Arr::get($config, 'password');

        return new PDOVertica($dsn, $username, $password, $options);
    }
}

新的 PostgresConnector:

namespace App\Vertica;

use \Illuminate\Database\Connectors\PostgresConnector as BasePostgresConnector;

class PostgresConnector extends BasePostgresConnector
{

    /**
     * Create a DSN string from a configuration.
     *
     * @param  array   $config
     * @return string
     */
    protected function getDsn(array $config)
    {
        // First we will create the basic DSN setup as well as the port if it is in
        // in the configuration options. This will give us the basic DSN we will
        // need to establish the PDO connections and return them back for use.
        extract($config, EXTR_SKIP);

        $host = isset($host) ? "host={$host};" : '';

        $dsn = "Driver={$driverpath};{$host}Database={$database}";

        // If a port was specified, we will add it to this Postgres DSN connections
        // format. Once we have done that we are ready to return this connection
        // string back out for usage, as this has been fully constructed here.
        if (isset($config['port'])) {
            $dsn .= ";port={$port}";
        }

        if (isset($config['sslmode'])) {
            $dsn .= ";sslmode={$sslmode}";
        }

        return $dsn;
    }
}

现在,我们正在尝试定义一个服务提供者,以从本质上告诉 Laravel 使用我们的类而不是默认类……但到目前为止还没有成功。这是提供程序的代码:

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class VerticaServiceProvider extends ServiceProvider
{
    /**
     * Register bindings in the container.
     *
     * @return void
     */
    public function register()
    {
        // dd(new \Illuminate\Database\Connectors\PostgresConnector);
        $this->app->singleton('\Illuminate\Database\Connectors\Connector', function()
        {
            return new \App\Vertica\Connector();
        });

        $this->app->singleton('\Illuminate\Database\Connectors\PostgresConnector', function()
        {
            return new \App\Vertica\PostgresConnector();
        });
    }
}

到目前为止,我们的 VerticaServiceProvider 的 register 方法被调用,但显然,内部的绑定是错误的,因为我们的类没有被调用。有人知道我们做错了什么吗?

【问题讨论】:

    标签: php laravel


    【解决方案1】:

    Laravel 无法从容器中解析 Connector 类,因此尝试通过类名覆盖连接器将不起作用。

    您可以在Illuminate/Database/Connectors/ConnectionFactory::createConnector 中查看连接器是如何解析的。 Laravel 只是做一个return new PostgresConnector(或任何适合驱动程序的),所以它不会在容器中查找类名。

    但是,在它“新建”Connector 之前,它会检查容器以查看是否有使用字符串'db.connector.[driver]' 绑定到驱动程序的连接器,其中[driver] 是数据库驱动程序名称。

    因此,与其尝试绑定容器中的类名,不如绑定字符串'db.connector.your-driver-name'。因此,如果您创建了自己的自定义驱动程序(例如 vertica),您可以将连接器绑定到 'db.connector.vertica'。或者,如果您想覆盖内置的 postgres 连接器,您可以将连接器绑定到 'db.connector.pgsql'

    根据您尝试覆盖 postgres 连接器的假设,您的服务提供者注册方法如下所示:

    public function register()
    {
        $this->app->bind('db.connector.pgsql', \App\Vertica\PostgresConnector::class);
    }
    

    【讨论】:

      【解决方案2】:

      我无法通过 PostgresConnector 连接器将 Illumitane 查询构建器与 Vertica 完全结合使用。 这就是我制作 laravel-ready VerticaConnector 的原因,它通过 1 个命令安装:

      composer require mixartemev/dbal-vertica-driver
      

      【讨论】:

        猜你喜欢
        • 2014-07-10
        • 2013-07-22
        • 2017-01-11
        • 2019-05-29
        • 2021-09-29
        • 1970-01-01
        • 2018-11-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多